Skip to content

Commit

Permalink
Allow flyimporting excluded trait items if there is an exact match in…
Browse files Browse the repository at this point in the history
… the name

I.e. with `fn foo()`, don't complete at `x.fo|`, but complete (with imports) for `x.foo|`, since this is less likely to have false positives.

I opted to only do that for flyimport, even though for basic imports there can also be snippet completion (completing the params list for a method), since this is less universally applicable and seems not so useful.
  • Loading branch information
ChayimFriedman2 committed Sep 29, 2024
1 parent 39d3441 commit addd4fd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
20 changes: 18 additions & 2 deletions crates/ide-completion/src/completions/flyimport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ fn import_on_the_fly(

let import_cfg = ctx.config.import_path_config();

let completed_name = ctx.token.to_string();

import_assets
.search_for_imports(&ctx.sema, import_cfg, ctx.config.insert_use.prefix_kind)
.filter(ns_filter)
Expand All @@ -271,7 +273,13 @@ fn import_on_the_fly(
if let Some(ModuleDef::Trait(trait_)) = import.item_to_import.as_module_def() {
let excluded = ctx.exclude_flyimport_traits.contains(&trait_);
let trait_itself_imported = import.item_to_import == import.original_item;
!excluded || trait_itself_imported
if !excluded || trait_itself_imported {
return true;
}

let Some(item) = import.original_item.as_module_def() else { return true };
// Filter that item out, unless its name matches the name the user wrote exactly - in which case preserve it.
item.name(ctx.db).is_some_and(|name| name.eq_ident(&completed_name))
} else {
true
}
Expand Down Expand Up @@ -355,6 +363,8 @@ fn import_on_the_fly_method(

let cfg = ctx.config.import_path_config();

let completed_name = ctx.token.to_string();

import_assets
.search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind)
.filter(|import| {
Expand All @@ -363,7 +373,13 @@ fn import_on_the_fly_method(
})
.filter(|import| {
if let Some(ModuleDef::Trait(trait_)) = import.item_to_import.as_module_def() {
!ctx.exclude_flyimport_traits.contains(&trait_)
if !ctx.exclude_flyimport_traits.contains(&trait_) {
return true;
}

let Some(item) = import.original_item.as_module_def() else { return true };
// Filter that method out, unless its name matches the name the user wrote exactly - in which case preserve it.
item.name(ctx.db).is_some_and(|name| name.eq_ident(&completed_name))
} else {
true
}
Expand Down
34 changes: 33 additions & 1 deletion crates/ide-completion/src/tests/flyimport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ use expect_test::{expect, Expect};
use crate::{
context::{CompletionAnalysis, NameContext, NameKind, NameRefKind},
tests::{check_edit, check_edit_with_config, TEST_CONFIG},
CompletionConfig,
};

fn check(ra_fixture: &str, expect: Expect) {
let config = TEST_CONFIG;
check_with_config(TEST_CONFIG, ra_fixture, expect);
}

fn check_with_config(config: CompletionConfig<'_>, ra_fixture: &str, expect: Expect) {
let (db, position) = crate::tests::position(ra_fixture);
let (ctx, analysis) = crate::context::CompletionContext::new(&db, position, &config).unwrap();

Expand Down Expand Up @@ -1669,3 +1673,31 @@ mod module {
"#]],
);
}

#[test]
fn excluded_trait_item_included_when_exact_match() {
check_with_config(
CompletionConfig {
exclude_traits: &["test::module2::ExcludedTrait".to_owned()],
..TEST_CONFIG
},
r#"
mod module2 {
pub trait ExcludedTrait {
fn foo(&self) {}
fn bar(&self) {}
fn baz(&self) {}
}
impl<T> ExcludedTrait for T {}
}
fn foo() {
true.foo$0
}
"#,
expect![[r#"
me foo() (use module2::ExcludedTrait) fn(&self)
"#]],
);
}

0 comments on commit addd4fd

Please sign in to comment.