Add ability to specify binary path/args for clangd (#10608)

This uses the language server settings added in #9293 to allow users to
specify the binary path and arguments with which to start up `clangd`.

Example user settings for `clangd`:

```json
{
  "lsp": {
    "clangd": {
      "binary": {
        "path": "/usr/bin/clangd",
        "arguments": ["--log=verbose"]
      },
    }
  }
}
```

Constraints:

* Right now this only allows ABSOLUTE paths.

Release Notes:

- Added ability to specify `clangd` binary `path` (must be absolute) and
`arguments` in user settings. Example: `{"lsp": {"clangd": {"binary":
{"path": "/usr/bin/clangd", "arguments": ["--log=verbose"] }}}}`
This commit is contained in:
Henrique Ferreiro 2024-04-16 18:17:15 +02:00 committed by GitHub
parent 2f00fcbdf6
commit c1c8a74c7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 16 deletions

View File

@ -4,6 +4,8 @@ use futures::StreamExt;
use gpui::AsyncAppContext; use gpui::AsyncAppContext;
pub use language::*; pub use language::*;
use lsp::LanguageServerBinary; use lsp::LanguageServerBinary;
use project::project_settings::{BinarySettings, ProjectSettings};
use settings::Settings;
use smol::fs::{self, File}; use smol::fs::{self, File};
use std::{any::Any, env::consts, path::PathBuf, sync::Arc}; use std::{any::Any, env::consts, path::PathBuf, sync::Arc};
use util::{ use util::{
@ -14,10 +16,51 @@ use util::{
pub struct CLspAdapter; pub struct CLspAdapter;
impl CLspAdapter {
const SERVER_NAME: &'static str = "clangd";
}
#[async_trait(?Send)] #[async_trait(?Send)]
impl super::LspAdapter for CLspAdapter { impl super::LspAdapter for CLspAdapter {
fn name(&self) -> LanguageServerName { fn name(&self) -> LanguageServerName {
LanguageServerName("clangd".into()) LanguageServerName(Self::SERVER_NAME.into())
}
async fn check_if_user_installed(
&self,
delegate: &dyn LspAdapterDelegate,
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let configured_binary = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
.and_then(|s| s.binary.clone())
});
if let Ok(Some(BinarySettings {
path: Some(path),
arguments,
})) = configured_binary
{
Some(LanguageServerBinary {
path: path.into(),
arguments: arguments
.unwrap_or_default()
.iter()
.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),
})
}
} }
async fn fetch_latest_server_version( async fn fetch_latest_server_version(
@ -45,20 +88,6 @@ impl super::LspAdapter for CLspAdapter {
Ok(Box::new(version) as Box<_>) Ok(Box::new(version) as Box<_>)
} }
async fn check_if_user_installed(
&self,
delegate: &dyn LspAdapterDelegate,
_: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let env = delegate.shell_env().await;
let path = delegate.which("clangd".as_ref()).await?;
Some(LanguageServerBinary {
path,
arguments: vec![],
env: Some(env),
})
}
async fn fetch_server_binary( async fn fetch_server_binary(
&self, &self,
version: Box<dyn 'static + Send + Any>, version: Box<dyn 'static + Send + Any>,

View File

@ -88,7 +88,7 @@ impl super::LspAdapter for GoLspAdapter {
}) })
} else { } else {
let env = delegate.shell_env().await; let env = delegate.shell_env().await;
let path = delegate.which("gopls".as_ref()).await?; let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
Some(LanguageServerBinary { Some(LanguageServerBinary {
path, path,
arguments: server_binary_arguments(), arguments: server_binary_arguments(),