diff --git a/crates/editor/src/link_go_to_definition.rs b/crates/editor/src/link_go_to_definition.rs index a52647fb55..f3ee76dc96 100644 --- a/crates/editor/src/link_go_to_definition.rs +++ b/crates/editor/src/link_go_to_definition.rs @@ -312,6 +312,7 @@ mod tests { let mut cx = EditorLspTestContext::new_rust( lsp::ServerCapabilities { hover_provider: Some(lsp::HoverProviderCapability::Simple(true)), + type_definition_provider: Some(lsp::TypeDefinitionProviderCapability::Simple(true)), ..Default::default() }, cx, diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 39e65c6321..96d4382075 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -792,6 +792,8 @@ impl LanguageServer { code_action_provider: Some(CodeActionProviderCapability::Simple(true)), document_formatting_provider: Some(OneOf::Left(true)), document_range_formatting_provider: Some(OneOf::Left(true)), + definition_provider: Some(OneOf::Left(true)), + type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)), ..Default::default() } } diff --git a/crates/lsp_log/src/lsp_log.rs b/crates/lsp_log/src/lsp_log.rs index 1071ed435a..5808b4da2e 100644 --- a/crates/lsp_log/src/lsp_log.rs +++ b/crates/lsp_log/src/lsp_log.rs @@ -20,6 +20,7 @@ use std::{borrow::Cow, sync::Arc}; use theme::{ui, Theme}; use workspace::{ item::{Item, ItemHandle}, + searchable::{SearchableItem, SearchableItemHandle}, ToolbarItemLocation, ToolbarItemView, Workspace, WorkspaceCreated, }; @@ -51,7 +52,7 @@ pub struct LspLogView { log_store: ModelHandle, current_server_id: Option, is_showing_rpc_trace: bool, - editor: Option>, + editor: ViewHandle, project: ModelHandle, } @@ -329,10 +330,11 @@ impl LspLogView { .projects .get(&project.downgrade()) .and_then(|project| project.servers.keys().copied().next()); + let buffer = cx.add_model(|cx| Buffer::new(0, "", cx)); let mut this = Self { + editor: Self::editor_for_buffer(project.clone(), buffer, cx), project, log_store, - editor: None, current_server_id: None, is_showing_rpc_trace: false, }; @@ -342,6 +344,22 @@ impl LspLogView { this } + fn editor_for_buffer( + project: ModelHandle, + buffer: ModelHandle, + cx: &mut ViewContext, + ) -> ViewHandle { + let editor = cx.add_view(|cx| { + let mut editor = Editor::for_buffer(buffer, Some(project), cx); + editor.set_read_only(true); + editor.move_to_end(&Default::default(), cx); + editor + }); + cx.subscribe(&editor, |_, _, event, cx| cx.emit(event.clone())) + .detach(); + editor + } + fn menu_items<'a>(&'a self, cx: &'a AppContext) -> Option> { let log_store = self.log_store.read(cx); let state = log_store.projects.get(&self.project.downgrade())?; @@ -377,12 +395,7 @@ impl LspLogView { if let Some(buffer) = buffer { self.current_server_id = Some(server_id); self.is_showing_rpc_trace = false; - self.editor = Some(cx.add_view(|cx| { - let mut editor = Editor::for_buffer(buffer, Some(self.project.clone()), cx); - editor.set_read_only(true); - editor.move_to_end(&Default::default(), cx); - editor - })); + self.editor = Self::editor_for_buffer(self.project.clone(), buffer, cx); cx.notify(); } } @@ -398,12 +411,7 @@ impl LspLogView { if let Some(buffer) = buffer { self.current_server_id = Some(server_id); self.is_showing_rpc_trace = true; - self.editor = Some(cx.add_view(|cx| { - let mut editor = Editor::for_buffer(buffer, Some(self.project.clone()), cx); - editor.set_read_only(true); - editor.move_to_end(&Default::default(), cx); - editor - })); + self.editor = Self::editor_for_buffer(self.project.clone(), buffer, cx); cx.notify(); } } @@ -434,10 +442,12 @@ impl View for LspLogView { } fn render(&mut self, cx: &mut ViewContext) -> AnyElement { - if let Some(editor) = &self.editor { - ChildView::new(&editor, cx).into_any() - } else { - Empty::new().into_any() + ChildView::new(&self.editor, cx).into_any() + } + + fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext) { + if cx.is_self_focused() { + cx.focus(&self.editor); } } } @@ -451,6 +461,58 @@ impl Item for LspLogView { ) -> AnyElement { Label::new("LSP Logs", style.label.clone()).into_any() } + + fn as_searchable(&self, handle: &ViewHandle) -> Option> { + Some(Box::new(handle.clone())) + } +} + +impl SearchableItem for LspLogView { + type Match = ::Match; + + fn to_search_event(event: &Self::Event) -> Option { + Editor::to_search_event(event) + } + + fn clear_matches(&mut self, cx: &mut ViewContext) { + self.editor.update(cx, |e, cx| e.clear_matches(cx)) + } + + fn update_matches(&mut self, matches: Vec, cx: &mut ViewContext) { + self.editor + .update(cx, |e, cx| e.update_matches(matches, cx)) + } + + fn query_suggestion(&mut self, cx: &mut ViewContext) -> String { + self.editor.update(cx, |e, cx| e.query_suggestion(cx)) + } + + fn activate_match( + &mut self, + index: usize, + matches: Vec, + cx: &mut ViewContext, + ) { + self.editor + .update(cx, |e, cx| e.activate_match(index, matches, cx)) + } + + fn find_matches( + &mut self, + query: project::search::SearchQuery, + cx: &mut ViewContext, + ) -> gpui::Task> { + self.editor.update(cx, |e, cx| e.find_matches(query, cx)) + } + + fn active_match_index( + &mut self, + matches: Vec, + cx: &mut ViewContext, + ) -> Option { + self.editor + .update(cx, |e, cx| e.active_match_index(matches, cx)) + } } impl ToolbarItemView for LspLogToolbarItemView { @@ -717,7 +779,7 @@ impl Entity for LogStore { } impl Entity for LspLogView { - type Event = (); + type Event = editor::Event; } impl Entity for LspLogToolbarItemView { diff --git a/crates/lsp_log/src/lsp_log_tests.rs b/crates/lsp_log/src/lsp_log_tests.rs index 4be0db456c..572758ad63 100644 --- a/crates/lsp_log/src/lsp_log_tests.rs +++ b/crates/lsp_log/src/lsp_log_tests.rs @@ -76,10 +76,7 @@ async fn test_lsp_logs(cx: &mut TestAppContext) { logs_selected: true, }] ); - assert_eq!( - view.editor.as_ref().unwrap().read(cx).text(cx), - "hello from the server\n" - ); + assert_eq!(view.editor.read(cx).text(cx), "hello from the server\n"); }); } diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index 2d4bed760d..8435de71e2 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -487,6 +487,14 @@ impl LspCommand for GetTypeDefinition { type LspRequest = lsp::request::GotoTypeDefinition; type ProtoRequest = proto::GetTypeDefinition; + fn check_capabilities(&self, capabilities: &ServerCapabilities) -> bool { + match &capabilities.type_definition_provider { + None => false, + Some(lsp::TypeDefinitionProviderCapability::Simple(false)) => false, + _ => true, + } + } + fn to_lsp( &self, path: &Path,