diff options
Diffstat (limited to 'crates/rust-analyzer/src/to_proto.rs')
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index df9292f8e..8d7cb9b74 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -145,6 +145,23 @@ pub(crate) fn text_edit(line_index: &LineIndex, indel: Indel) -> lsp_types::Text | |||
145 | lsp_types::TextEdit { range, new_text } | 145 | lsp_types::TextEdit { range, new_text } |
146 | } | 146 | } |
147 | 147 | ||
148 | pub(crate) fn completion_text_edit( | ||
149 | line_index: &LineIndex, | ||
150 | insert_replace_support: Option<lsp_types::Position>, | ||
151 | indel: Indel, | ||
152 | ) -> lsp_types::CompletionTextEdit { | ||
153 | let text_edit = text_edit(line_index, indel); | ||
154 | match insert_replace_support { | ||
155 | Some(cursor_pos) => lsp_types::InsertReplaceEdit { | ||
156 | new_text: text_edit.new_text, | ||
157 | insert: lsp_types::Range { start: text_edit.range.start, end: cursor_pos }, | ||
158 | replace: text_edit.range, | ||
159 | } | ||
160 | .into(), | ||
161 | None => text_edit.into(), | ||
162 | } | ||
163 | } | ||
164 | |||
148 | pub(crate) fn snippet_text_edit( | 165 | pub(crate) fn snippet_text_edit( |
149 | line_index: &LineIndex, | 166 | line_index: &LineIndex, |
150 | is_snippet: bool, | 167 | is_snippet: bool, |
@@ -179,6 +196,7 @@ pub(crate) fn snippet_text_edit_vec( | |||
179 | } | 196 | } |
180 | 197 | ||
181 | pub(crate) fn completion_item( | 198 | pub(crate) fn completion_item( |
199 | insert_replace_support: Option<lsp_types::Position>, | ||
182 | line_index: &LineIndex, | 200 | line_index: &LineIndex, |
183 | item: CompletionItem, | 201 | item: CompletionItem, |
184 | ) -> Vec<lsp_types::CompletionItem> { | 202 | ) -> Vec<lsp_types::CompletionItem> { |
@@ -190,7 +208,7 @@ pub(crate) fn completion_item( | |||
190 | for indel in item.text_edit().iter() { | 208 | for indel in item.text_edit().iter() { |
191 | if indel.delete.contains_range(source_range) { | 209 | if indel.delete.contains_range(source_range) { |
192 | text_edit = Some(if indel.delete == source_range { | 210 | text_edit = Some(if indel.delete == source_range { |
193 | self::text_edit(line_index, indel.clone()) | 211 | self::completion_text_edit(line_index, insert_replace_support, indel.clone()) |
194 | } else { | 212 | } else { |
195 | assert!(source_range.end() == indel.delete.end()); | 213 | assert!(source_range.end() == indel.delete.end()); |
196 | let range1 = TextRange::new(indel.delete.start(), source_range.start()); | 214 | let range1 = TextRange::new(indel.delete.start(), source_range.start()); |
@@ -198,7 +216,7 @@ pub(crate) fn completion_item( | |||
198 | let indel1 = Indel::replace(range1, String::new()); | 216 | let indel1 = Indel::replace(range1, String::new()); |
199 | let indel2 = Indel::replace(range2, indel.insert.clone()); | 217 | let indel2 = Indel::replace(range2, indel.insert.clone()); |
200 | additional_text_edits.push(self::text_edit(line_index, indel1)); | 218 | additional_text_edits.push(self::text_edit(line_index, indel1)); |
201 | self::text_edit(line_index, indel2) | 219 | self::completion_text_edit(line_index, insert_replace_support, indel2) |
202 | }) | 220 | }) |
203 | } else { | 221 | } else { |
204 | assert!(source_range.intersect(indel.delete).is_none()); | 222 | assert!(source_range.intersect(indel.delete).is_none()); |
@@ -213,7 +231,7 @@ pub(crate) fn completion_item( | |||
213 | detail: item.detail().map(|it| it.to_string()), | 231 | detail: item.detail().map(|it| it.to_string()), |
214 | filter_text: Some(item.lookup().to_string()), | 232 | filter_text: Some(item.lookup().to_string()), |
215 | kind: item.kind().map(completion_item_kind), | 233 | kind: item.kind().map(completion_item_kind), |
216 | text_edit: Some(text_edit.into()), | 234 | text_edit: Some(text_edit), |
217 | additional_text_edits: Some(additional_text_edits), | 235 | additional_text_edits: Some(additional_text_edits), |
218 | documentation: item.documentation().map(documentation), | 236 | documentation: item.documentation().map(documentation), |
219 | deprecated: Some(item.deprecated()), | 237 | deprecated: Some(item.deprecated()), |
@@ -831,40 +849,31 @@ pub(crate) fn code_action_kind(kind: AssistKind) -> lsp_types::CodeActionKind { | |||
831 | } | 849 | } |
832 | } | 850 | } |
833 | 851 | ||
834 | pub(crate) fn unresolved_code_action( | 852 | pub(crate) fn code_action( |
835 | snap: &GlobalStateSnapshot, | 853 | snap: &GlobalStateSnapshot, |
836 | code_action_params: lsp_types::CodeActionParams, | ||
837 | assist: Assist, | 854 | assist: Assist, |
838 | index: usize, | 855 | resolve_data: Option<(usize, lsp_types::CodeActionParams)>, |
839 | ) -> Result<lsp_ext::CodeAction> { | 856 | ) -> Result<lsp_ext::CodeAction> { |
840 | assert!(assist.source_change.is_none()); | 857 | let mut res = lsp_ext::CodeAction { |
841 | let res = lsp_ext::CodeAction { | ||
842 | title: assist.label.to_string(), | 858 | title: assist.label.to_string(), |
843 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), | 859 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), |
844 | kind: Some(code_action_kind(assist.id.1)), | 860 | kind: Some(code_action_kind(assist.id.1)), |
845 | edit: None, | 861 | edit: None, |
846 | is_preferred: None, | 862 | is_preferred: None, |
847 | data: Some(lsp_ext::CodeActionData { | ||
848 | id: format!("{}:{}", assist.id.0, index.to_string()), | ||
849 | code_action_params, | ||
850 | }), | ||
851 | }; | ||
852 | Ok(res) | ||
853 | } | ||
854 | |||
855 | pub(crate) fn resolved_code_action( | ||
856 | snap: &GlobalStateSnapshot, | ||
857 | assist: Assist, | ||
858 | ) -> Result<lsp_ext::CodeAction> { | ||
859 | let change = assist.source_change.unwrap(); | ||
860 | let res = lsp_ext::CodeAction { | ||
861 | edit: Some(snippet_workspace_edit(snap, change)?), | ||
862 | title: assist.label.to_string(), | ||
863 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), | ||
864 | kind: Some(code_action_kind(assist.id.1)), | ||
865 | is_preferred: None, | ||
866 | data: None, | 863 | data: None, |
867 | }; | 864 | }; |
865 | match (assist.source_change, resolve_data) { | ||
866 | (Some(it), _) => res.edit = Some(snippet_workspace_edit(snap, it)?), | ||
867 | (None, Some((index, code_action_params))) => { | ||
868 | res.data = Some(lsp_ext::CodeActionData { | ||
869 | id: format!("{}:{}", assist.id.0, index.to_string()), | ||
870 | code_action_params, | ||
871 | }); | ||
872 | } | ||
873 | (None, None) => { | ||
874 | stdx::never!("assist should always be resolved if client can't do lazy resolving") | ||
875 | } | ||
876 | }; | ||
868 | Ok(res) | 877 | Ok(res) |
869 | } | 878 | } |
870 | 879 | ||
@@ -1142,7 +1151,7 @@ mod tests { | |||
1142 | .unwrap() | 1151 | .unwrap() |
1143 | .into_iter() | 1152 | .into_iter() |
1144 | .filter(|c| c.label().ends_with("arg")) | 1153 | .filter(|c| c.label().ends_with("arg")) |
1145 | .map(|c| completion_item(&line_index, c)) | 1154 | .map(|c| completion_item(None, &line_index, c)) |
1146 | .flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text))) | 1155 | .flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text))) |
1147 | .collect(); | 1156 | .collect(); |
1148 | expect_test::expect![[r#" | 1157 | expect_test::expect![[r#" |