Unnamed repository; edit this file 'description' to name the repository.
Show case-insensitive exact matches instead of fuzzy flyimport for short paths
Lukas Wirth 2021-12-11
parent c469f8a · commit 143a30a
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs2
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs14
-rw-r--r--crates/ide_completion/src/lib.rs2
-rw-r--r--crates/ide_completion/src/tests/flyimport.rs26
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs34
-rw-r--r--crates/ide_db/src/items_locator.rs10
6 files changed, 55 insertions, 33 deletions
diff --git a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
index 3e33c62144..46bf4d7b46 100644
--- a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -65,7 +65,7 @@ pub(crate) fn replace_derive_with_manual_impl(
let found_traits = items_locator::items_with_name(
&ctx.sema,
current_crate,
- NameToImport::Exact(trait_path.segments().last()?.to_string()),
+ NameToImport::exact_case_sensitive(trait_path.segments().last()?.to_string()),
items_locator::AssocItemSearch::Exclude,
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
)
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index 3a9c1b3beb..8994c25475 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -227,22 +227,18 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs
)
} else {
let fuzzy_name_length = fuzzy_name.len();
- let assets_for_path = ImportAssets::for_fuzzy_path(
+ let mut assets_for_path = ImportAssets::for_fuzzy_path(
current_module,
ctx.path_qual().cloned(),
fuzzy_name,
&ctx.sema,
ctx.token.parent()?,
)?;
-
- if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_))
- && fuzzy_name_length < 2
- {
- cov_mark::hit!(ignore_short_input_for_path);
- None
- } else {
- Some(assets_for_path)
+ if fuzzy_name_length < 3 {
+ cov_mark::hit!(flyimport_exact_on_short_path);
+ assets_for_path.path_fuzzy_name_to_exact(false);
}
+ Some(assets_for_path)
}
}
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index d9618642c4..6a087edc4f 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -195,7 +195,7 @@ pub fn resolve_completion_edits(
let items_with_name = items_locator::items_with_name(
&ctx.sema,
current_crate,
- NameToImport::Exact(imported_name),
+ NameToImport::exact_case_sensitive(imported_name),
items_locator::AssocItemSearch::Include,
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
);
diff --git a/crates/ide_completion/src/tests/flyimport.rs b/crates/ide_completion/src/tests/flyimport.rs
index 23e5da463c..f40df62ece 100644
--- a/crates/ide_completion/src/tests/flyimport.rs
+++ b/crates/ide_completion/src/tests/flyimport.rs
@@ -96,25 +96,29 @@ fn main() {
#[test]
fn short_paths_are_ignored() {
- cov_mark::check!(ignore_short_input_for_path);
+ cov_mark::check!(flyimport_exact_on_short_path);
check(
r#"
//- /lib.rs crate:dep
-pub struct FirstStruct;
+pub struct Bar;
+pub struct Rcar;
+pub struct Rc;
pub mod some_module {
- pub struct SecondStruct;
- pub struct ThirdStruct;
+ pub struct Bar;
+ pub struct Rcar;
+ pub struct Rc;
}
//- /main.rs crate:main deps:dep
-use dep::{FirstStruct, some_module::SecondStruct};
-
fn main() {
- t$0
+ rc$0
}
"#,
- expect![[r#""#]],
+ expect![[r#"
+ st Rc (use dep::Rc)
+ st Rc (use dep::some_module::Rc)
+ "#]],
);
}
@@ -772,7 +776,7 @@ mod foo {
}
fn main() {
- TE$0
+ TES$0
}"#,
expect![[r#"
ct TEST_CONST (use foo::TEST_CONST)
@@ -789,7 +793,7 @@ mod foo {
}
fn main() {
- te$0
+ tes$0
}"#,
expect![[r#"
ct TEST_CONST (use foo::TEST_CONST)
@@ -846,7 +850,7 @@ struct Foo {
some_field: i32,
}
fn main() {
- let _ = Foo { some_field: so$0 };
+ let _ = Foo { some_field: som$0 };
}
"#,
expect![[r#"
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs
index 9a8adf167c..024e0c9f81 100644
--- a/crates/ide_db/src/helpers/import_assets.rs
+++ b/crates/ide_db/src/helpers/import_assets.rs
@@ -68,17 +68,23 @@ pub struct FirstSegmentUnresolved {
/// A name that will be used during item lookups.
#[derive(Debug, Clone)]
pub enum NameToImport {
- /// Requires items with names that exactly match the given string, case-sensitive.
- Exact(String),
+ /// Requires items with names that exactly match the given string, bool indicatse case-sensitivity.
+ Exact(String, bool),
/// Requires items with names that case-insensitively contain all letters from the string,
/// in the same order, but not necessary adjacent.
Fuzzy(String),
}
impl NameToImport {
+ pub fn exact_case_sensitive(s: String) -> NameToImport {
+ NameToImport::Exact(s, true)
+ }
+}
+
+impl NameToImport {
pub fn text(&self) -> &str {
match self {
- NameToImport::Exact(text) => text.as_str(),
+ NameToImport::Exact(text, _) => text.as_str(),
NameToImport::Fuzzy(text) => text.as_str(),
}
}
@@ -140,7 +146,7 @@ impl ImportAssets {
if let Some(_) = path.qualifier() {
return None;
}
- let name = NameToImport::Exact(path.segment()?.name_ref()?.to_string());
+ let name = NameToImport::exact_case_sensitive(path.segment()?.name_ref()?.to_string());
let candidate_node = attr.syntax().clone();
Some(Self {
import_candidate: ImportCandidate::Path(PathImportCandidate { qualifier: None, name }),
@@ -230,6 +236,18 @@ impl ImportAssets {
self.search_for(sema, None)
}
+ pub fn path_fuzzy_name_to_exact(&mut self, case_sensitive: bool) {
+ if let ImportCandidate::Path(PathImportCandidate { name: to_import, .. }) =
+ &mut self.import_candidate
+ {
+ let name = match to_import {
+ NameToImport::Fuzzy(name) => std::mem::take(name),
+ _ => return,
+ };
+ *to_import = NameToImport::Exact(name, case_sensitive);
+ }
+ }
+
fn search_for(
&self,
sema: &Semantics<RootDatabase>,
@@ -561,7 +579,9 @@ impl ImportCandidate {
Some(_) => None,
None => Some(Self::TraitMethod(TraitImportCandidate {
receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.adjusted(),
- assoc_item_name: NameToImport::Exact(method_call.name_ref()?.to_string()),
+ assoc_item_name: NameToImport::exact_case_sensitive(
+ method_call.name_ref()?.to_string(),
+ ),
})),
}
}
@@ -573,7 +593,7 @@ impl ImportCandidate {
path_import_candidate(
sema,
path.qualifier(),
- NameToImport::Exact(path.segment()?.name_ref()?.to_string()),
+ NameToImport::exact_case_sensitive(path.segment()?.name_ref()?.to_string()),
)
}
@@ -587,7 +607,7 @@ impl ImportCandidate {
}
Some(ImportCandidate::Path(PathImportCandidate {
qualifier: None,
- name: NameToImport::Exact(name.to_string()),
+ name: NameToImport::exact_case_sensitive(name.to_string()),
}))
}
diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs
index e0dbe6caf0..ca8266b6d2 100644
--- a/crates/ide_db/src/items_locator.rs
+++ b/crates/ide_db/src/items_locator.rs
@@ -50,16 +50,18 @@ pub fn items_with_name<'a>(
});
let (mut local_query, mut external_query) = match name {
- NameToImport::Exact(exact_name) => {
+ NameToImport::Exact(exact_name, case_sensitive) => {
let mut local_query = symbol_index::Query::new(exact_name.clone());
local_query.exact();
let external_query = import_map::Query::new(exact_name)
.name_only()
- .search_mode(import_map::SearchMode::Equals)
- .case_sensitive();
+ .search_mode(import_map::SearchMode::Equals);
- (local_query, external_query)
+ (
+ local_query,
+ if case_sensitive { external_query.case_sensitive() } else { external_query },
+ )
}
NameToImport::Fuzzy(fuzzy_search_string) => {
let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());