aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ide_db/src/symbol_index.rs5
-rw-r--r--crates/rust-analyzer/src/config.rs63
-rw-r--r--crates/rust-analyzer/src/handlers.rs48
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs42
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
5 files changed, 153 insertions, 7 deletions
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs
index da427d686..0f5c4abc4 100644
--- a/crates/ide_db/src/symbol_index.rs
+++ b/crates/ide_db/src/symbol_index.rs
@@ -161,6 +161,11 @@ impl<DB: ParallelDatabase> Clone for Snap<salsa::Snapshot<DB>> {
161// That is, `#` switches from "types" to all symbols, `*` switches from the current 161// That is, `#` switches from "types" to all symbols, `*` switches from the current
162// workspace to dependencies. 162// workspace to dependencies.
163// 163//
164// Note that filtering does not currently work in VSCode due to the editor never
165// sending the special symbols to the language server. Instead, you can configure
166// the filtering via the `rust-analyzer.workspace.symbol.search.scope` and
167// `rust-analyzer.workspace.symbol.search.kind` settings.
168//
164// |=== 169// |===
165// | Editor | Shortcut 170// | Editor | Shortcut
166// 171//
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index a3866c1ba..339014fd3 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -24,7 +24,8 @@ use vfs::AbsPathBuf;
24 24
25use crate::{ 25use crate::{
26 caps::completion_item_edit_resolve, diagnostics::DiagnosticsMapConfig, 26 caps::completion_item_edit_resolve, diagnostics::DiagnosticsMapConfig,
27 line_index::OffsetEncoding, lsp_ext::supports_utf8, 27 line_index::OffsetEncoding, lsp_ext::supports_utf8, lsp_ext::WorkspaceSymbolSearchKind,
28 lsp_ext::WorkspaceSymbolSearchScope,
28}; 29};
29 30
30// Defines the server-side configuration of the rust-analyzer. We generate 31// Defines the server-side configuration of the rust-analyzer. We generate
@@ -215,6 +216,11 @@ config_data! {
215 /// Advanced option, fully override the command rust-analyzer uses for 216 /// Advanced option, fully override the command rust-analyzer uses for
216 /// formatting. 217 /// formatting.
217 rustfmt_overrideCommand: Option<Vec<String>> = "null", 218 rustfmt_overrideCommand: Option<Vec<String>> = "null",
219
220 /// Workspace symbol search scope.
221 workspace_symbol_search_scope: WorskpaceSymbolSearchScopeDef = "\"workspace\"",
222 /// Workspace symbol search kind.
223 workspace_symbol_search_kind: WorskpaceSymbolSearchKindDef = "\"only_types\"",
218 } 224 }
219} 225}
220 226
@@ -309,6 +315,15 @@ pub struct RunnablesConfig {
309 pub cargo_extra_args: Vec<String>, 315 pub cargo_extra_args: Vec<String>,
310} 316}
311 317
318/// Configuration for workspace symbol search requests.
319#[derive(Debug, Clone)]
320pub struct WorkspaceSymbolConfig {
321 /// In what scope should the symbol be searched in.
322 pub search_scope: WorkspaceSymbolSearchScope,
323 /// What kind of symbol is being search for.
324 pub search_kind: WorkspaceSymbolSearchKind,
325}
326
312impl Config { 327impl Config {
313 pub fn new(root_path: AbsPathBuf, caps: ClientCapabilities) -> Self { 328 pub fn new(root_path: AbsPathBuf, caps: ClientCapabilities) -> Self {
314 Config { caps, data: ConfigData::default(), discovered_projects: None, root_path } 329 Config { caps, data: ConfigData::default(), discovered_projects: None, root_path }
@@ -687,6 +702,22 @@ impl Config {
687 .contains(&MarkupKind::Markdown), 702 .contains(&MarkupKind::Markdown),
688 } 703 }
689 } 704 }
705
706 pub fn workspace_symbol(&self) -> WorkspaceSymbolConfig {
707 WorkspaceSymbolConfig {
708 search_scope: match self.data.workspace_symbol_search_scope {
709 WorskpaceSymbolSearchScopeDef::Workspace => WorkspaceSymbolSearchScope::Workspace,
710 WorskpaceSymbolSearchScopeDef::WorkspaceAndDependencies => {
711 WorkspaceSymbolSearchScope::WorkspaceAndDependencies
712 }
713 },
714 search_kind: match self.data.workspace_symbol_search_kind {
715 WorskpaceSymbolSearchKindDef::OnlyTypes => WorkspaceSymbolSearchKind::OnlyTypes,
716 WorskpaceSymbolSearchKindDef::AllSymbols => WorkspaceSymbolSearchKind::AllSymbols,
717 },
718 }
719 }
720
690 pub fn semantic_tokens_refresh(&self) -> bool { 721 pub fn semantic_tokens_refresh(&self) -> bool {
691 try_or!(self.caps.workspace.as_ref()?.semantic_tokens.as_ref()?.refresh_support?, false) 722 try_or!(self.caps.workspace.as_ref()?.semantic_tokens.as_ref()?.refresh_support?, false)
692 } 723 }
@@ -733,6 +764,20 @@ enum ImportPrefixDef {
733 ByCrate, 764 ByCrate,
734} 765}
735 766
767#[derive(Deserialize, Debug, Clone)]
768#[serde(rename_all = "snake_case")]
769enum WorskpaceSymbolSearchScopeDef {
770 Workspace,
771 WorkspaceAndDependencies,
772}
773
774#[derive(Deserialize, Debug, Clone)]
775#[serde(rename_all = "snake_case")]
776enum WorskpaceSymbolSearchKindDef {
777 OnlyTypes,
778 AllSymbols,
779}
780
736macro_rules! _config_data { 781macro_rules! _config_data {
737 (struct $name:ident { 782 (struct $name:ident {
738 $( 783 $(
@@ -903,6 +948,22 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
903 "type": "array", 948 "type": "array",
904 "items": { "type": ["string", "object"] }, 949 "items": { "type": ["string", "object"] },
905 }, 950 },
951 "WorskpaceSymbolSearchScopeDef" => set! {
952 "type": "string",
953 "enum": ["workspace", "workspace_and_dependencies"],
954 "enumDescriptions": [
955 "Search in current workspace only",
956 "Search in current workspace and dependencies"
957 ],
958 },
959 "WorskpaceSymbolSearchKindDef" => set! {
960 "type": "string",
961 "enum": ["only_types", "all_symbols"],
962 "enumDescriptions": [
963 "Search for types only",
964 "Search for all symbols kinds"
965 ],
966 },
906 _ => panic!("{}: {}", ty, default), 967 _ => panic!("{}: {}", ty, default),
907 } 968 }
908 969
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
381pub(crate) fn handle_workspace_symbol( 381pub(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(&params, &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)? {
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index 3bd098058..34b53a7a8 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -4,7 +4,8 @@ use std::{collections::HashMap, path::PathBuf};
4 4
5use lsp_types::request::Request; 5use lsp_types::request::Request;
6use lsp_types::{ 6use lsp_types::{
7 notification::Notification, CodeActionKind, Position, Range, TextDocumentIdentifier, 7 notification::Notification, CodeActionKind, PartialResultParams, Position, Range,
8 TextDocumentIdentifier, WorkDoneProgressParams,
8}; 9};
9use serde::{Deserialize, Serialize}; 10use serde::{Deserialize, Serialize};
10 11
@@ -438,3 +439,42 @@ pub enum MoveItemDirection {
438 Up, 439 Up,
439 Down, 440 Down,
440} 441}
442
443#[derive(Debug)]
444pub enum WorkspaceSymbol {}
445
446impl Request for WorkspaceSymbol {
447 type Params = WorkspaceSymbolParams;
448 type Result = Option<Vec<lsp_types::SymbolInformation>>;
449 const METHOD: &'static str = "workspace/symbol";
450}
451
452#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
453pub struct WorkspaceSymbolParams {
454 #[serde(flatten)]
455 pub partial_result_params: PartialResultParams,
456
457 #[serde(flatten)]
458 pub work_done_progress_params: WorkDoneProgressParams,
459
460 /// A non-empty query string
461 pub query: String,
462
463 pub search_scope: Option<WorkspaceSymbolSearchScope>,
464
465 pub search_kind: Option<WorkspaceSymbolSearchKind>,
466}
467
468#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
469#[serde(rename_all = "camelCase")]
470pub enum WorkspaceSymbolSearchScope {
471 Workspace,
472 WorkspaceAndDependencies,
473}
474
475#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
476#[serde(rename_all = "camelCase")]
477pub enum WorkspaceSymbolSearchKind {
478 OnlyTypes,
479 AllSymbols,
480}
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index c7bd7eee1..4e0791611 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -525,9 +525,9 @@ impl GlobalState {
525 .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs) 525 .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
526 .on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml) 526 .on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
527 .on::<lsp_ext::MoveItem>(handlers::handle_move_item) 527 .on::<lsp_ext::MoveItem>(handlers::handle_move_item)
528 .on::<lsp_ext::WorkspaceSymbol>(handlers::handle_workspace_symbol)
528 .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting) 529 .on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
529 .on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol) 530 .on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
530 .on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol)
531 .on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition) 531 .on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition)
532 .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation) 532 .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation)
533 .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition) 533 .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition)