mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
Show case-insensitive exact matches instead of fuzzy flyimport for short paths
This commit is contained in:
parent
c469f8abcb
commit
143a30aa51
6 changed files with 55 additions and 33 deletions
|
@ -65,7 +65,7 @@ pub(crate) fn replace_derive_with_manual_impl(
|
||||||
let found_traits = items_locator::items_with_name(
|
let found_traits = items_locator::items_with_name(
|
||||||
&ctx.sema,
|
&ctx.sema,
|
||||||
current_crate,
|
current_crate,
|
||||||
NameToImport::Exact(trait_path.segments().last()?.to_string()),
|
NameToImport::exact_case_sensitive(trait_path.segments().last()?.to_string()),
|
||||||
items_locator::AssocItemSearch::Exclude,
|
items_locator::AssocItemSearch::Exclude,
|
||||||
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
|
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
|
||||||
)
|
)
|
||||||
|
|
|
@ -227,22 +227,18 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let fuzzy_name_length = fuzzy_name.len();
|
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,
|
current_module,
|
||||||
ctx.path_qual().cloned(),
|
ctx.path_qual().cloned(),
|
||||||
fuzzy_name,
|
fuzzy_name,
|
||||||
&ctx.sema,
|
&ctx.sema,
|
||||||
ctx.token.parent()?,
|
ctx.token.parent()?,
|
||||||
)?;
|
)?;
|
||||||
|
if fuzzy_name_length < 3 {
|
||||||
if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_))
|
cov_mark::hit!(flyimport_exact_on_short_path);
|
||||||
&& fuzzy_name_length < 2
|
assets_for_path.path_fuzzy_name_to_exact(false);
|
||||||
{
|
|
||||||
cov_mark::hit!(ignore_short_input_for_path);
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(assets_for_path)
|
|
||||||
}
|
}
|
||||||
|
Some(assets_for_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ pub fn resolve_completion_edits(
|
||||||
let items_with_name = items_locator::items_with_name(
|
let items_with_name = items_locator::items_with_name(
|
||||||
&ctx.sema,
|
&ctx.sema,
|
||||||
current_crate,
|
current_crate,
|
||||||
NameToImport::Exact(imported_name),
|
NameToImport::exact_case_sensitive(imported_name),
|
||||||
items_locator::AssocItemSearch::Include,
|
items_locator::AssocItemSearch::Include,
|
||||||
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
|
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
|
||||||
);
|
);
|
||||||
|
|
|
@ -96,25 +96,29 @@ fn main() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn short_paths_are_ignored() {
|
fn short_paths_are_ignored() {
|
||||||
cov_mark::check!(ignore_short_input_for_path);
|
cov_mark::check!(flyimport_exact_on_short_path);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
//- /lib.rs crate:dep
|
//- /lib.rs crate:dep
|
||||||
pub struct FirstStruct;
|
pub struct Bar;
|
||||||
|
pub struct Rcar;
|
||||||
|
pub struct Rc;
|
||||||
pub mod some_module {
|
pub mod some_module {
|
||||||
pub struct SecondStruct;
|
pub struct Bar;
|
||||||
pub struct ThirdStruct;
|
pub struct Rcar;
|
||||||
|
pub struct Rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- /main.rs crate:main deps:dep
|
//- /main.rs crate:main deps:dep
|
||||||
use dep::{FirstStruct, some_module::SecondStruct};
|
|
||||||
|
|
||||||
fn main() {
|
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() {
|
fn main() {
|
||||||
TE$0
|
TES$0
|
||||||
}"#,
|
}"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
ct TEST_CONST (use foo::TEST_CONST)
|
ct TEST_CONST (use foo::TEST_CONST)
|
||||||
|
@ -789,7 +793,7 @@ mod foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
te$0
|
tes$0
|
||||||
}"#,
|
}"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
ct TEST_CONST (use foo::TEST_CONST)
|
ct TEST_CONST (use foo::TEST_CONST)
|
||||||
|
@ -846,7 +850,7 @@ struct Foo {
|
||||||
some_field: i32,
|
some_field: i32,
|
||||||
}
|
}
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = Foo { some_field: so$0 };
|
let _ = Foo { some_field: som$0 };
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
|
|
|
@ -68,17 +68,23 @@ pub struct FirstSegmentUnresolved {
|
||||||
/// A name that will be used during item lookups.
|
/// A name that will be used during item lookups.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum NameToImport {
|
pub enum NameToImport {
|
||||||
/// Requires items with names that exactly match the given string, case-sensitive.
|
/// Requires items with names that exactly match the given string, bool indicatse case-sensitivity.
|
||||||
Exact(String),
|
Exact(String, bool),
|
||||||
/// Requires items with names that case-insensitively contain all letters from the string,
|
/// Requires items with names that case-insensitively contain all letters from the string,
|
||||||
/// in the same order, but not necessary adjacent.
|
/// in the same order, but not necessary adjacent.
|
||||||
Fuzzy(String),
|
Fuzzy(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NameToImport {
|
||||||
|
pub fn exact_case_sensitive(s: String) -> NameToImport {
|
||||||
|
NameToImport::Exact(s, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl NameToImport {
|
impl NameToImport {
|
||||||
pub fn text(&self) -> &str {
|
pub fn text(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
NameToImport::Exact(text) => text.as_str(),
|
NameToImport::Exact(text, _) => text.as_str(),
|
||||||
NameToImport::Fuzzy(text) => text.as_str(),
|
NameToImport::Fuzzy(text) => text.as_str(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +146,7 @@ impl ImportAssets {
|
||||||
if let Some(_) = path.qualifier() {
|
if let Some(_) = path.qualifier() {
|
||||||
return None;
|
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();
|
let candidate_node = attr.syntax().clone();
|
||||||
Some(Self {
|
Some(Self {
|
||||||
import_candidate: ImportCandidate::Path(PathImportCandidate { qualifier: None, name }),
|
import_candidate: ImportCandidate::Path(PathImportCandidate { qualifier: None, name }),
|
||||||
|
@ -230,6 +236,18 @@ impl ImportAssets {
|
||||||
self.search_for(sema, None)
|
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(
|
fn search_for(
|
||||||
&self,
|
&self,
|
||||||
sema: &Semantics<RootDatabase>,
|
sema: &Semantics<RootDatabase>,
|
||||||
|
@ -561,7 +579,9 @@ impl ImportCandidate {
|
||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => Some(Self::TraitMethod(TraitImportCandidate {
|
None => Some(Self::TraitMethod(TraitImportCandidate {
|
||||||
receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.adjusted(),
|
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(
|
path_import_candidate(
|
||||||
sema,
|
sema,
|
||||||
path.qualifier(),
|
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 {
|
Some(ImportCandidate::Path(PathImportCandidate {
|
||||||
qualifier: None,
|
qualifier: None,
|
||||||
name: NameToImport::Exact(name.to_string()),
|
name: NameToImport::exact_case_sensitive(name.to_string()),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,16 +50,18 @@ pub fn items_with_name<'a>(
|
||||||
});
|
});
|
||||||
|
|
||||||
let (mut local_query, mut external_query) = match name {
|
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());
|
let mut local_query = symbol_index::Query::new(exact_name.clone());
|
||||||
local_query.exact();
|
local_query.exact();
|
||||||
|
|
||||||
let external_query = import_map::Query::new(exact_name)
|
let external_query = import_map::Query::new(exact_name)
|
||||||
.name_only()
|
.name_only()
|
||||||
.search_mode(import_map::SearchMode::Equals)
|
.search_mode(import_map::SearchMode::Equals);
|
||||||
.case_sensitive();
|
|
||||||
|
|
||||||
(local_query, external_query)
|
(
|
||||||
|
local_query,
|
||||||
|
if case_sensitive { external_query.case_sensitive() } else { external_query },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
NameToImport::Fuzzy(fuzzy_search_string) => {
|
NameToImport::Fuzzy(fuzzy_search_string) => {
|
||||||
let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());
|
let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue