diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index c8554074cd..e4552864dd 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -130,6 +130,14 @@ impl CachedLspAdapter { self.adapter.fetch_latest_server_version(delegate).await } + pub fn will_fetch_server_binary( + &self, + delegate: &Arc, + cx: &mut AsyncAppContext, + ) -> Option>> { + self.adapter.will_fetch_server_binary(delegate, cx) + } + pub async fn fetch_server_binary( &self, version: Box, @@ -204,6 +212,14 @@ pub trait LspAdapter: 'static + Send + Sync { delegate: &dyn LspAdapterDelegate, ) -> Result>; + fn will_fetch_server_binary( + &self, + _: &Arc, + _: &mut AsyncAppContext, + ) -> Option>> { + None + } + async fn fetch_server_binary( &self, version: Box, @@ -971,7 +987,7 @@ async fn get_binary( delegate: Arc, download_dir: Arc, statuses: async_broadcast::Sender<(Arc, LanguageServerBinaryStatus)>, - _cx: AsyncAppContext, + mut cx: AsyncAppContext, ) -> Result { let container_dir = download_dir.join(adapter.name.0.as_ref()); if !container_dir.exists() { @@ -980,6 +996,10 @@ async fn get_binary( .context("failed to create container directory")?; } + if let Some(task) = adapter.will_fetch_server_binary(&delegate, &mut cx) { + task.await?; + } + let binary = fetch_latest_binary( adapter.clone(), language.clone(), diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 6d823f0107..27d424879f 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -252,7 +252,7 @@ pub enum Event { LanguageServerAdded(LanguageServerId), LanguageServerRemoved(LanguageServerId), LanguageServerLog(LanguageServerId, String), - LanguageServerNotification(String), + Notification(String), ActiveEntryChanged(Option), WorktreeAdded, WorktreeRemoved(WorktreeId), @@ -7205,9 +7205,8 @@ impl ProjectLspAdapterDelegate { impl LspAdapterDelegate for ProjectLspAdapterDelegate { fn show_notification(&self, message: &str, cx: &mut AppContext) { - self.project.update(cx, |_, cx| { - cx.emit(Event::LanguageServerNotification(message.to_owned())) - }); + self.project + .update(cx, |_, cx| cx.emit(Event::Notification(message.to_owned()))); } fn http_client(&self) -> Arc { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index f813635941..43ca41ab1d 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -553,6 +553,10 @@ impl Workspace { } } + project::Event::Notification(message) => this.show_notification(0, cx, |cx| { + cx.add_view(|_| MessageNotification::new(message.clone())) + }), + _ => {} } cx.notify() diff --git a/crates/zed/src/languages/go.rs b/crates/zed/src/languages/go.rs index c425e6931f..fe518ed4ee 100644 --- a/crates/zed/src/languages/go.rs +++ b/crates/zed/src/languages/go.rs @@ -1,6 +1,7 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use futures::StreamExt; +use gpui::{AsyncAppContext, Task}; pub use language::*; use lazy_static::lazy_static; use regex::Regex; @@ -47,6 +48,24 @@ impl super::LspAdapter for GoLspAdapter { Ok(Box::new(version) as Box<_>) } + fn will_fetch_server_binary( + &self, + delegate: &Arc, + cx: &mut AsyncAppContext, + ) -> Option>> { + let delegate = delegate.clone(); + Some(cx.spawn(|mut cx| async move { + let install_output = process::Command::new("go").args(["version"]).output().await; + if install_output.is_err() { + cx.update(|cx| { + delegate + .show_notification("go is not installed. gopls will not be available.", cx); + }) + } + Ok(()) + })) + } + async fn fetch_server_binary( &self, version: Box,