diff options
-rw-r--r-- | crates/completion/src/config.rs | 4 | ||||
-rw-r--r-- | crates/completion/src/item.rs | 36 | ||||
-rw-r--r-- | crates/completion/src/render.rs | 4 | ||||
-rw-r--r-- | crates/completion/src/render/enum_variant.rs | 2 | ||||
-rw-r--r-- | crates/completion/src/render/function.rs | 2 | ||||
-rw-r--r-- | crates/completion/src/render/macro_.rs | 2 | ||||
-rw-r--r-- | crates/completion/src/test_utils.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 4 |
8 files changed, 43 insertions, 13 deletions
diff --git a/crates/completion/src/config.rs b/crates/completion/src/config.rs index 736af455e..e9a02aeb8 100644 --- a/crates/completion/src/config.rs +++ b/crates/completion/src/config.rs | |||
@@ -29,6 +29,10 @@ impl CompletionConfig { | |||
29 | pub fn allow_snippets(&mut self, yes: bool) { | 29 | pub fn allow_snippets(&mut self, yes: bool) { |
30 | self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None } | 30 | self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None } |
31 | } | 31 | } |
32 | |||
33 | pub fn should_resolve_immediately(&self) -> bool { | ||
34 | !self.resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits) | ||
35 | } | ||
32 | } | 36 | } |
33 | 37 | ||
34 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | 38 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index dc67df075..5906637a6 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs | |||
@@ -3,8 +3,11 @@ | |||
3 | use std::fmt; | 3 | use std::fmt; |
4 | 4 | ||
5 | use hir::{Documentation, ModPath, Mutability}; | 5 | use hir::{Documentation, ModPath, Mutability}; |
6 | use ide_db::helpers::insert_use::{ImportScope, MergeBehaviour}; | 6 | use ide_db::helpers::{ |
7 | use syntax::TextRange; | 7 | insert_use::{self, ImportScope, MergeBehaviour}, |
8 | mod_path_to_ast, | ||
9 | }; | ||
10 | use syntax::{algo, TextRange}; | ||
8 | use text_edit::TextEdit; | 11 | use text_edit::TextEdit; |
9 | 12 | ||
10 | use crate::config::SnippetCap; | 13 | use crate::config::SnippetCap; |
@@ -207,6 +210,7 @@ impl CompletionItem { | |||
207 | score: None, | 210 | score: None, |
208 | ref_match: None, | 211 | ref_match: None, |
209 | import_to_add: None, | 212 | import_to_add: None, |
213 | resolve_import_immediately: true, | ||
210 | } | 214 | } |
211 | } | 215 | } |
212 | 216 | ||
@@ -279,6 +283,7 @@ pub(crate) struct Builder { | |||
279 | source_range: TextRange, | 283 | source_range: TextRange, |
280 | completion_kind: CompletionKind, | 284 | completion_kind: CompletionKind, |
281 | import_to_add: Option<ImportToAdd>, | 285 | import_to_add: Option<ImportToAdd>, |
286 | resolve_import_immediately: bool, | ||
282 | label: String, | 287 | label: String, |
283 | insert_text: Option<String>, | 288 | insert_text: Option<String>, |
284 | insert_text_format: InsertTextFormat, | 289 | insert_text_format: InsertTextFormat, |
@@ -300,6 +305,7 @@ impl Builder { | |||
300 | let mut label = self.label; | 305 | let mut label = self.label; |
301 | let mut lookup = self.lookup; | 306 | let mut lookup = self.lookup; |
302 | let mut insert_text = self.insert_text; | 307 | let mut insert_text = self.insert_text; |
308 | let mut text_edits = TextEdit::builder(); | ||
303 | 309 | ||
304 | if let Some(import_to_add) = self.import_to_add.as_ref() { | 310 | if let Some(import_to_add) = self.import_to_add.as_ref() { |
305 | let mut import_path_without_last_segment = import_to_add.import_path.to_owned(); | 311 | let mut import_path_without_last_segment = import_to_add.import_path.to_owned(); |
@@ -314,20 +320,35 @@ impl Builder { | |||
314 | } | 320 | } |
315 | label = format!("{}::{}", import_path_without_last_segment, label); | 321 | label = format!("{}::{}", import_path_without_last_segment, label); |
316 | } | 322 | } |
323 | |||
324 | if self.resolve_import_immediately { | ||
325 | let rewriter = insert_use::insert_use( | ||
326 | &import_to_add.import_scope, | ||
327 | mod_path_to_ast(&import_to_add.import_path), | ||
328 | import_to_add.merge_behaviour, | ||
329 | ); | ||
330 | if let Some(old_ast) = rewriter.rewrite_root() { | ||
331 | algo::diff(&old_ast, &rewriter.rewrite(&old_ast)) | ||
332 | .into_text_edit(&mut text_edits); | ||
333 | } | ||
334 | } | ||
317 | } | 335 | } |
318 | 336 | ||
319 | let text_edit = match self.text_edit { | 337 | let original_edit = match self.text_edit { |
320 | Some(it) => it, | 338 | Some(it) => it, |
321 | None => { | 339 | None => { |
322 | TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone())) | 340 | TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone())) |
323 | } | 341 | } |
324 | }; | 342 | }; |
325 | 343 | ||
344 | let mut resulting_edit = text_edits.finish(); | ||
345 | resulting_edit.union(original_edit).expect("Failed to unite text edits"); | ||
346 | |||
326 | CompletionItem { | 347 | CompletionItem { |
327 | source_range: self.source_range, | 348 | source_range: self.source_range, |
328 | label, | 349 | label, |
329 | insert_text_format: self.insert_text_format, | 350 | insert_text_format: self.insert_text_format, |
330 | text_edit, | 351 | text_edit: resulting_edit, |
331 | detail: self.detail, | 352 | detail: self.detail, |
332 | documentation: self.documentation, | 353 | documentation: self.documentation, |
333 | lookup, | 354 | lookup, |
@@ -400,8 +421,13 @@ impl Builder { | |||
400 | self.trigger_call_info = Some(true); | 421 | self.trigger_call_info = Some(true); |
401 | self | 422 | self |
402 | } | 423 | } |
403 | pub(crate) fn add_import(mut self, import_to_add: Option<ImportToAdd>) -> Builder { | 424 | pub(crate) fn add_import( |
425 | mut self, | ||
426 | import_to_add: Option<ImportToAdd>, | ||
427 | resolve_import_immediately: bool, | ||
428 | ) -> Builder { | ||
404 | self.import_to_add = import_to_add; | 429 | self.import_to_add = import_to_add; |
430 | self.resolve_import_immediately = resolve_import_immediately; | ||
405 | self | 431 | self |
406 | } | 432 | } |
407 | pub(crate) fn set_ref_match( | 433 | pub(crate) fn set_ref_match( |
diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index 504757a6a..b7a3a3935 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs | |||
@@ -194,7 +194,7 @@ impl<'a> Render<'a> { | |||
194 | local_name, | 194 | local_name, |
195 | ) | 195 | ) |
196 | .kind(CompletionItemKind::UnresolvedReference) | 196 | .kind(CompletionItemKind::UnresolvedReference) |
197 | .add_import(import_to_add) | 197 | .add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately()) |
198 | .build(); | 198 | .build(); |
199 | return Some(item); | 199 | return Some(item); |
200 | } | 200 | } |
@@ -249,7 +249,7 @@ impl<'a> Render<'a> { | |||
249 | 249 | ||
250 | let item = item | 250 | let item = item |
251 | .kind(kind) | 251 | .kind(kind) |
252 | .add_import(import_to_add) | 252 | .add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately()) |
253 | .set_documentation(docs) | 253 | .set_documentation(docs) |
254 | .set_ref_match(ref_match) | 254 | .set_ref_match(ref_match) |
255 | .build(); | 255 | .build(); |
diff --git a/crates/completion/src/render/enum_variant.rs b/crates/completion/src/render/enum_variant.rs index f4bd02f25..c08824c6a 100644 --- a/crates/completion/src/render/enum_variant.rs +++ b/crates/completion/src/render/enum_variant.rs | |||
@@ -71,7 +71,7 @@ impl<'a> EnumVariantRender<'a> { | |||
71 | .kind(CompletionItemKind::EnumVariant) | 71 | .kind(CompletionItemKind::EnumVariant) |
72 | .set_documentation(self.variant.docs(self.ctx.db())) | 72 | .set_documentation(self.variant.docs(self.ctx.db())) |
73 | .set_deprecated(self.ctx.is_deprecated(self.variant)) | 73 | .set_deprecated(self.ctx.is_deprecated(self.variant)) |
74 | .add_import(import_to_add) | 74 | .add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately()) |
75 | .detail(self.detail()); | 75 | .detail(self.detail()); |
76 | 76 | ||
77 | if self.variant_kind == StructKind::Tuple { | 77 | if self.variant_kind == StructKind::Tuple { |
diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs index 00e3eb203..3492384c6 100644 --- a/crates/completion/src/render/function.rs +++ b/crates/completion/src/render/function.rs | |||
@@ -47,7 +47,7 @@ impl<'a> FunctionRender<'a> { | |||
47 | .set_deprecated(self.ctx.is_deprecated(self.func)) | 47 | .set_deprecated(self.ctx.is_deprecated(self.func)) |
48 | .detail(self.detail()) | 48 | .detail(self.detail()) |
49 | .add_call_parens(self.ctx.completion, self.name, params) | 49 | .add_call_parens(self.ctx.completion, self.name, params) |
50 | .add_import(import_to_add) | 50 | .add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately()) |
51 | .build() | 51 | .build() |
52 | } | 52 | } |
53 | 53 | ||
diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index b4ab32c6e..15648b5b7 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs | |||
@@ -50,7 +50,7 @@ impl<'a> MacroRender<'a> { | |||
50 | .kind(CompletionItemKind::Macro) | 50 | .kind(CompletionItemKind::Macro) |
51 | .set_documentation(self.docs.clone()) | 51 | .set_documentation(self.docs.clone()) |
52 | .set_deprecated(self.ctx.is_deprecated(self.macro_)) | 52 | .set_deprecated(self.ctx.is_deprecated(self.macro_)) |
53 | .add_import(import_to_add) | 53 | .add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately()) |
54 | .detail(self.detail()); | 54 | .detail(self.detail()); |
55 | 55 | ||
56 | let needs_bang = self.needs_bang(); | 56 | let needs_bang = self.needs_bang(); |
diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs index 516a63b4d..88351ee15 100644 --- a/crates/completion/src/test_utils.rs +++ b/crates/completion/src/test_utils.rs | |||
@@ -97,7 +97,7 @@ pub(crate) fn check_edit_with_config( | |||
97 | .unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions)); | 97 | .unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions)); |
98 | let mut actual = db.file_text(position.file_id).to_string(); | 98 | let mut actual = db.file_text(position.file_id).to_string(); |
99 | completion.text_edit().apply(&mut actual); | 99 | completion.text_edit().apply(&mut actual); |
100 | // TODO kb how to apply imports now? | 100 | // git how to apply imports now? |
101 | assert_eq_text!(&ra_fixture_after, &actual) | 101 | assert_eq_text!(&ra_fixture_after, &actual) |
102 | } | 102 | } |
103 | 103 | ||
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index a186d2e5d..eeb2f6f93 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -623,7 +623,7 @@ pub(crate) fn handle_resolve_completion( | |||
623 | for supported_completion_resolve_cap in &snap.config.completion.resolve_capabilities { | 623 | for supported_completion_resolve_cap in &snap.config.completion.resolve_capabilities { |
624 | match supported_completion_resolve_cap { | 624 | match supported_completion_resolve_cap { |
625 | ide::CompletionResolveCapability::AdditionalTextEdits => { | 625 | ide::CompletionResolveCapability::AdditionalTextEdits => { |
626 | // TODO kb actually add all additional edits here? | 626 | // FIXME actually add all additional edits here? |
627 | if let Some(import_to_add) = server_completion_data.item.import_to_add() { | 627 | if let Some(import_to_add) = server_completion_data.item.import_to_add() { |
628 | append_import_edits( | 628 | append_import_edits( |
629 | &mut original_completion, | 629 | &mut original_completion, |
@@ -633,7 +633,7 @@ pub(crate) fn handle_resolve_completion( | |||
633 | ); | 633 | ); |
634 | } | 634 | } |
635 | } | 635 | } |
636 | // TODO kb calculate the rest also? | 636 | // FIXME resolve the other capabilities also? |
637 | _ => {} | 637 | _ => {} |
638 | } | 638 | } |
639 | } | 639 | } |