Skip to content

Commit 3183ff3

Browse files
Disable the completion for no corresponding client resolve capabilities
1 parent 9656ceb commit 3183ff3

File tree

12 files changed

+87
-163
lines changed

12 files changed

+87
-163
lines changed

crates/completion/src/completions/unqualified_path.rs

Lines changed: 58 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
4444
acc.add_resolution(ctx, name.to_string(), &res)
4545
});
4646

47-
if ctx.config.enable_experimental_completions {
47+
if !ctx.config.disable_fuzzy_autoimports && ctx.config.resolve_additional_edits_lazily() {
4848
fuzzy_completion(acc, ctx).unwrap_or_default()
4949
}
5050
}
@@ -99,6 +99,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T
9999
//
100100
// To avoid an excessive amount of the results returned, completion input is checked for inclusion in the identifiers only
101101
// (i.e. in `HashMap` in the `std::collections::HashMap` path), also not in the module indentifiers.
102+
// It also avoids searching for any imports for inputs with their length less that 3 symbols.
102103
//
103104
// .Merge Behaviour
104105
//
@@ -107,53 +108,53 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T
107108
//
108109
// .LSP and performance implications
109110
//
110-
// LSP 3.16 provides the way to defer the computation of some completion data, including the import edits for this feature.
111-
// If the LSP client supports the `additionalTextEdits` (case sensitive) resolve client capability, rust-analyzer computes
112-
// the completion edits only when a corresponding completion item is selected.
111+
// The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits`
112+
// (case sensitive) resolve client capability in its client capabilities.
113+
// This way the server is able to defer the costly computations, doing them for a selected completion item only.
113114
// For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones,
114-
// which might be slow.
115+
// which might be slow ergo the feature is automatically disabled.
115116
//
116117
// .Feature toggle
117118
//
118-
// The feature can be turned off in the settings with the `rust-analyzer.completion.enableExperimental` flag.
119+
// The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.disableFuzzyAutoimports` flag.
119120
fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
120121
let _p = profile::span("fuzzy_completion");
122+
let potential_import_name = ctx.token.to_string();
123+
124+
if potential_import_name.len() < 3 {
125+
return None;
126+
}
127+
121128
let current_module = ctx.scope.module()?;
122129
let anchor = ctx.name_ref_syntax.as_ref()?;
123130
let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
124131

125-
let potential_import_name = ctx.token.to_string();
126-
127-
let possible_imports = imports_locator::find_similar_imports(
128-
&ctx.sema,
129-
ctx.krate?,
130-
&potential_import_name,
131-
50,
132-
true,
133-
)
134-
.filter_map(|import_candidate| {
135-
Some(match import_candidate {
136-
Either::Left(module_def) => {
137-
(current_module.find_use_path(ctx.db, module_def)?, ScopeDef::ModuleDef(module_def))
138-
}
139-
Either::Right(macro_def) => {
140-
(current_module.find_use_path(ctx.db, macro_def)?, ScopeDef::MacroDef(macro_def))
141-
}
142-
})
143-
})
144-
.filter(|(mod_path, _)| mod_path.len() > 1)
145-
.take(20)
146-
.filter_map(|(import_path, definition)| {
147-
render_resolution_with_import(
148-
RenderContext::new(ctx),
149-
ImportEdit {
150-
import_path: import_path.clone(),
151-
import_scope: import_scope.clone(),
152-
merge_behaviour: ctx.config.merge,
153-
},
154-
&definition,
155-
)
156-
});
132+
let possible_imports =
133+
imports_locator::find_similar_imports(&ctx.sema, ctx.krate?, &potential_import_name, true)
134+
.filter_map(|import_candidate| {
135+
Some(match import_candidate {
136+
Either::Left(module_def) => (
137+
current_module.find_use_path(ctx.db, module_def)?,
138+
ScopeDef::ModuleDef(module_def),
139+
),
140+
Either::Right(macro_def) => (
141+
current_module.find_use_path(ctx.db, macro_def)?,
142+
ScopeDef::MacroDef(macro_def),
143+
),
144+
})
145+
})
146+
.filter(|(mod_path, _)| mod_path.len() > 1)
147+
.filter_map(|(import_path, definition)| {
148+
render_resolution_with_import(
149+
RenderContext::new(ctx),
150+
ImportEdit {
151+
import_path: import_path.clone(),
152+
import_scope: import_scope.clone(),
153+
merge_behaviour: ctx.config.merge,
154+
},
155+
&definition,
156+
)
157+
});
157158

158159
acc.add_all(possible_imports);
159160
Some(())
@@ -775,7 +776,13 @@ impl My<|>
775776

