Add ability to specify binary path/args for gopls (#9803)

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

Example user settings for `gopls`:

```json
{
  "lsp": {
    "gopls": {
      "binary": {
        "path": "/Users/thorstenball/tmp/gopls",
        "arguments": ["-debug=0.0.0.0:8080"]
      },
    }
  }
}
```

Constraints:

* Right now this only allows ABSOLUTE paths.

Release Notes:

- Added ability to specify `gopls` binary `path` (must be absolute) and
`arguments` in user settings. Example: `{"lsp": {"gopls": {"binary":
{"path": "/my/abs/path/gopls", "arguments": ["-debug=0.0.0.0:8080"]
}}}}`
This commit is contained in:
Thorsten Ball 2024-03-26 07:09:06 +01:00 committed by GitHub
parent b0409ddd68
commit 157fb98a8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -5,8 +5,10 @@ use gpui::{AsyncAppContext, Task};
pub use language::*;
use lazy_static::lazy_static;
use lsp::LanguageServerBinary;
use project::project_settings::{BinarySettings, ProjectSettings};
use regex::Regex;
use serde_json::json;
use settings::Settings;
use smol::{fs, process};
use std::{
any::Any,
@ -28,6 +30,10 @@ fn server_binary_arguments() -> Vec<OsString> {
#[derive(Copy, Clone)]
pub struct GoLspAdapter;
impl GoLspAdapter {
const SERVER_NAME: &'static str = "gopls";
}
lazy_static! {
static ref GOPLS_VERSION_REGEX: Regex = Regex::new(r"\d+\.\d+\.\d+").unwrap();
}
@ -35,7 +41,7 @@ lazy_static! {
#[async_trait(?Send)]
impl super::LspAdapter for GoLspAdapter {
fn name(&self) -> LanguageServerName {
LanguageServerName("gopls".into())
LanguageServerName(Self::SERVER_NAME.into())
}
async fn fetch_latest_server_version(
@ -57,15 +63,38 @@ impl super::LspAdapter for GoLspAdapter {
async fn check_if_user_installed(
&self,
delegate: &dyn LspAdapterDelegate,
_: &AsyncAppContext,
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let env = delegate.shell_env().await;
let path = delegate.which("gopls".as_ref()).await?;
Some(LanguageServerBinary {
path,
arguments: server_binary_arguments(),
env: Some(env),
})
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("gopls".as_ref()).await?;
Some(LanguageServerBinary {
path,
arguments: server_binary_arguments(),
env: Some(env),
})
}
}
fn will_fetch_server(