diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index 1a91d80afa..c7e8317e51 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -26,7 +26,7 @@ use language::{ tree_sitter_rust, tree_sitter_typescript, Diagnostic, DiagnosticEntry, FakeLspAdapter, Language, LanguageConfig, LanguageMatcher, LineEnding, OffsetRangeExt, Point, Rope, }; -use lsp::LanguageServerId; +use lsp::{LanguageServerId, OneOf}; use parking_lot::Mutex; use pretty_assertions::assert_eq; use project::{ @@ -5399,9 +5399,16 @@ async fn test_project_symbols( let active_call_a = cx_a.read(ActiveCall::global); client_a.language_registry().add(rust_lang()); - let mut fake_language_servers = client_a - .language_registry() - .register_fake_lsp("Rust", Default::default()); + let mut fake_language_servers = client_a.language_registry().register_fake_lsp( + "Rust", + FakeLspAdapter { + capabilities: lsp::ServerCapabilities { + workspace_symbol_provider: Some(OneOf::Left(true)), + ..Default::default() + }, + ..Default::default() + }, + ); client_a .fs() diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 69cdf1fc7c..9aebeaa948 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -1483,6 +1483,7 @@ impl LanguageServer { document_formatting_provider: Some(OneOf::Left(true)), document_range_formatting_provider: Some(OneOf::Left(true)), definition_provider: Some(OneOf::Left(true)), + workspace_symbol_provider: Some(OneOf::Left(true)), implementation_provider: Some(ImplementationProviderCapability::Simple(true)), type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)), ..Default::default() diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 9f466b3cae..32b4c05841 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -5791,48 +5791,57 @@ impl LspStore { _ => continue 'next_server, }; + let supports_workspace_symbol_request = + match server.capabilities().workspace_symbol_provider { + Some(OneOf::Left(supported)) => supported, + Some(OneOf::Right(_)) => true, + None => false, + }; + if !supports_workspace_symbol_request { + continue 'next_server; + } let worktree_abs_path = worktree.abs_path().clone(); let worktree_handle = worktree_handle.clone(); let server_id = server.server_id(); requests.push( - server - .request::( - lsp::WorkspaceSymbolParams { - query: query.to_string(), - ..Default::default() - }, - ) - .log_err() - .map(move |response| { - let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response { - lsp::WorkspaceSymbolResponse::Flat(flat_responses) => { - flat_responses.into_iter().map(|lsp_symbol| { - (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location) - }).collect::>() - } - lsp::WorkspaceSymbolResponse::Nested(nested_responses) => { - nested_responses.into_iter().filter_map(|lsp_symbol| { - let location = match lsp_symbol.location { - OneOf::Left(location) => location, - OneOf::Right(_) => { - log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport"); - return None - } - }; - Some((lsp_symbol.name, lsp_symbol.kind, location)) - }).collect::>() - } - }).unwrap_or_default(); - - WorkspaceSymbolsResult { - server_id, - lsp_adapter, - worktree: worktree_handle.downgrade(), - worktree_abs_path, - lsp_symbols, + server + .request::( + lsp::WorkspaceSymbolParams { + query: query.to_string(), + ..Default::default() + }, + ) + .log_err() + .map(move |response| { + let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response { + lsp::WorkspaceSymbolResponse::Flat(flat_responses) => { + flat_responses.into_iter().map(|lsp_symbol| { + (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location) + }).collect::>() } - }), - ); + lsp::WorkspaceSymbolResponse::Nested(nested_responses) => { + nested_responses.into_iter().filter_map(|lsp_symbol| { + let location = match lsp_symbol.location { + OneOf::Left(location) => location, + OneOf::Right(_) => { + log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport"); + return None + } + }; + Some((lsp_symbol.name, lsp_symbol.kind, location)) + }).collect::>() + } + }).unwrap_or_default(); + + WorkspaceSymbolsResult { + server_id, + lsp_adapter, + worktree: worktree_handle.downgrade(), + worktree_abs_path, + lsp_symbols, + } + }), + ); } requested_servers.append(&mut servers_to_query); } diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index fe0761e7a4..0f7ebf3a2a 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -270,6 +270,7 @@ mod tests { use futures::StreamExt; use gpui::{SemanticVersion, TestAppContext, VisualContext}; use language::{FakeLspAdapter, Language, LanguageConfig, LanguageMatcher}; + use lsp::OneOf; use project::FakeFs; use serde_json::json; use settings::SettingsStore; @@ -298,8 +299,16 @@ mod tests { }, None, ))); - let mut fake_servers = - language_registry.register_fake_lsp("Rust", FakeLspAdapter::default()); + let mut fake_servers = language_registry.register_fake_lsp( + "Rust", + FakeLspAdapter { + capabilities: lsp::ServerCapabilities { + workspace_symbol_provider: Some(OneOf::Left(true)), + ..Default::default() + }, + ..Default::default() + }, + ); let _buffer = project .update(cx, |project, cx| {