diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index a0815c3131..4b295fe9ec 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -33,6 +33,7 @@ pub struct FileSymbol { /// Whether this symbol is a doc alias for the original symbol. pub is_alias: bool, pub is_assoc: bool, + pub is_import: bool, pub do_not_complete: Complete, } @@ -196,6 +197,7 @@ impl<'a> SymbolCollector<'a> { loc: dec_loc, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Complete::Yes, }); }; @@ -226,6 +228,7 @@ impl<'a> SymbolCollector<'a> { loc: dec_loc, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Complete::Yes, }); }; @@ -397,6 +400,7 @@ impl<'a> SymbolCollector<'a> { container_name: self.current_container_name.clone(), is_alias: true, is_assoc, + is_import: false, do_not_complete, }); } @@ -409,6 +413,7 @@ impl<'a> SymbolCollector<'a> { loc: dec_loc, is_alias: false, is_assoc, + is_import: false, do_not_complete, }); @@ -441,6 +446,7 @@ impl<'a> SymbolCollector<'a> { container_name: self.current_container_name.clone(), is_alias: true, is_assoc: false, + is_import: false, do_not_complete, }); } @@ -453,6 +459,7 @@ impl<'a> SymbolCollector<'a> { loc: dec_loc, is_alias: false, is_assoc: false, + is_import: false, do_not_complete, }); } diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs index d1ba79e8c7..c15cade84a 100644 --- a/crates/ide-db/src/symbol_index.rs +++ b/crates/ide-db/src/symbol_index.rs @@ -50,6 +50,7 @@ pub struct Query { case_sensitive: bool, only_types: bool, libs: bool, + exclude_imports: bool, } impl Query { @@ -63,6 +64,7 @@ impl Query { mode: SearchMode::Fuzzy, assoc_mode: AssocSearchMode::Include, case_sensitive: false, + exclude_imports: false, } } @@ -94,6 +96,10 @@ impl Query { pub fn case_sensitive(&mut self) { self.case_sensitive = true; } + + pub fn exclude_imports(&mut self) { + self.exclude_imports = true; + } } #[query_group::query_group] @@ -362,6 +368,9 @@ impl Query { if ignore_underscore_prefixed && symbol_name.starts_with("__") { continue; } + if self.exclude_imports && symbol.is_import { + continue; + } if self.mode.check(&self.query, self.case_sensitive, symbol_name) { if let Some(b) = cb(symbol).break_value() { return Some(b); @@ -385,7 +394,8 @@ impl Query { mod tests { use expect_test::expect_file; - use test_fixture::WithFixture; + use salsa::Durability; + use test_fixture::{WORKSPACE, WithFixture}; use super::*; @@ -506,4 +516,31 @@ struct Duplicate; expect_file!["./test_data/test_doc_alias.txt"].assert_debug_eq(&symbols); } + + #[test] + fn test_exclude_imports() { + let (mut db, _) = RootDatabase::with_many_files( + r#" +//- /lib.rs +mod foo; +pub use foo::Foo; + +//- /foo.rs +pub struct Foo; +"#, + ); + + let mut local_roots = FxHashSet::default(); + local_roots.insert(WORKSPACE); + db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH); + + let mut query = Query::new("Foo".to_owned()); + let mut symbols = world_symbols(&db, query.clone()); + symbols.sort_by_key(|x| x.is_import); + expect_file!["./test_data/test_symbols_with_imports.txt"].assert_debug_eq(&symbols); + + query.exclude_imports(); + let symbols = world_symbols(&db, query); + expect_file!["./test_data/test_symbols_exclude_imports.txt"].assert_debug_eq(&symbols); + } } diff --git a/crates/ide-db/src/test_data/test_doc_alias.txt b/crates/ide-db/src/test_data/test_doc_alias.txt index 455a680590..30d1df4f8e 100644 --- a/crates/ide-db/src/test_data/test_doc_alias.txt +++ b/crates/ide-db/src/test_data/test_doc_alias.txt @@ -41,6 +41,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -74,6 +75,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -107,6 +109,7 @@ container_name: None, is_alias: true, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -140,6 +143,7 @@ container_name: None, is_alias: true, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -173,6 +177,7 @@ container_name: None, is_alias: true, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -206,6 +211,7 @@ container_name: None, is_alias: true, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -239,6 +245,7 @@ container_name: None, is_alias: true, is_assoc: false, + is_import: false, do_not_complete: Yes, }, ], diff --git a/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 5e5ae1d168..de046e70c6 100644 --- a/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -39,6 +39,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -70,6 +71,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -101,6 +103,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -134,6 +137,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -167,6 +171,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Yes, }, FileSymbol { @@ -200,6 +205,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -231,6 +237,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -264,6 +271,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -297,6 +305,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -332,6 +341,7 @@ ), is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -367,6 +377,7 @@ ), is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -400,6 +411,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -433,6 +445,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -464,6 +477,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -497,6 +511,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Yes, }, FileSymbol { @@ -530,6 +545,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -565,6 +581,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -600,6 +617,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -633,6 +651,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -666,6 +685,7 @@ ), is_alias: false, is_assoc: true, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -699,6 +719,7 @@ ), is_alias: false, is_assoc: true, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -732,6 +753,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -763,6 +785,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -796,6 +819,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Yes, }, FileSymbol { @@ -829,6 +853,7 @@ ), is_alias: false, is_assoc: true, + is_import: false, do_not_complete: Yes, }, ], @@ -875,6 +900,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, ], @@ -919,6 +945,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Yes, }, FileSymbol { @@ -952,6 +979,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Yes, }, FileSymbol { @@ -985,6 +1013,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: false, do_not_complete: Yes, }, FileSymbol { @@ -1018,6 +1047,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Yes, }, FileSymbol { @@ -1051,6 +1081,7 @@ container_name: None, is_alias: false, is_assoc: false, + is_import: true, do_not_complete: Yes, }, ], diff --git a/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt b/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt new file mode 100644 index 0000000000..22872b577f --- /dev/null +++ b/crates/ide-db/src/test_data/test_symbols_exclude_imports.txt @@ -0,0 +1,36 @@ +[ + FileSymbol { + name: "Foo", + def: Adt( + Struct( + Struct { + id: StructId( + 3800, + ), + }, + ), + ), + loc: DeclarationLocation { + hir_file_id: FileId( + EditionedFileId( + Id(2001), + ), + ), + ptr: SyntaxNodePtr { + kind: STRUCT, + range: 0..15, + }, + name_ptr: AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 11..14, + }, + ), + }, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: false, + do_not_complete: Yes, + }, +] diff --git a/crates/ide-db/src/test_data/test_symbols_with_imports.txt b/crates/ide-db/src/test_data/test_symbols_with_imports.txt new file mode 100644 index 0000000000..9f98bf87e2 --- /dev/null +++ b/crates/ide-db/src/test_data/test_symbols_with_imports.txt @@ -0,0 +1,70 @@ +[ + FileSymbol { + name: "Foo", + def: Adt( + Struct( + Struct { + id: StructId( + 3800, + ), + }, + ), + ), + loc: DeclarationLocation { + hir_file_id: FileId( + EditionedFileId( + Id(2001), + ), + ), + ptr: SyntaxNodePtr { + kind: STRUCT, + range: 0..15, + }, + name_ptr: AstPtr( + SyntaxNodePtr { + kind: NAME, + range: 11..14, + }, + ), + }, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: false, + do_not_complete: Yes, + }, + FileSymbol { + name: "Foo", + def: Adt( + Struct( + Struct { + id: StructId( + 3800, + ), + }, + ), + ), + loc: DeclarationLocation { + hir_file_id: FileId( + EditionedFileId( + Id(2000), + ), + ), + ptr: SyntaxNodePtr { + kind: USE_TREE, + range: 17..25, + }, + name_ptr: AstPtr( + SyntaxNodePtr { + kind: NAME_REF, + range: 22..25, + }, + ), + }, + container_name: None, + is_alias: false, + is_assoc: false, + is_import: true, + do_not_complete: Yes, + }, +] diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 5cbea9c2b3..762b63f54b 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -760,6 +760,8 @@ config_data! { /// though Cargo might be the eventual consumer. vfs_extraIncludes: Vec = vec![], + /// Exclude imports from symbol search. + workspace_symbol_search_excludeImports: bool = false, /// Workspace symbol search kind. workspace_symbol_search_kind: WorkspaceSymbolSearchKindDef = WorkspaceSymbolSearchKindDef::OnlyTypes, /// Limits the number of items returned from a workspace symbol search (Defaults to 128). @@ -1352,6 +1354,8 @@ pub struct RunnablesConfig { /// Configuration for workspace symbol search requests. #[derive(Debug, Clone)] pub struct WorkspaceSymbolConfig { + /// Should imports be excluded. + pub search_exclude_imports: bool, /// In what scope should the symbol be searched in. pub search_scope: WorkspaceSymbolSearchScope, /// What kind of symbol is being searched for. @@ -2280,6 +2284,7 @@ impl Config { pub fn workspace_symbol(&self, source_root: Option) -> WorkspaceSymbolConfig { WorkspaceSymbolConfig { + search_exclude_imports: *self.workspace_symbol_search_excludeImports(source_root), search_scope: match self.workspace_symbol_search_scope(source_root) { WorkspaceSymbolSearchScopeDef::Workspace => WorkspaceSymbolSearchScope::Workspace, WorkspaceSymbolSearchScopeDef::WorkspaceAndDependencies => { diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 6d46ce68ed..afd9eff526 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -658,6 +658,9 @@ pub(crate) fn handle_workspace_symbol( if libs { q.libs(); } + if config.search_exclude_imports { + q.exclude_imports(); + } q }; let mut res = exec_query(&snap, query, config.search_limit)?; diff --git a/docs/book/src/configuration_generated.md b/docs/book/src/configuration_generated.md index 0e07dadfb7..4eb9cfc4e5 100644 --- a/docs/book/src/configuration_generated.md +++ b/docs/book/src/configuration_generated.md @@ -1531,6 +1531,13 @@ buck2's `rust-project` will likely be useful: https://github.com/facebook/buck2/tree/main/integrations/rust-project. +## rust-analyzer.workspace.symbol.search.excludeImports {#workspace.symbol.search.excludeImports} + +Default: `false` + +Exclude imports from symbol search. + + ## rust-analyzer.workspace.symbol.search.kind {#workspace.symbol.search.kind} Default: `"only_types"` diff --git a/editors/code/package.json b/editors/code/package.json index c8c36cd85c..dcdb4fe30e 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -2891,6 +2891,16 @@ } } }, + { + "title": "workspace", + "properties": { + "rust-analyzer.workspace.symbol.search.excludeImports": { + "markdownDescription": "Exclude imports from symbol search.", + "default": false, + "type": "boolean" + } + } + }, { "title": "workspace", "properties": {