diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 2b2271bf1ef03605ca6d577626a79898dfdcb6ac..8571ff033d9e907fb59c152f9ed13c0faecea683 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -245,10 +245,11 @@ pub struct Collaborator { pub replica_id: ReplicaId, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq)] pub enum Event { LanguageServerAdded(LanguageServerId), LanguageServerRemoved(LanguageServerId), + LanguageServerLog(LanguageServerId, String), ActiveEntryChanged(Option), WorktreeAdded, WorktreeRemoved(WorktreeId), @@ -2454,18 +2455,23 @@ impl Project { LanguageServerState::Starting(cx.spawn_weak(|this, mut cx| async move { let workspace_config = cx.update(|cx| languages.workspace_configuration(cx)).await; let language_server = pending_server.task.await.log_err()?; - let language_server = language_server - .initialize(initialization_options) - .await - .log_err()?; - let this = this.upgrade(&cx)?; + + language_server + .on_notification::({ + move |params, mut cx| { + if let Some(this) = this.upgrade(&cx) { + this.update(&mut cx, |_, cx| { + cx.emit(Event::LanguageServerLog(server_id, params.message)) + }); + } + } + }) + .detach(); language_server .on_notification::({ - let this = this.downgrade(); let adapter = adapter.clone(); move |mut params, cx| { - let this = this; let adapter = adapter.clone(); cx.spawn(|mut cx| async move { adapter.process_diagnostics(&mut params).await; @@ -2517,8 +2523,7 @@ impl Project { // avoid stalling any language server like `gopls` which waits for a response // to these requests when initializing. language_server - .on_request::({ - let this = this.downgrade(); + .on_request::( move |params, mut cx| async move { if let Some(this) = this.upgrade(&cx) { this.update(&mut cx, |this, _| { @@ -2532,12 +2537,11 @@ impl Project { }); } Ok(()) - } - }) + }, + ) .detach(); language_server - .on_request::({ - let this = this.downgrade(); + .on_request::( move |params, mut cx| async move { let this = this .upgrade(&cx) @@ -2555,24 +2559,15 @@ impl Project { } } Ok(()) - } - }) + }, + ) .detach(); language_server .on_request::({ - let this = this.downgrade(); let adapter = adapter.clone(); - let language_server = language_server.clone(); move |params, cx| { - Self::on_lsp_workspace_edit( - this, - params, - server_id, - adapter.clone(), - language_server.clone(), - cx, - ) + Self::on_lsp_workspace_edit(this, params, server_id, adapter.clone(), cx) } }) .detach(); @@ -2582,7 +2577,6 @@ impl Project { language_server .on_notification::({ - let this = this.downgrade(); move |params, mut cx| { if let Some(this) = this.upgrade(&cx) { this.update(&mut cx, |this, cx| { @@ -2598,6 +2592,10 @@ impl Project { }) .detach(); + let language_server = language_server + .initialize(initialization_options) + .await + .log_err()?; language_server .notify::( lsp::DidChangeConfigurationParams { @@ -2606,6 +2604,7 @@ impl Project { ) .ok(); + let this = this.upgrade(&cx)?; this.update(&mut cx, |this, cx| { // If the language server for this key doesn't match the server id, don't store the // server. Which will cause it to be dropped, killing the process @@ -2640,6 +2639,8 @@ impl Project { }, ); + cx.emit(Event::LanguageServerAdded(server_id)); + if let Some(project_id) = this.remote_id() { this.client .send(proto::StartLanguageServer { @@ -2765,6 +2766,7 @@ impl Project { cx.notify(); let server_state = self.language_servers.remove(&server_id); + cx.emit(Event::LanguageServerRemoved(server_id)); cx.spawn_weak(|this, mut cx| async move { let mut root_path = None; @@ -3109,12 +3111,14 @@ impl Project { params: lsp::ApplyWorkspaceEditParams, server_id: LanguageServerId, adapter: Arc, - language_server: Arc, mut cx: AsyncAppContext, ) -> Result { let this = this .upgrade(&cx) .ok_or_else(|| anyhow!("project project closed"))?; + let language_server = this + .read_with(&cx, |this, _| this.language_server_for_id(server_id)) + .ok_or_else(|| anyhow!("language server not found"))?; let transaction = Self::deserialize_workspace_edit( this.clone(), params.edit,