diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index b72f00f361..866bb8d7f5 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -368,7 +368,7 @@ impl Copilot { }; let binaries = LanguageServerBinaries { binary: binary.clone(), - installation_test_binary: binary, + installation_test_binary: Some(binary), }; let server = LanguageServer::new( LanguageServerId(0), diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 28cd1cd5b1..c25027f9bc 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -141,8 +141,11 @@ impl CachedLspAdapter { self.adapter.cached_server_binary(container_dir).await } - async fn installation_test_binary(&self, container_dir: PathBuf) -> LanguageServerBinary { - self.adapter.installation_test_binary(container_dir) + async fn installation_test_binary( + &self, + container_dir: PathBuf, + ) -> Option { + self.adapter.installation_test_binary(container_dir).await } pub fn code_action_kinds(&self) -> Option> { @@ -202,7 +205,10 @@ pub trait LspAdapter: 'static + Send + Sync { async fn cached_server_binary(&self, container_dir: PathBuf) -> Option; - fn installation_test_binary(&self, _container_dir: PathBuf) -> LanguageServerBinary { + async fn installation_test_binary( + &self, + _container_dir: PathBuf, + ) -> Option { unimplemented!(); } diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 94a5096c5f..f7d924604b 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -46,7 +46,7 @@ pub struct LanguageServerBinary { #[derive(Debug, Clone, Deserialize)] pub struct LanguageServerBinaries { pub binary: LanguageServerBinary, - pub installation_test_binary: LanguageServerBinary, + pub installation_test_binary: Option, } pub struct LanguageServer { @@ -162,7 +162,7 @@ impl LanguageServer { stdin, stout, Some(server), - Some(binaries.installation_test_binary), + binaries.installation_test_binary, root_path, code_action_kinds, cx, diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index e131bbb746..9641ecc0f1 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -3002,27 +3002,29 @@ impl Project { if !language_server.is_dead() { return; } - let server_id = language_server.server_id(); - let test_binary = match language_server.test_installation_binary() { - Some(test_binary) => test_binary.clone(), - None => return, - }; + + // A lack of test binary counts as a failure + let process = language_server + .test_installation_binary() + .as_ref() + .and_then(|binary| { + smol::process::Command::new(&binary.path) + .current_dir(&binary.path) + .args(&binary.arguments) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .kill_on_drop(true) + .spawn() + .ok() + }); const PROCESS_TIMEOUT: Duration = Duration::from_secs(5); let mut timeout = cx.background().timer(PROCESS_TIMEOUT).fuse(); let mut errored = false; - let result = smol::process::Command::new(&test_binary.path) - .current_dir(&test_binary.path) - .args(test_binary.arguments) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::inherit()) - .kill_on_drop(true) - .spawn(); - - if let Ok(mut process) = result { + if let Some(mut process) = process { futures::select! { status = process.status().fuse() => match status { Ok(status) => errored = !status.success(), diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs index 9d4e1802d5..0f580f1d4f 100644 --- a/crates/zed/src/languages/c.rs +++ b/crates/zed/src/languages/c.rs @@ -109,9 +109,17 @@ impl super::LspAdapter for CLspAdapter { .await .log_err() } - - fn installation_test_binary(&self, container_dir: PathBuf) -> LanguageServerBinary { - unimplemented!(); + + async fn installation_test_binary( + &self, + container_dir: PathBuf, + ) -> Option { + self.cached_server_binary(container_dir) + .await + .map(|mut binary| { + binary.arguments = vec!["--help".into()]; + binary + }) } async fn label_for_completion(