aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/completions/unqualified_path.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-08 13:10:28 +0000
committerGitHub <[email protected]>2020-12-08 13:10:28 +0000
commit4d4f11925f793c45560c45c088d4b3139c2c171c (patch)
treef8c5e3c14a0bb55d4b435b8389bccf305975d39a /crates/completion/src/completions/unqualified_path.rs
parent021e97ea03cf67ad7785ab39580e04bc69506b8c (diff)
parentbf24cb3e8db94a84fb4a24c407797ab6ff5ee109 (diff)
Merge #6706
6706: Move import text edit calculation into a completion resolve request r=matklad a=SomeoneToIgnore Part of https://github.com/rust-analyzer/rust-analyzer/issues/6612 (presumably fixing it) Part of https://github.com/rust-analyzer/rust-analyzer/issues/6366 (does not cover all possible resolve capabilities we can do) Closes https://github.com/rust-analyzer/rust-analyzer/issues/6594 Further improves imports on completion performance by deferring the computations for import inserts. To use the new mode, you have to have the experimental completions enabled and use the LSP 3.16-compliant client that reports `additionalTextEdits` in its `CompletionItemCapabilityResolveSupport` field in the client capabilities. rust-analyzer VSCode extension does this already hence picks up the changes completely. Performance implications are descrbed in: https://github.com/rust-analyzer/rust-analyzer/issues/6633#issuecomment-737295182 Co-authored-by: Kirill Bulatov <[email protected]>
Diffstat (limited to 'crates/completion/src/completions/unqualified_path.rs')
-rw-r--r--crates/completion/src/completions/unqualified_path.rs92
1 files changed, 78 insertions, 14 deletions
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index 81691cd7f..4e4e2b36f 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -9,7 +9,7 @@ use test_utils::mark;
9 9
10use crate::{ 10use crate::{
11 render::{render_resolution_with_import, RenderContext}, 11 render::{render_resolution_with_import, RenderContext},
12 CompletionContext, Completions, 12 CompletionContext, Completions, ImportEdit,
13}; 13};
14 14
15pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { 15pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
@@ -44,7 +44,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
44 acc.add_resolution(ctx, name.to_string(), &res) 44 acc.add_resolution(ctx, name.to_string(), &res)
45 }); 45 });
46 46
47 if ctx.config.enable_experimental_completions { 47 if ctx.config.enable_autoimport_completions && ctx.config.resolve_additional_edits_lazily() {
48 fuzzy_completion(acc, ctx).unwrap_or_default() 48 fuzzy_completion(acc, ctx).unwrap_or_default()
49 } 49 }
50} 50}
@@ -73,19 +73,64 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T
73 } 73 }
74} 74}
75 75
76// Feature: Fuzzy Completion and Autoimports
77//
78// When completing names in the current scope, proposes additional imports from other modules or crates,
79// if they can be qualified in the scope and their name contains all symbols from the completion input
80// (case-insensitive, in any order or places).
81//
82// ```
83// fn main() {
84// pda<|>
85// }
86// # pub mod std { pub mod marker { pub struct PhantomData { } } }
87// ```
88// ->
89// ```
90// use std::marker::PhantomData;
91//
92// fn main() {
93// PhantomData
94// }
95// # pub mod std { pub mod marker { pub struct PhantomData { } } }
96// ```
97//
98// .Fuzzy search details
99//
100// To avoid an excessive amount of the results returned, completion input is checked for inclusion in the identifiers only
101// (i.e. in `HashMap` in the `std::collections::HashMap` path), also not in the module indentifiers.
102//
103// .Merge Behaviour
104//
105// It is possible to configure how use-trees are merged with the `importMergeBehaviour` setting.
106// Mimics the corresponding behaviour of the `Auto Import` feature.
107//
108// .LSP and performance implications
109//
110// The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits`
111// (case sensitive) resolve client capability in its client capabilities.
112// This way the server is able to defer the costly computations, doing them for a selected completion item only.
113// 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 ergo the feature is automatically disabled.
115//
116// .Feature toggle
117//
118// The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.enableAutoimportCompletions` flag.
119// Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding
120// capability enabled.
76fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { 121fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
77 let _p = profile::span("fuzzy_completion"); 122 let _p = profile::span("fuzzy_completion");
123 let potential_import_name = ctx.token.to_string();
124
78 let current_module = ctx.scope.module()?; 125 let current_module = ctx.scope.module()?;
79 let anchor = ctx.name_ref_syntax.as_ref()?; 126 let anchor = ctx.name_ref_syntax.as_ref()?;
80 let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?; 127 let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
81 128
82 let potential_import_name = ctx.token.to_string();
83
84 let possible_imports = imports_locator::find_similar_imports( 129 let possible_imports = imports_locator::find_similar_imports(
85 &ctx.sema, 130 &ctx.sema,
86 ctx.krate?, 131 ctx.krate?,
132 Some(100),
87 &potential_import_name, 133 &potential_import_name,
88 50,
89 true, 134 true,
90 ) 135 )
91 .filter_map(|import_candidate| { 136 .filter_map(|import_candidate| {
@@ -99,13 +144,14 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
99 }) 144 })
100 }) 145 })
101 .filter(|(mod_path, _)| mod_path.len() > 1) 146 .filter(|(mod_path, _)| mod_path.len() > 1)
102 .take(20)
103 .filter_map(|(import_path, definition)| { 147 .filter_map(|(import_path, definition)| {
104 render_resolution_with_import( 148 render_resolution_with_import(
105 RenderContext::new(ctx), 149 RenderContext::new(ctx),
106 import_path.clone(), 150 ImportEdit {
107 import_scope.clone(), 151 import_path: import_path.clone(),
108 ctx.config.merge, 152 import_scope: import_scope.clone(),
153 merge_behaviour: ctx.config.merge,
154 },
109 &definition, 155 &definition,
110 ) 156 )
111 }); 157 });
@@ -120,8 +166,8 @@ mod tests {
120 use test_utils::mark; 166 use test_utils::mark;
121 167
122 use crate::{ 168 use crate::{
123 test_utils::{check_edit, completion_list}, 169 test_utils::{check_edit, check_edit_with_config, completion_list},
124 CompletionKind, 170 CompletionConfig, CompletionKind,
125 }; 171 };
126 172
127 fn check(ra_fixture: &str, expect: Expect) { 173 fn check(ra_fixture: &str, expect: Expect) {
@@ -730,7 +776,13 @@ impl My<|>
730 776
731 #[test] 777 #[test]
732 fn function_fuzzy_completion() { 778 fn function_fuzzy_completion() {
733 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,
734 "stdin", 786 "stdin",
735 r#" 787 r#"
736//- /lib.rs crate:dep 788//- /lib.rs crate:dep
@@ -755,7 +807,13 @@ fn main() {
755 807
756 #[test] 808 #[test]
757 fn macro_fuzzy_completion() { 809 fn macro_fuzzy_completion() {
758 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,
759 "macro_with_curlies!", 817 "macro_with_curlies!",
760 r#" 818 r#"
761//- /lib.rs crate:dep 819//- /lib.rs crate:dep
@@ -782,7 +840,13 @@ fn main() {
782 840
783 #[test] 841 #[test]
784 fn struct_fuzzy_completion() { 842 fn struct_fuzzy_completion() {
785 check_edit( 843 let mut completion_config = CompletionConfig::default();
844 completion_config
845 .active_resolve_capabilities
846 .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
847
848 check_edit_with_config(
849 completion_config,
786 "ThirdStruct", 850 "ThirdStruct",
787 r#" 851 r#"
788//- /lib.rs crate:dep 852//- /lib.rs crate:dep