diff options
author | alcroito <[email protected]> | 2021-02-23 12:03:31 +0000 |
---|---|---|
committer | alcroito <[email protected]> | 2021-05-17 23:40:30 +0100 |
commit | 1f7d2a6c2297de4dedfb42b739e880ad2dd7d5d5 (patch) | |
tree | 46f7897cceaac302c0930dcdae99593e795b1351 /crates/rust-analyzer/src/handlers.rs | |
parent | c04eaa1f37f31d7125372ba14da3d5059297e8b2 (diff) |
Add new LSP extension for workspace symbol lookup
The new extension allows filtering of workspace symbool lookup
results by search scope or search kind.
Filtering can be configured in 3 different ways:
- The '#' or '*' markers can be added inline with the symbol lookup
query.
The '#' marker means symbols should be looked up in the current
workspace and any dependencies. If not specified, only current
workspace is considered.
The '*' marker means all kinds of symbols should be looked up
(types, functions, etc). If not specified, only type symbols are
returned.
- Each LSP request can take an optional search_scope or search_kind
argument query parameter.
- Finally there are 2 global config options that can be set for all
requests served by the active RA instance.
Add support for setting the global config options to the VSCode
extension.
The extension does not use the per-request way, but it's useful for
other IDEs.
The latest version of VSCode filters out the inline markers, so
currently the only reasonable way to use the new functionality is
via the global config.
Diffstat (limited to 'crates/rust-analyzer/src/handlers.rs')
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 8fe97fd7c..51041d7a0 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -38,7 +38,7 @@ use crate::{ | |||
38 | from_proto, | 38 | from_proto, |
39 | global_state::{GlobalState, GlobalStateSnapshot}, | 39 | global_state::{GlobalState, GlobalStateSnapshot}, |
40 | line_index::LineEndings, | 40 | line_index::LineEndings, |
41 | lsp_ext::{self, InlayHint, InlayHintsParams}, | 41 | lsp_ext::{self, InlayHint, InlayHintsParams, WorkspaceSymbolParams}, |
42 | lsp_utils::all_edits_are_disjoint, | 42 | lsp_utils::all_edits_are_disjoint, |
43 | to_proto, LspError, Result, | 43 | to_proto, LspError, Result, |
44 | }; | 44 | }; |
@@ -380,11 +380,12 @@ pub(crate) fn handle_document_symbol( | |||
380 | 380 | ||
381 | pub(crate) fn handle_workspace_symbol( | 381 | pub(crate) fn handle_workspace_symbol( |
382 | snap: GlobalStateSnapshot, | 382 | snap: GlobalStateSnapshot, |
383 | params: lsp_types::WorkspaceSymbolParams, | 383 | params: WorkspaceSymbolParams, |
384 | ) -> Result<Option<Vec<SymbolInformation>>> { | 384 | ) -> Result<Option<Vec<SymbolInformation>>> { |
385 | let _p = profile::span("handle_workspace_symbol"); | 385 | let _p = profile::span("handle_workspace_symbol"); |
386 | let all_symbols = params.query.contains('#'); | 386 | |
387 | let libs = params.query.contains('*'); | 387 | let (all_symbols, libs) = decide_search_scope_and_kind(¶ms, &snap); |
388 | |||
388 | let query = { | 389 | let query = { |
389 | let query: String = params.query.chars().filter(|&c| c != '#' && c != '*').collect(); | 390 | let query: String = params.query.chars().filter(|&c| c != '#' && c != '*').collect(); |
390 | let mut q = Query::new(query); | 391 | let mut q = Query::new(query); |
@@ -406,6 +407,45 @@ pub(crate) fn handle_workspace_symbol( | |||
406 | 407 | ||
407 | return Ok(Some(res)); | 408 | return Ok(Some(res)); |
408 | 409 | ||
410 | fn decide_search_scope_and_kind( | ||
411 | params: &WorkspaceSymbolParams, | ||
412 | snap: &GlobalStateSnapshot, | ||
413 | ) -> (bool, bool) { | ||
414 | // Support old-style parsing of markers in the query. | ||
415 | let mut all_symbols = params.query.contains('#'); | ||
416 | let mut libs = params.query.contains('*'); | ||
417 | |||
418 | let config = snap.config.workspace_symbol(); | ||
419 | |||
420 | // If no explicit marker was set, check request params. If that's also empty | ||
421 | // use global config. | ||
422 | if !all_symbols { | ||
423 | let search_kind = if let Some(ref search_kind) = params.search_kind { | ||
424 | search_kind | ||
425 | } else { | ||
426 | &config.search_kind | ||
427 | }; | ||
428 | all_symbols = match search_kind { | ||
429 | lsp_ext::WorkspaceSymbolSearchKind::OnlyTypes => false, | ||
430 | lsp_ext::WorkspaceSymbolSearchKind::AllSymbols => true, | ||
431 | } | ||
432 | } | ||
433 | |||
434 | if !libs { | ||
435 | let search_scope = if let Some(ref search_scope) = params.search_scope { | ||
436 | search_scope | ||
437 | } else { | ||
438 | &config.search_scope | ||
439 | }; | ||
440 | libs = match search_scope { | ||
441 | lsp_ext::WorkspaceSymbolSearchScope::Workspace => false, | ||
442 | lsp_ext::WorkspaceSymbolSearchScope::WorkspaceAndDependencies => true, | ||
443 | } | ||
444 | } | ||
445 | |||
446 | (all_symbols, libs) | ||
447 | } | ||
448 | |||
409 | fn exec_query(snap: &GlobalStateSnapshot, query: Query) -> Result<Vec<SymbolInformation>> { | 449 | fn exec_query(snap: &GlobalStateSnapshot, query: Query) -> Result<Vec<SymbolInformation>> { |
410 | let mut res = Vec::new(); | 450 | let mut res = Vec::new(); |
411 | for nav in snap.analysis.symbol_search(query)? { | 451 | for nav in snap.analysis.symbol_search(query)? { |