776777
#[test]
777778
fn function_fuzzy_completion() {
778-
check_edit(
779+
let mut completion_config = CompletionConfig::default();
780+
completion_config
781+
.active_resolve_capabilities
782+
.insert(crate::CompletionResolveCapability::AdditionalTextEdits);
783+
784+
check_edit_with_config(
785+
completion_config,
779786
"stdin",
780787
r#"
781788
//- /lib.rs crate:dep
@@ -800,7 +807,13 @@ fn main() {
800807

801808
#[test]
802809
fn macro_fuzzy_completion() {
803-
check_edit(
810+
let mut completion_config = CompletionConfig::default();
811+
completion_config
812+
.active_resolve_capabilities
813+
.insert(crate::CompletionResolveCapability::AdditionalTextEdits);
814+
815+
check_edit_with_config(
816+
completion_config,
804817
"macro_with_curlies!",
805818
r#"
806819
//- /lib.rs crate:dep
@@ -827,37 +840,6 @@ fn main() {
827840

828841
#[test]
829842
fn struct_fuzzy_completion() {
830-
check_edit(
831-
"ThirdStruct",
832-
r#"
833-
//- /lib.rs crate:dep
834-
pub struct FirstStruct;
835-
pub mod some_module {
836-
pub struct SecondStruct;
837-
pub struct ThirdStruct;
838-
}
839-
840-
//- /main.rs crate:main deps:dep
841-
use dep::{FirstStruct, some_module::SecondStruct};
842-
843-
fn main() {
844-
this<|>
845-
}
846-
"#,
847-
r#"
848-
use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
849-
850-
fn main() {
851-
ThirdStruct
852-
}
853-
"#,
854-
);
855-
}
856-
857-
/// LSP protocol supports separate completion resolve requests to do the heavy computations there.
858-
/// This test checks that for a certain resolve capatilities no such operations (autoimport) are done.
859-
#[test]
860-
fn no_fuzzy_completions_applied_for_certain_resolve_capability() {
861843
let mut completion_config = CompletionConfig::default();
862844
completion_config
863845
.active_resolve_capabilities
@@ -870,22 +852,22 @@ fn main() {
870852
//- /lib.rs crate:dep
871853
pub struct FirstStruct;
872854
pub mod some_module {
873-
pub struct SecondStruct;
874-
pub struct ThirdStruct;
855+
pub struct SecondStruct;
856+
pub struct ThirdStruct;
875857
}
876858
877859
//- /main.rs crate:main deps:dep
878860
use dep::{FirstStruct, some_module::SecondStruct};
879861
880862
fn main() {
881-
this<|>
863+
this<|>
882864
}
883865
"#,
884866
r#"
885-
use dep::{FirstStruct, some_module::SecondStruct};
867+
use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
886868
887869
fn main() {
888-
ThirdStruct
870+
ThirdStruct
889871
}
890872
"#,
891873
);

crates/completion/src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_hash::FxHashSet;
1010
#[derive(Clone, Debug, PartialEq, Eq)]
1111
pub struct CompletionConfig {
1212
pub enable_postfix_completions: bool,
13-
pub enable_experimental_completions: bool,
13+
pub disable_fuzzy_autoimports: bool,
1414
pub add_call_parenthesis: bool,
1515
pub add_call_argument_snippets: bool,
1616
pub snippet_cap: Option<SnippetCap>,
@@ -52,7 +52,7 @@ impl Default for CompletionConfig {
5252
fn default() -> Self {
5353
CompletionConfig {
5454
enable_postfix_completions: true,
55-
enable_experimental_completions: true,
55+
disable_fuzzy_autoimports: false,
5656
add_call_parenthesis: true,
5757
add_call_argument_snippets: true,
5858
snippet_cap: Some(SnippetCap { _private: () }),

crates/completion/src/item.rs

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ impl CompletionItem {
209209
score: None,
210210
ref_match: None,
211211
import_to_add: None,
212-
resolve_import_lazily: false,
213212
}
214213
}
215214

@@ -301,7 +300,6 @@ pub(crate) struct Builder {
301300
source_range: TextRange,
302301
completion_kind: CompletionKind,
303302
import_to_add: Option<ImportEdit>,
304-
resolve_import_lazily: bool,
305303
label: String,
306304
insert_text: Option<String>,
307305
insert_text_format: InsertTextFormat,
@@ -339,25 +337,13 @@ impl Builder {
339337
}
340338
}
341339

342-
let mut text_edit = match self.text_edit {
340+
let text_edit = match self.text_edit {
343341
Some(it) => it,
344342
None => {
345343
TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone()))
346344
}
347345
};
348346

349-
let import_to_add = if self.resolve_import_lazily {
350-
self.import_to_add
351-
} else {
352-
match apply_import_eagerly(self.import_to_add.as_ref(), &mut text_edit) {
353-
Ok(()) => self.import_to_add,
354-
Err(()) => {
355-
log::error!("Failed to apply eager import edit: original edit and import edit intersect");
356-
None
357-
}
358-
}
359-
};
360-
361347
CompletionItem {
362348
source_range: self.source_range,
363349
label,
@@ -372,7 +358,7 @@ impl Builder {
372358
trigger_call_info: self.trigger_call_info.unwrap_or(false),
373359
score: self.score,
374360
ref_match: self.ref_match,
375-
import_to_add,
361+
import_to_add: self.import_to_add,
376362
}
377363
}
378364
pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder {
@@ -435,13 +421,8 @@ impl Builder {
435421
self.trigger_call_info = Some(true);
436422
self
437423
}
438-
pub(crate) fn add_import(
439-
mut self,
440-
import_to_add: Option<ImportEdit>,
441-
resolve_import_lazily: bool,
442-
) -> Builder {
424+
pub(crate) fn add_import(mut self, import_to_add: Option<ImportEdit>) -> Builder {
443425
self.import_to_add = import_to_add;
444-
self.resolve_import_lazily = resolve_import_lazily;
445426
self
446427
}
447428
pub(crate) fn set_ref_match(
@@ -453,16 +434,6 @@ impl Builder {
453434
}
454435
}
455436

456-
fn apply_import_eagerly(
457-
import_to_add: Option<&ImportEdit>,
458-
original_edit: &mut TextEdit,
459-
) -> Result<(), ()> {
460-
match import_to_add.and_then(|import_edit| import_edit.to_text_edit()) {
461-
Some(import_edit) => original_edit.union(import_edit).map_err(|_| ()),
462-
None => Ok(()),
463-
}
464-
}
465-
466437
impl<'a> Into<CompletionItem> for Builder {
467438
fn into(self) -> CompletionItem {
468439
self.build()

crates/completion/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub use crate::{
7373
// }
7474
// ```
7575
//
76-
// And experimental completions, enabled with the `rust-analyzer.completion.enableExperimental` setting.
76+
// And experimental completions, enabled with the `rust-analyzer.completion.disableFuzzyAutoimports` setting.
7777
// This flag enables or disables:
7878
//
7979
// - Auto import: additional completion options with automatic `use` import and options from all project importable items, matched for the input

crates/completion/src/render.rs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,7 @@ impl<'a> Render<'a> {
190190
local_name,
191191
)
192192
.kind(CompletionItemKind::UnresolvedReference)
193-
.add_import(
194-
import_to_add,
195-
self.ctx.completion.config.resolve_additional_edits_lazily(),
196-
)
193+
.add_import(import_to_add)
197194
.build();
198195
return Some(item);
199196
}
@@ -248,7 +245,7 @@ impl<'a> Render<'a> {
248245

249246
let item = item
250247
.kind(kind)
251-
.add_import(import_to_add, self.ctx.completion.config.resolve_additional_edits_lazily())
248+
.add_import(import_to_add)
252249
.set_documentation(docs)
253250
.set_ref_match(ref_match)
254251
.build();
@@ -449,28 +446,6 @@ fn main() { let _: m::Spam = S<|> }
449446
insert: "m",
450447
kind: Module,
451448
},
452-
CompletionItem {
453-
label: "m::Spam",
454-
source_range: 75..76,
455-
text_edit: TextEdit {
456-
indels: [
457-
Indel {
458-
insert: "use m::Spam;",
459-
delete: 0..0,
460-
},
461-
Indel {
462-
insert: "\n\n",
463-
delete: 0..0,
464-
},
465-
Indel {
466-
insert: "Spam",
467-
delete: 75..76,
468-
},
469-
],
470-
},
471-
kind: Enum,
472-
lookup: "Spam",
473-
},
474449
CompletionItem {
475450
label: "m::Spam::Foo",
476451
source_range: 75..76,

crates/completion/src/render/enum_variant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl<'a> EnumVariantRender<'a> {
7171
.kind(CompletionItemKind::EnumVariant)
7272
.set_documentation(self.variant.docs(self.ctx.db()))
7373
.set_deprecated(self.ctx.is_deprecated(self.variant))
74-
.add_import(import_to_add, self.ctx.completion.config.resolve_additional_edits_lazily())
74+
.add_import(import_to_add)
7575
.detail(self.detail());
7676

7777
if self.variant_kind == StructKind::Tuple {

crates/completion/src/render/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl<'a> FunctionRender<'a> {
4747
.set_deprecated(self.ctx.is_deprecated(self.func))
4848
.detail(self.detail())
4949
.add_call_parens(self.ctx.completion, self.name, params)
50-
.add_import(import_to_add, self.ctx.completion.config.resolve_additional_edits_lazily())
50+
.add_import(import_to_add)
5151
.build()
5252
}
5353

crates/completion/src/render/macro_.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,7 @@ impl<'a> MacroRender<'a> {
5050
.kind(CompletionItemKind::Macro)
5151
.set_documentation(self.docs.clone())
5252
.set_deprecated(self.ctx.is_deprecated(self.macro_))
53-
.add_import(
54-
import_to_add,
55-
self.ctx.completion.config.resolve_additional_edits_lazily(),
56-
)
53+
.add_import(import_to_add)
5754
.detail(self.detail());
5855

5956
let needs_bang = self.needs_bang();

0 commit comments

Comments
 (0)