diff --git a/crates/languages/src/c.rs b/crates/languages/src/c.rs index 3279a7d9a9..988d5cf257 100644 --- a/crates/languages/src/c.rs +++ b/crates/languages/src/c.rs @@ -35,12 +35,12 @@ impl super::LspAdapter for CLspAdapter { .and_then(|s| s.binary.clone()) }); - if let Ok(Some(BinarySettings { - path: Some(path), - arguments, - })) = configured_binary - { - Some(LanguageServerBinary { + match configured_binary { + Ok(Some(BinarySettings { + path: Some(path), + arguments, + .. + })) => Some(LanguageServerBinary { path: path.into(), arguments: arguments .unwrap_or_default() @@ -48,15 +48,20 @@ impl super::LspAdapter for CLspAdapter { .map(|arg| arg.into()) .collect(), env: None, - }) - } else { - let env = delegate.shell_env().await; - let path = delegate.which(Self::SERVER_NAME.as_ref()).await?; - Some(LanguageServerBinary { - path, - arguments: vec![], - env: Some(env), - }) + }), + Ok(Some(BinarySettings { + path_lookup: Some(false), + .. + })) => None, + _ => { + let env = delegate.shell_env().await; + let path = delegate.which(Self::SERVER_NAME.as_ref()).await?; + Some(LanguageServerBinary { + path, + arguments: vec![], + env: Some(env), + }) + } } } diff --git a/crates/languages/src/go.rs b/crates/languages/src/go.rs index 30f9f35363..4b03117a0a 100644 --- a/crates/languages/src/go.rs +++ b/crates/languages/src/go.rs @@ -78,12 +78,12 @@ impl super::LspAdapter for GoLspAdapter { .and_then(|s| s.binary.clone()) }); - if let Ok(Some(BinarySettings { - path: Some(path), - arguments, - })) = configured_binary - { - Some(LanguageServerBinary { + match configured_binary { + Ok(Some(BinarySettings { + path: Some(path), + arguments, + .. + })) => Some(LanguageServerBinary { path: path.into(), arguments: arguments .unwrap_or_default() @@ -91,15 +91,20 @@ impl super::LspAdapter for GoLspAdapter { .map(|arg| arg.into()) .collect(), env: None, - }) - } else { - let env = delegate.shell_env().await; - let path = delegate.which(Self::SERVER_NAME.as_ref()).await?; - Some(LanguageServerBinary { - path, - arguments: server_binary_arguments(), - env: Some(env), - }) + }), + Ok(Some(BinarySettings { + path_lookup: Some(false), + .. + })) => None, + _ => { + let env = delegate.shell_env().await; + let path = delegate.which(Self::SERVER_NAME.as_ref()).await?; + Some(LanguageServerBinary { + path, + arguments: server_binary_arguments(), + env: Some(env), + }) + } } } diff --git a/crates/languages/src/rust.rs b/crates/languages/src/rust.rs index fa13957d1d..39a9835bc7 100644 --- a/crates/languages/src/rust.rs +++ b/crates/languages/src/rust.rs @@ -7,7 +7,7 @@ use http::github::{latest_github_release, GitHubLspBinaryVersion}; pub use language::*; use lazy_static::lazy_static; use lsp::LanguageServerBinary; -use project::project_settings::ProjectSettings; +use project::project_settings::{BinarySettings, ProjectSettings}; use regex::Regex; use settings::Settings; use smol::fs::{self, File}; @@ -35,29 +35,50 @@ impl LspAdapter for RustLspAdapter { async fn check_if_user_installed( &self, - _delegate: &dyn LspAdapterDelegate, + delegate: &dyn LspAdapterDelegate, cx: &AsyncAppContext, ) -> Option { - let binary = cx - .update(|cx| { - ProjectSettings::get_global(cx) - .lsp - .get(Self::SERVER_NAME) - .and_then(|s| s.binary.clone()) - }) - .ok()??; + let configured_binary = cx.update(|cx| { + ProjectSettings::get_global(cx) + .lsp + .get(Self::SERVER_NAME) + .and_then(|s| s.binary.clone()) + }); - let path = binary.path?; - Some(LanguageServerBinary { - path: path.into(), - arguments: binary - .arguments - .unwrap_or_default() - .iter() - .map(|arg| arg.into()) - .collect(), - env: None, - }) + match configured_binary { + Ok(Some(BinarySettings { + path, + arguments, + path_lookup, + })) => { + let (path, env) = match (path, path_lookup) { + (Some(path), lookup) => { + if lookup.is_some() { + log::warn!( + "Both `path` and `path_lookup` are set, ignoring `path_lookup`" + ); + } + (Some(path.into()), None) + } + (None, Some(true)) => { + let path = delegate.which(Self::SERVER_NAME.as_ref()).await?; + let env = delegate.shell_env().await; + (Some(path), Some(env)) + } + (None, Some(false)) | (None, None) => (None, None), + }; + path.map(|path| LanguageServerBinary { + path, + arguments: arguments + .unwrap_or_default() + .iter() + .map(|arg| arg.into()) + .collect(), + env, + }) + } + _ => None, + } } async fn fetch_latest_server_version( diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index c852833c98..fdf43a7edd 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -94,6 +94,7 @@ const fn true_value() -> bool { pub struct BinarySettings { pub path: Option, pub arguments: Option>, + pub path_lookup: Option, } #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]