diff --git a/crates/collab/src/tests/integration_tests.rs b/crates/collab/src/tests/integration_tests.rs index d78db041f2..d1099a327a 100644 --- a/crates/collab/src/tests/integration_tests.rs +++ b/crates/collab/src/tests/integration_tests.rs @@ -4821,7 +4821,7 @@ async fn test_definition( ); let definitions_1 = project_b - .update(cx_b, |p, cx| p.definition(&buffer_b, 23, cx)) + .update(cx_b, |p, cx| p.definitions(&buffer_b, 23, cx)) .await .unwrap(); cx_b.read(|cx| { @@ -4852,7 +4852,7 @@ async fn test_definition( ); let definitions_2 = project_b - .update(cx_b, |p, cx| p.definition(&buffer_b, 33, cx)) + .update(cx_b, |p, cx| p.definitions(&buffer_b, 33, cx)) .await .unwrap(); cx_b.read(|cx| { @@ -4889,7 +4889,7 @@ async fn test_definition( ); let type_definitions = project_b - .update(cx_b, |p, cx| p.type_definition(&buffer_b, 7, cx)) + .update(cx_b, |p, cx| p.type_definitions(&buffer_b, 7, cx)) .await .unwrap(); cx_b.read(|cx| { @@ -5057,7 +5057,7 @@ async fn test_references( lsp_response_tx .unbounded_send(Err(anyhow!("can't find references"))) .unwrap(); - references.await.unwrap_err(); + assert_eq!(references.await.unwrap(), []); // User is informed that the request is no longer pending. executor.run_until_parked(); @@ -5641,7 +5641,7 @@ async fn test_open_buffer_while_getting_definition_pointing_to_it( let definitions; let buffer_b2; if rng.r#gen() { - definitions = project_b.update(cx_b, |p, cx| p.definition(&buffer_b1, 23, cx)); + definitions = project_b.update(cx_b, |p, cx| p.definitions(&buffer_b1, 23, cx)); (buffer_b2, _) = project_b .update(cx_b, |p, cx| { p.open_buffer_with_lsp((worktree_id, "b.rs"), cx) @@ -5655,7 +5655,7 @@ async fn test_open_buffer_while_getting_definition_pointing_to_it( }) .await .unwrap(); - definitions = project_b.update(cx_b, |p, cx| p.definition(&buffer_b1, 23, cx)); + definitions = project_b.update(cx_b, |p, cx| p.definitions(&buffer_b1, 23, cx)); } let definitions = definitions.await.unwrap(); diff --git a/crates/collab/src/tests/random_project_collaboration_tests.rs b/crates/collab/src/tests/random_project_collaboration_tests.rs index 6dafdc458e..4d94d041b9 100644 --- a/crates/collab/src/tests/random_project_collaboration_tests.rs +++ b/crates/collab/src/tests/random_project_collaboration_tests.rs @@ -838,7 +838,7 @@ impl RandomizedTest for ProjectCollaborationTest { .map(|_| Ok(())) .boxed(), LspRequestKind::Definition => project - .definition(&buffer, offset, cx) + .definitions(&buffer, offset, cx) .map_ok(|_| ()) .boxed(), LspRequestKind::Highlights => project diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index aed3988af7..69b9158c31 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -21944,10 +21944,10 @@ impl SemanticsProvider for Entity { cx: &mut App, ) -> Option>>> { Some(self.update(cx, |project, cx| match kind { - GotoDefinitionKind::Symbol => project.definition(&buffer, position, cx), - GotoDefinitionKind::Declaration => project.declaration(&buffer, position, cx), - GotoDefinitionKind::Type => project.type_definition(&buffer, position, cx), - GotoDefinitionKind::Implementation => project.implementation(&buffer, position, cx), + GotoDefinitionKind::Symbol => project.definitions(&buffer, position, cx), + GotoDefinitionKind::Declaration => project.declarations(&buffer, position, cx), + GotoDefinitionKind::Type => project.type_definitions(&buffer, position, cx), + GotoDefinitionKind::Implementation => project.implementations(&buffer, position, cx), })) } diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index 70d8518c48..8ed3716436 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -171,27 +171,27 @@ pub(crate) struct PerformRename { pub push_to_history: bool, } -#[derive(Debug)] -pub struct GetDefinition { +#[derive(Debug, Clone, Copy)] +pub struct GetDefinitions { pub position: PointUtf16, } -#[derive(Debug)] -pub(crate) struct GetDeclaration { +#[derive(Debug, Clone, Copy)] +pub(crate) struct GetDeclarations { pub position: PointUtf16, } -#[derive(Debug)] -pub(crate) struct GetTypeDefinition { +#[derive(Debug, Clone, Copy)] +pub(crate) struct GetTypeDefinitions { pub position: PointUtf16, } -#[derive(Debug)] -pub(crate) struct GetImplementation { +#[derive(Debug, Clone, Copy)] +pub(crate) struct GetImplementations { pub position: PointUtf16, } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub(crate) struct GetReferences { pub position: PointUtf16, } @@ -588,7 +588,7 @@ impl LspCommand for PerformRename { } #[async_trait(?Send)] -impl LspCommand for GetDefinition { +impl LspCommand for GetDefinitions { type Response = Vec; type LspRequest = lsp::request::GotoDefinition; type ProtoRequest = proto::GetDefinition; @@ -690,7 +690,7 @@ impl LspCommand for GetDefinition { } #[async_trait(?Send)] -impl LspCommand for GetDeclaration { +impl LspCommand for GetDeclarations { type Response = Vec; type LspRequest = lsp::request::GotoDeclaration; type ProtoRequest = proto::GetDeclaration; @@ -793,7 +793,7 @@ impl LspCommand for GetDeclaration { } #[async_trait(?Send)] -impl LspCommand for GetImplementation { +impl LspCommand for GetImplementations { type Response = Vec; type LspRequest = lsp::request::GotoImplementation; type ProtoRequest = proto::GetImplementation; @@ -895,7 +895,7 @@ impl LspCommand for GetImplementation { } #[async_trait(?Send)] -impl LspCommand for GetTypeDefinition { +impl LspCommand for GetTypeDefinitions { type Response = Vec; type LspRequest = lsp::request::GotoTypeDefinition; type ProtoRequest = proto::GetTypeDefinition; diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 1047d7a5f0..f2b04b9b21 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -4,8 +4,9 @@ pub mod rust_analyzer_ext; use crate::{ CodeAction, ColorPresentation, Completion, CompletionResponse, CompletionSource, - CoreCompletion, DocumentColor, Hover, InlayHint, LspAction, LspPullDiagnostics, ProjectItem, - ProjectPath, ProjectTransaction, PulledDiagnostics, ResolveState, Symbol, ToolchainStore, + CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction, LspPullDiagnostics, + ProjectItem, ProjectPath, ProjectTransaction, PulledDiagnostics, ResolveState, Symbol, + ToolchainStore, buffer_store::{BufferStore, BufferStoreEvent}, environment::ProjectEnvironment, lsp_command::{self, *}, @@ -3660,12 +3661,8 @@ impl LspStore { client.add_entity_request_handler(Self::handle_lsp_command::); client.add_entity_request_handler(Self::handle_lsp_command::); client.add_entity_request_handler(Self::handle_lsp_command::); - client.add_entity_request_handler(Self::handle_lsp_command::); - client.add_entity_request_handler(Self::handle_lsp_command::); - client.add_entity_request_handler(Self::handle_lsp_command::); client.add_entity_request_handler(Self::handle_lsp_command::); client.add_entity_request_handler(Self::handle_lsp_command::); - client.add_entity_request_handler(Self::handle_lsp_command::); client.add_entity_request_handler(Self::handle_lsp_command::); client.add_entity_request_handler(Self::handle_lsp_command::); client.add_entity_request_handler(Self::handle_lsp_command::); @@ -5257,6 +5254,371 @@ impl LspStore { }) } + pub fn definitions( + &mut self, + buffer_handle: &Entity, + position: PointUtf16, + cx: &mut Context, + ) -> Task>> { + if let Some((upstream_client, project_id)) = self.upstream_client() { + let request_task = upstream_client.request(proto::MultiLspQuery { + buffer_id: buffer_handle.read(cx).remote_id().into(), + version: serialize_version(&buffer_handle.read(cx).version()), + project_id, + strategy: Some(proto::multi_lsp_query::Strategy::All( + proto::AllLanguageServers {}, + )), + request: Some(proto::multi_lsp_query::Request::GetDefinition( + GetDefinitions { position }.to_proto(project_id, buffer_handle.read(cx)), + )), + }); + let buffer = buffer_handle.clone(); + cx.spawn(async move |weak_project, cx| { + let Some(project) = weak_project.upgrade() else { + return Ok(Vec::new()); + }; + let responses = request_task.await?.responses; + let actions = join_all( + responses + .into_iter() + .filter_map(|lsp_response| match lsp_response.response? { + proto::lsp_response::Response::GetDefinitionResponse(response) => { + Some(response) + } + unexpected => { + debug_panic!("Unexpected response: {unexpected:?}"); + None + } + }) + .map(|definitions_response| { + GetDefinitions { position }.response_from_proto( + definitions_response, + project.clone(), + buffer.clone(), + cx.clone(), + ) + }), + ) + .await; + + Ok(actions + .into_iter() + .collect::>>>()? + .into_iter() + .flatten() + .dedup() + .collect()) + }) + } else { + let definitions_task = self.request_multiple_lsp_locally( + buffer_handle, + Some(position), + GetDefinitions { position }, + cx, + ); + cx.spawn(async move |_, _| { + Ok(definitions_task + .await + .into_iter() + .flat_map(|(_, definitions)| definitions) + .dedup() + .collect()) + }) + } + } + + pub fn declarations( + &mut self, + buffer_handle: &Entity, + position: PointUtf16, + cx: &mut Context, + ) -> Task>> { + if let Some((upstream_client, project_id)) = self.upstream_client() { + let request_task = upstream_client.request(proto::MultiLspQuery { + buffer_id: buffer_handle.read(cx).remote_id().into(), + version: serialize_version(&buffer_handle.read(cx).version()), + project_id, + strategy: Some(proto::multi_lsp_query::Strategy::All( + proto::AllLanguageServers {}, + )), + request: Some(proto::multi_lsp_query::Request::GetDeclaration( + GetDeclarations { position }.to_proto(project_id, buffer_handle.read(cx)), + )), + }); + let buffer = buffer_handle.clone(); + cx.spawn(async move |weak_project, cx| { + let Some(project) = weak_project.upgrade() else { + return Ok(Vec::new()); + }; + let responses = request_task.await?.responses; + let actions = join_all( + responses + .into_iter() + .filter_map(|lsp_response| match lsp_response.response? { + proto::lsp_response::Response::GetDeclarationResponse(response) => { + Some(response) + } + unexpected => { + debug_panic!("Unexpected response: {unexpected:?}"); + None + } + }) + .map(|declarations_response| { + GetDeclarations { position }.response_from_proto( + declarations_response, + project.clone(), + buffer.clone(), + cx.clone(), + ) + }), + ) + .await; + + Ok(actions + .into_iter() + .collect::>>>()? + .into_iter() + .flatten() + .dedup() + .collect()) + }) + } else { + let declarations_task = self.request_multiple_lsp_locally( + buffer_handle, + Some(position), + GetDeclarations { position }, + cx, + ); + cx.spawn(async move |_, _| { + Ok(declarations_task + .await + .into_iter() + .flat_map(|(_, declarations)| declarations) + .dedup() + .collect()) + }) + } + } + + pub fn type_definitions( + &mut self, + buffer_handle: &Entity, + position: PointUtf16, + cx: &mut Context, + ) -> Task>> { + if let Some((upstream_client, project_id)) = self.upstream_client() { + let request_task = upstream_client.request(proto::MultiLspQuery { + buffer_id: buffer_handle.read(cx).remote_id().into(), + version: serialize_version(&buffer_handle.read(cx).version()), + project_id, + strategy: Some(proto::multi_lsp_query::Strategy::All( + proto::AllLanguageServers {}, + )), + request: Some(proto::multi_lsp_query::Request::GetTypeDefinition( + GetTypeDefinitions { position }.to_proto(project_id, buffer_handle.read(cx)), + )), + }); + let buffer = buffer_handle.clone(); + cx.spawn(async move |weak_project, cx| { + let Some(project) = weak_project.upgrade() else { + return Ok(Vec::new()); + }; + let responses = request_task.await?.responses; + let actions = join_all( + responses + .into_iter() + .filter_map(|lsp_response| match lsp_response.response? { + proto::lsp_response::Response::GetTypeDefinitionResponse(response) => { + Some(response) + } + unexpected => { + debug_panic!("Unexpected response: {unexpected:?}"); + None + } + }) + .map(|type_definitions_response| { + GetTypeDefinitions { position }.response_from_proto( + type_definitions_response, + project.clone(), + buffer.clone(), + cx.clone(), + ) + }), + ) + .await; + + Ok(actions + .into_iter() + .collect::>>>()? + .into_iter() + .flatten() + .dedup() + .collect()) + }) + } else { + let type_definitions_task = self.request_multiple_lsp_locally( + buffer_handle, + Some(position), + GetTypeDefinitions { position }, + cx, + ); + cx.spawn(async move |_, _| { + Ok(type_definitions_task + .await + .into_iter() + .flat_map(|(_, type_definitions)| type_definitions) + .dedup() + .collect()) + }) + } + } + + pub fn implementations( + &mut self, + buffer_handle: &Entity, + position: PointUtf16, + cx: &mut Context, + ) -> Task>> { + if let Some((upstream_client, project_id)) = self.upstream_client() { + let request_task = upstream_client.request(proto::MultiLspQuery { + buffer_id: buffer_handle.read(cx).remote_id().into(), + version: serialize_version(&buffer_handle.read(cx).version()), + project_id, + strategy: Some(proto::multi_lsp_query::Strategy::All( + proto::AllLanguageServers {}, + )), + request: Some(proto::multi_lsp_query::Request::GetImplementation( + GetImplementations { position }.to_proto(project_id, buffer_handle.read(cx)), + )), + }); + let buffer = buffer_handle.clone(); + cx.spawn(async move |weak_project, cx| { + let Some(project) = weak_project.upgrade() else { + return Ok(Vec::new()); + }; + let responses = request_task.await?.responses; + let actions = join_all( + responses + .into_iter() + .filter_map(|lsp_response| match lsp_response.response? { + proto::lsp_response::Response::GetImplementationResponse(response) => { + Some(response) + } + unexpected => { + debug_panic!("Unexpected response: {unexpected:?}"); + None + } + }) + .map(|implementations_response| { + GetImplementations { position }.response_from_proto( + implementations_response, + project.clone(), + buffer.clone(), + cx.clone(), + ) + }), + ) + .await; + + Ok(actions + .into_iter() + .collect::>>>()? + .into_iter() + .flatten() + .dedup() + .collect()) + }) + } else { + let implementations_task = self.request_multiple_lsp_locally( + buffer_handle, + Some(position), + GetImplementations { position }, + cx, + ); + cx.spawn(async move |_, _| { + Ok(implementations_task + .await + .into_iter() + .flat_map(|(_, implementations)| implementations) + .dedup() + .collect()) + }) + } + } + + pub fn references( + &mut self, + buffer_handle: &Entity, + position: PointUtf16, + cx: &mut Context, + ) -> Task>> { + if let Some((upstream_client, project_id)) = self.upstream_client() { + let request_task = upstream_client.request(proto::MultiLspQuery { + buffer_id: buffer_handle.read(cx).remote_id().into(), + version: serialize_version(&buffer_handle.read(cx).version()), + project_id, + strategy: Some(proto::multi_lsp_query::Strategy::All( + proto::AllLanguageServers {}, + )), + request: Some(proto::multi_lsp_query::Request::GetReferences( + GetReferences { position }.to_proto(project_id, buffer_handle.read(cx)), + )), + }); + let buffer = buffer_handle.clone(); + cx.spawn(async move |weak_project, cx| { + let Some(project) = weak_project.upgrade() else { + return Ok(Vec::new()); + }; + let responses = request_task.await?.responses; + let actions = join_all( + responses + .into_iter() + .filter_map(|lsp_response| match lsp_response.response? { + proto::lsp_response::Response::GetReferencesResponse(response) => { + Some(response) + } + unexpected => { + debug_panic!("Unexpected response: {unexpected:?}"); + None + } + }) + .map(|references_response| { + GetReferences { position }.response_from_proto( + references_response, + project.clone(), + buffer.clone(), + cx.clone(), + ) + }), + ) + .await; + + Ok(actions + .into_iter() + .collect::>>>()? + .into_iter() + .flatten() + .dedup() + .collect()) + }) + } else { + let references_task = self.request_multiple_lsp_locally( + buffer_handle, + Some(position), + GetReferences { position }, + cx, + ); + cx.spawn(async move |_, _| { + Ok(references_task + .await + .into_iter() + .flat_map(|(_, references)| references) + .dedup() + .collect()) + }) + } + } + pub fn code_actions( &mut self, buffer_handle: &Entity, @@ -7886,6 +8248,200 @@ impl LspStore { .collect(), }) } + Some(proto::multi_lsp_query::Request::GetDefinition(message)) => { + let get_definitions = GetDefinitions::from_proto( + message, + lsp_store.clone(), + buffer.clone(), + cx.clone(), + ) + .await?; + + let definitions = lsp_store + .update(&mut cx, |project, cx| { + project.request_multiple_lsp_locally( + &buffer, + Some(get_definitions.position), + get_definitions, + cx, + ) + })? + .await + .into_iter(); + + lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse { + responses: definitions + .map(|(server_id, definitions)| proto::LspResponse { + server_id: server_id.to_proto(), + response: Some(proto::lsp_response::Response::GetDefinitionResponse( + GetDefinitions::response_to_proto( + definitions, + project, + sender_id, + &buffer_version, + cx, + ), + )), + }) + .collect(), + }) + } + Some(proto::multi_lsp_query::Request::GetDeclaration(message)) => { + let get_declarations = GetDeclarations::from_proto( + message, + lsp_store.clone(), + buffer.clone(), + cx.clone(), + ) + .await?; + + let declarations = lsp_store + .update(&mut cx, |project, cx| { + project.request_multiple_lsp_locally( + &buffer, + Some(get_declarations.position), + get_declarations, + cx, + ) + })? + .await + .into_iter(); + + lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse { + responses: declarations + .map(|(server_id, declarations)| proto::LspResponse { + server_id: server_id.to_proto(), + response: Some(proto::lsp_response::Response::GetDeclarationResponse( + GetDeclarations::response_to_proto( + declarations, + project, + sender_id, + &buffer_version, + cx, + ), + )), + }) + .collect(), + }) + } + Some(proto::multi_lsp_query::Request::GetTypeDefinition(message)) => { + let get_type_definitions = GetTypeDefinitions::from_proto( + message, + lsp_store.clone(), + buffer.clone(), + cx.clone(), + ) + .await?; + + let type_definitions = lsp_store + .update(&mut cx, |project, cx| { + project.request_multiple_lsp_locally( + &buffer, + Some(get_type_definitions.position), + get_type_definitions, + cx, + ) + })? + .await + .into_iter(); + + lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse { + responses: type_definitions + .map(|(server_id, type_definitions)| proto::LspResponse { + server_id: server_id.to_proto(), + response: Some( + proto::lsp_response::Response::GetTypeDefinitionResponse( + GetTypeDefinitions::response_to_proto( + type_definitions, + project, + sender_id, + &buffer_version, + cx, + ), + ), + ), + }) + .collect(), + }) + } + Some(proto::multi_lsp_query::Request::GetImplementation(message)) => { + let get_implementations = GetImplementations::from_proto( + message, + lsp_store.clone(), + buffer.clone(), + cx.clone(), + ) + .await?; + + let implementations = lsp_store + .update(&mut cx, |project, cx| { + project.request_multiple_lsp_locally( + &buffer, + Some(get_implementations.position), + get_implementations, + cx, + ) + })? + .await + .into_iter(); + + lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse { + responses: implementations + .map(|(server_id, implementations)| proto::LspResponse { + server_id: server_id.to_proto(), + response: Some( + proto::lsp_response::Response::GetImplementationResponse( + GetImplementations::response_to_proto( + implementations, + project, + sender_id, + &buffer_version, + cx, + ), + ), + ), + }) + .collect(), + }) + } + Some(proto::multi_lsp_query::Request::GetReferences(message)) => { + let get_references = GetReferences::from_proto( + message, + lsp_store.clone(), + buffer.clone(), + cx.clone(), + ) + .await?; + + let references = lsp_store + .update(&mut cx, |project, cx| { + project.request_multiple_lsp_locally( + &buffer, + Some(get_references.position), + get_references, + cx, + ) + })? + .await + .into_iter(); + + lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse { + responses: references + .map(|(server_id, references)| proto::LspResponse { + server_id: server_id.to_proto(), + response: Some(proto::lsp_response::Response::GetReferencesResponse( + GetReferences::response_to_proto( + references, + project, + sender_id, + &buffer_version, + cx, + ), + )), + }) + .collect(), + }) + } None => anyhow::bail!("empty multi lsp query request"), } } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index ee144b8b36..8a41a75d68 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -696,7 +696,7 @@ pub struct MarkupContent { pub value: String, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct LocationLink { pub origin: Option, pub target: Location, @@ -3342,91 +3342,52 @@ impl Project { }) } - #[inline(never)] - fn definition_impl( - &mut self, - buffer: &Entity, - position: PointUtf16, - cx: &mut Context, - ) -> Task>> { - self.request_lsp( - buffer.clone(), - LanguageServerToQuery::FirstCapable, - GetDefinition { position }, - cx, - ) - } - pub fn definition( + pub fn definitions( &mut self, buffer: &Entity, position: T, cx: &mut Context, ) -> Task>> { let position = position.to_point_utf16(buffer.read(cx)); - self.definition_impl(buffer, position, cx) + self.lsp_store.update(cx, |lsp_store, cx| { + lsp_store.definitions(buffer, position, cx) + }) } - fn declaration_impl( - &mut self, - buffer: &Entity, - position: PointUtf16, - cx: &mut Context, - ) -> Task>> { - self.request_lsp( - buffer.clone(), - LanguageServerToQuery::FirstCapable, - GetDeclaration { position }, - cx, - ) - } - - pub fn declaration( + pub fn declarations( &mut self, buffer: &Entity, position: T, cx: &mut Context, ) -> Task>> { let position = position.to_point_utf16(buffer.read(cx)); - self.declaration_impl(buffer, position, cx) + self.lsp_store.update(cx, |lsp_store, cx| { + lsp_store.declarations(buffer, position, cx) + }) } - fn type_definition_impl( - &mut self, - buffer: &Entity, - position: PointUtf16, - cx: &mut Context, - ) -> Task>> { - self.request_lsp( - buffer.clone(), - LanguageServerToQuery::FirstCapable, - GetTypeDefinition { position }, - cx, - ) - } - - pub fn type_definition( + pub fn type_definitions( &mut self, buffer: &Entity, position: T, cx: &mut Context, ) -> Task>> { let position = position.to_point_utf16(buffer.read(cx)); - self.type_definition_impl(buffer, position, cx) + self.lsp_store.update(cx, |lsp_store, cx| { + lsp_store.type_definitions(buffer, position, cx) + }) } - pub fn implementation( + pub fn implementations( &mut self, buffer: &Entity, position: T, cx: &mut Context, ) -> Task>> { let position = position.to_point_utf16(buffer.read(cx)); - self.request_lsp( - buffer.clone(), - LanguageServerToQuery::FirstCapable, - GetImplementation { position }, - cx, - ) + self.lsp_store.update(cx, |lsp_store, cx| { + lsp_store.implementations(buffer, position, cx) + }) } pub fn references( @@ -3436,12 +3397,9 @@ impl Project { cx: &mut Context, ) -> Task>> { let position = position.to_point_utf16(buffer.read(cx)); - self.request_lsp( - buffer.clone(), - LanguageServerToQuery::FirstCapable, - GetReferences { position }, - cx, - ) + self.lsp_store.update(cx, |lsp_store, cx| { + lsp_store.references(buffer, position, cx) + }) } fn document_highlights_impl( diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 3e9a2c3273..b5eb62c4eb 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -2993,7 +2993,7 @@ async fn test_definition(cx: &mut gpui::TestAppContext) { ))) }); let mut definitions = project - .update(cx, |project, cx| project.definition(&buffer, 22, cx)) + .update(cx, |project, cx| project.definitions(&buffer, 22, cx)) .await .unwrap(); diff --git a/crates/proto/proto/lsp.proto b/crates/proto/proto/lsp.proto index 0743b94e55..c0eadd5e69 100644 --- a/crates/proto/proto/lsp.proto +++ b/crates/proto/proto/lsp.proto @@ -757,6 +757,11 @@ message MultiLspQuery { GetCodeLens get_code_lens = 8; GetDocumentDiagnostics get_document_diagnostics = 9; GetDocumentColor get_document_color = 10; + GetDefinition get_definition = 11; + GetDeclaration get_declaration = 12; + GetTypeDefinition get_type_definition = 13; + GetImplementation get_implementation = 14; + GetReferences get_references = 15; } } @@ -795,6 +800,11 @@ message LspResponse { GetCodeLensResponse get_code_lens_response = 4; GetDocumentDiagnosticsResponse get_document_diagnostics_response = 5; GetDocumentColorResponse get_document_color_response = 6; + GetDefinitionResponse get_definition_response = 8; + GetDeclarationResponse get_declaration_response = 9; + GetTypeDefinitionResponse get_type_definition_response = 10; + GetImplementationResponse get_implementation_response = 11; + GetReferencesResponse get_references_response = 12; } uint64 server_id = 7; }