Merge #7698
7698: Add new LSP extension for workspace symbol lookup r=matklad a=alcroito As well as all symbol types (functions, modules). Remove outdated documentation regarding symbol lookup filtering. Closes #4881 Co-authored-by: alcroito <placinta@gmail.com>
This commit is contained in:
commit
49a5d6a8d4
@ -161,6 +161,11 @@ impl<DB: ParallelDatabase> Clone for Snap<salsa::Snapshot<DB>> {
|
||||
// That is, `#` switches from "types" to all symbols, `*` switches from the current
|
||||
// workspace to dependencies.
|
||||
//
|
||||
// Note that filtering does not currently work in VSCode due to the editor never
|
||||
// sending the special symbols to the language server. Instead, you can configure
|
||||
// the filtering via the `rust-analyzer.workspace.symbol.search.scope` and
|
||||
// `rust-analyzer.workspace.symbol.search.kind` settings.
|
||||
//
|
||||
// |===
|
||||
// | Editor | Shortcut
|
||||
//
|
||||
|
@ -24,7 +24,8 @@ use vfs::AbsPathBuf;
|
||||
|
||||
use crate::{
|
||||
caps::completion_item_edit_resolve, diagnostics::DiagnosticsMapConfig,
|
||||
line_index::OffsetEncoding, lsp_ext::supports_utf8,
|
||||
line_index::OffsetEncoding, lsp_ext::supports_utf8, lsp_ext::WorkspaceSymbolSearchKind,
|
||||
lsp_ext::WorkspaceSymbolSearchScope,
|
||||
};
|
||||
|
||||
// Defines the server-side configuration of the rust-analyzer. We generate
|
||||
@ -215,6 +216,11 @@ config_data! {
|
||||
/// Advanced option, fully override the command rust-analyzer uses for
|
||||
/// formatting.
|
||||
rustfmt_overrideCommand: Option<Vec<String>> = "null",
|
||||
|
||||
/// Workspace symbol search scope.
|
||||
workspace_symbol_search_scope: WorskpaceSymbolSearchScopeDef = "\"workspace\"",
|
||||
/// Workspace symbol search kind.
|
||||
workspace_symbol_search_kind: WorskpaceSymbolSearchKindDef = "\"only_types\"",
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,6 +315,15 @@ pub struct RunnablesConfig {
|
||||
pub cargo_extra_args: Vec<String>,
|
||||
}
|
||||
|
||||
/// Configuration for workspace symbol search requests.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WorkspaceSymbolConfig {
|
||||
/// In what scope should the symbol be searched in.
|
||||
pub search_scope: WorkspaceSymbolSearchScope,
|
||||
/// What kind of symbol is being search for.
|
||||
pub search_kind: WorkspaceSymbolSearchKind,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(root_path: AbsPathBuf, caps: ClientCapabilities) -> Self {
|
||||
Config { caps, data: ConfigData::default(), discovered_projects: None, root_path }
|
||||
@ -687,6 +702,22 @@ impl Config {
|
||||
.contains(&MarkupKind::Markdown),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn workspace_symbol(&self) -> WorkspaceSymbolConfig {
|
||||
WorkspaceSymbolConfig {
|
||||
search_scope: match self.data.workspace_symbol_search_scope {
|
||||
WorskpaceSymbolSearchScopeDef::Workspace => WorkspaceSymbolSearchScope::Workspace,
|
||||
WorskpaceSymbolSearchScopeDef::WorkspaceAndDependencies => {
|
||||
WorkspaceSymbolSearchScope::WorkspaceAndDependencies
|
||||
}
|
||||
},
|
||||
search_kind: match self.data.workspace_symbol_search_kind {
|
||||
WorskpaceSymbolSearchKindDef::OnlyTypes => WorkspaceSymbolSearchKind::OnlyTypes,
|
||||
WorskpaceSymbolSearchKindDef::AllSymbols => WorkspaceSymbolSearchKind::AllSymbols,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn semantic_tokens_refresh(&self) -> bool {
|
||||
try_or!(self.caps.workspace.as_ref()?.semantic_tokens.as_ref()?.refresh_support?, false)
|
||||
}
|
||||
@ -733,6 +764,20 @@ enum ImportPrefixDef {
|
||||
ByCrate,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
enum WorskpaceSymbolSearchScopeDef {
|
||||
Workspace,
|
||||
WorkspaceAndDependencies,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
enum WorskpaceSymbolSearchKindDef {
|
||||
OnlyTypes,
|
||||
AllSymbols,
|
||||
}
|
||||
|
||||
macro_rules! _config_data {
|
||||
(struct $name:ident {
|
||||
$(
|
||||
@ -903,6 +948,22 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
|
||||
"type": "array",
|
||||
"items": { "type": ["string", "object"] },
|
||||
},
|
||||
"WorskpaceSymbolSearchScopeDef" => set! {
|
||||
"type": "string",
|
||||
"enum": ["workspace", "workspace_and_dependencies"],
|
||||
"enumDescriptions": [
|
||||
"Search in current workspace only",
|
||||
"Search in current workspace and dependencies"
|
||||
],
|
||||
},
|
||||
"WorskpaceSymbolSearchKindDef" => set! {
|
||||
"type": "string",
|
||||
"enum": ["only_types", "all_symbols"],
|
||||
"enumDescriptions": [
|
||||
"Search for types only",
|
||||
"Search for all symbols kinds"
|
||||
],
|
||||
},
|
||||
_ => panic!("{}: {}", ty, default),
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ use crate::{
|
||||
from_proto,
|
||||
global_state::{GlobalState, GlobalStateSnapshot},
|
||||
line_index::LineEndings,
|
||||
lsp_ext::{self, InlayHint, InlayHintsParams},
|
||||
lsp_ext::{self, InlayHint, InlayHintsParams, WorkspaceSymbolParams},
|
||||
lsp_utils::all_edits_are_disjoint,
|
||||
to_proto, LspError, Result,
|
||||
};
|
||||
@ -380,11 +380,12 @@ pub(crate) fn handle_document_symbol(
|
||||
|
||||
pub(crate) fn handle_workspace_symbol(
|
||||
snap: GlobalStateSnapshot,
|
||||
params: lsp_types::WorkspaceSymbolParams,
|
||||
params: WorkspaceSymbolParams,
|
||||
) -> Result<Option<Vec<SymbolInformation>>> {
|
||||
let _p = profile::span("handle_workspace_symbol");
|
||||
let all_symbols = params.query.contains('#');
|
||||
let libs = params.query.contains('*');
|
||||
|
||||
let (all_symbols, libs) = decide_search_scope_and_kind(¶ms, &snap);
|
||||
|
||||
let query = {
|
||||
let query: String = params.query.chars().filter(|&c| c != '#' && c != '*').collect();
|
||||
let mut q = Query::new(query);
|
||||
@ -406,6 +407,45 @@ pub(crate) fn handle_workspace_symbol(
|
||||
|
||||
return Ok(Some(res));
|
||||
|
||||
fn decide_search_scope_and_kind(
|
||||
params: &WorkspaceSymbolParams,
|
||||
snap: &GlobalStateSnapshot,
|
||||
) -> (bool, bool) {
|
||||
// Support old-style parsing of markers in the query.
|
||||
let mut all_symbols = params.query.contains('#');
|
||||
let mut libs = params.query.contains('*');
|
||||
|
||||
let config = snap.config.workspace_symbol();
|
||||
|
||||
// If no explicit marker was set, check request params. If that's also empty
|
||||
// use global config.
|
||||
if !all_symbols {
|
||||
let search_kind = if let Some(ref search_kind) = params.search_kind {
|
||||
search_kind
|
||||
} else {
|
||||
&config.search_kind
|
||||
};
|
||||
all_symbols = match search_kind {
|
||||
lsp_ext::WorkspaceSymbolSearchKind::OnlyTypes => false,
|
||||
lsp_ext::WorkspaceSymbolSearchKind::AllSymbols => true,
|
||||
}
|
||||
}
|
||||
|
||||
if !libs {
|
||||
let search_scope = if let Some(ref search_scope) = params.search_scope {
|
||||
search_scope
|
||||
} else {
|
||||
&config.search_scope
|
||||
};
|
||||
libs = match search_scope {
|
||||
lsp_ext::WorkspaceSymbolSearchScope::Workspace => false,
|
||||
lsp_ext::WorkspaceSymbolSearchScope::WorkspaceAndDependencies => true,
|
||||
}
|
||||
}
|
||||
|
||||
(all_symbols, libs)
|
||||
}
|
||||
|
||||
fn exec_query(snap: &GlobalStateSnapshot, query: Query) -> Result<Vec<SymbolInformation>> {
|
||||
let mut res = Vec::new();
|
||||
for nav in snap.analysis.symbol_search(query)? {
|
||||
|
@ -4,7 +4,8 @@ use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use lsp_types::request::Request;
|
||||
use lsp_types::{
|
||||
notification::Notification, CodeActionKind, Position, Range, TextDocumentIdentifier,
|
||||
notification::Notification, CodeActionKind, PartialResultParams, Position, Range,
|
||||
TextDocumentIdentifier, WorkDoneProgressParams,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -438,3 +439,42 @@ pub enum MoveItemDirection {
|
||||
Up,
|
||||
Down,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum WorkspaceSymbol {}
|
||||
|
||||
impl Request for WorkspaceSymbol {
|
||||
type Params = WorkspaceSymbolParams;
|
||||
type Result = Option<Vec<lsp_types::SymbolInformation>>;
|
||||
const METHOD: &'static str = "workspace/symbol";
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
|
||||
pub struct WorkspaceSymbolParams {
|
||||
#[serde(flatten)]
|
||||
pub partial_result_params: PartialResultParams,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub work_done_progress_params: WorkDoneProgressParams,
|
||||
|
||||
/// A non-empty query string
|
||||
pub query: String,
|
||||
|
||||
pub search_scope: Option<WorkspaceSymbolSearchScope>,
|
||||
|
||||
pub search_kind: Option<WorkspaceSymbolSearchKind>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum WorkspaceSymbolSearchScope {
|
||||
Workspace,
|
||||
WorkspaceAndDependencies,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum WorkspaceSymbolSearchKind {
|
||||
OnlyTypes,
|
||||
AllSymbols,
|
||||
}
|
||||
|
@ -525,9 +525,9 @@ impl GlobalState {
|
||||
.on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
|
||||
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
|
||||
.on::<lsp_ext::MoveItem>(handlers::handle_move_item)
|
||||
.on::<lsp_ext::WorkspaceSymbol>(handlers::handle_workspace_symbol)
|
||||
.on::<lsp_types::request::OnTypeFormatting>(handlers::handle_on_type_formatting)
|
||||
.on::<lsp_types::request::DocumentSymbolRequest>(handlers::handle_document_symbol)
|
||||
.on::<lsp_types::request::WorkspaceSymbol>(handlers::handle_workspace_symbol)
|
||||
.on::<lsp_types::request::GotoDefinition>(handlers::handle_goto_definition)
|
||||
.on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation)
|
||||
.on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!---
|
||||
lsp_ext.rs hash: 6e57fc1b345b00e9
|
||||
lsp_ext.rs hash: 10a8988e6893e6b2
|
||||
|
||||
If you need to change the above hash to make the test pass, please check if you
|
||||
need to adjust this doc as well and ping this issue:
|
||||
@ -650,3 +650,33 @@ export const enum Direction {
|
||||
Down = "Down"
|
||||
}
|
||||
```
|
||||
|
||||
## Lookup workspace symbol search scope and kind
|
||||
|
||||
**Issue:** https://github.com/rust-analyzer/rust-analyzer/pull/7698
|
||||
|
||||
This request is sent from client to server to search for workspace symbols filtered by an
|
||||
optional search scope and / or an optional symbol kind.
|
||||
|
||||
**Method:** `workspace/symbol`
|
||||
|
||||
**Request:** `WorkspaceSymbolParams`
|
||||
|
||||
**Response:** `SymbolInformation[] | null`
|
||||
|
||||
```typescript
|
||||
interface lsp_ext.WorkspaceSymbolParams extends WorkspaceSymbolParams {
|
||||
searchScope?: WorkspaceSymbolSearchScope;
|
||||
searchKind?: WorkspaceSymbolSearchKind;
|
||||
}
|
||||
|
||||
const enum WorkspaceSymbolSearchScope {
|
||||
Workspace = "Workspace",
|
||||
WorkspaceAndDependencies = "WorkspaceAndDependencies"
|
||||
}
|
||||
|
||||
const enum WorkspaceSymbolSearchKind {
|
||||
OnlyTypes = "OnlyTypes",
|
||||
AllSymbols = "AllSymbols"
|
||||
}
|
||||
```
|
||||
|
@ -341,3 +341,13 @@ Additional arguments to `rustfmt`.
|
||||
Advanced option, fully override the command rust-analyzer uses for
|
||||
formatting.
|
||||
--
|
||||
[[rust-analyzer.workspace.symbol.search.scope]]rust-analyzer.workspace.symbol.search.scope (default: `"workspace"`)::
|
||||
+
|
||||
--
|
||||
Workspace symbol search scope.
|
||||
--
|
||||
[[rust-analyzer.workspace.symbol.search.kind]]rust-analyzer.workspace.symbol.search.kind (default: `"only_types"`)::
|
||||
+
|
||||
--
|
||||
Workspace symbol search kind.
|
||||
--
|
||||
|
@ -783,6 +783,32 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"rust-analyzer.workspace.symbol.search.scope": {
|
||||
"markdownDescription": "Workspace symbol search scope.",
|
||||
"default": "workspace",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"workspace",
|
||||
"workspace_and_dependencies"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"Search in current workspace only",
|
||||
"Search in current workspace and dependencies"
|
||||
]
|
||||
},
|
||||
"rust-analyzer.workspace.symbol.search.kind": {
|
||||
"markdownDescription": "Workspace symbol search kind.",
|
||||
"default": "only_types",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"only_types",
|
||||
"all_symbols"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"Search for types only",
|
||||
"Search for all symbols kinds"
|
||||
]
|
||||
},
|
||||
"$generated-end": false
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user