diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 5efa3908256531e40845096187d44353ae140bbc..90e488368f99ea50bdcbfc671a359fa5e899f59e 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -16783,6 +16783,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut TestAppCon "some other init value": false })), enable_lsp_tasks: false, + fetch: None, }, ); }); @@ -16803,6 +16804,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut TestAppCon "anotherInitValue": false })), enable_lsp_tasks: false, + fetch: None, }, ); }); @@ -16823,6 +16825,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut TestAppCon "anotherInitValue": false })), enable_lsp_tasks: false, + fetch: None, }, ); }); @@ -16841,6 +16844,7 @@ async fn test_language_server_restart_due_to_settings_change(cx: &mut TestAppCon settings: None, initialization_options: None, enable_lsp_tasks: false, + fetch: None, }, ); }); diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 0606ae3de9be5800401787a852bafd5cfd9051be..e4a1510d7df128158691842206a27844304b3237 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -395,6 +395,7 @@ pub trait LspAdapter: 'static + Send + Sync { async fn fetch_latest_server_version( &self, delegate: &dyn LspAdapterDelegate, + cx: &AsyncApp, ) -> Result>; fn will_fetch_server( @@ -605,7 +606,7 @@ async fn try_fetch_server_binary delegate.update_status(name.clone(), BinaryStatus::CheckingForUpdate); let latest_version = adapter - .fetch_latest_server_version(delegate.as_ref()) + .fetch_latest_server_version(delegate.as_ref(), cx) .await?; if let Some(binary) = adapter @@ -2222,6 +2223,7 @@ impl LspAdapter for FakeLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { unreachable!(); } diff --git a/crates/language_extension/src/extension_lsp_adapter.rs b/crates/language_extension/src/extension_lsp_adapter.rs index e465a8dd0a0404e76b19942dd15bf19c4f204fdc..9b6e467f2f2dfddccaa96d7aaf5d5550d72fe904 100644 --- a/crates/language_extension/src/extension_lsp_adapter.rs +++ b/crates/language_extension/src/extension_lsp_adapter.rs @@ -204,6 +204,7 @@ impl LspAdapter for ExtensionLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { unreachable!("get_language_server_command is overridden") } diff --git a/crates/languages/src/c.rs b/crates/languages/src/c.rs index 2820f55a497c8b77b679a3ab5368cae6901c89e6..afdf49e66e59b78c82f234160a9c4bc1efa83574 100644 --- a/crates/languages/src/c.rs +++ b/crates/languages/src/c.rs @@ -5,8 +5,9 @@ use gpui::{App, AsyncApp}; use http_client::github::{AssetKind, GitHubLspBinaryVersion, latest_github_release}; pub use language::*; use lsp::{InitializeParams, LanguageServerBinary, LanguageServerName}; -use project::lsp_store::clangd_ext; +use project::{lsp_store::clangd_ext, project_settings::ProjectSettings}; use serde_json::json; +use settings::Settings as _; use smol::fs; use std::{any::Any, env::consts, path::PathBuf, sync::Arc}; use util::{ResultExt, fs::remove_matching, maybe, merge_json_value_into}; @@ -42,9 +43,19 @@ impl super::LspAdapter for CLspAdapter { async fn fetch_latest_server_version( &self, delegate: &dyn LspAdapterDelegate, + cx: &AsyncApp, ) -> Result> { - let release = - latest_github_release("clangd/clangd", true, false, delegate.http_client()).await?; + let release = latest_github_release( + "clangd/clangd", + true, + ProjectSettings::try_read_global(cx, |s| { + s.lsp.get(&Self::SERVER_NAME)?.fetch.as_ref()?.pre_release + }) + .flatten() + .unwrap_or(false), + delegate.http_client(), + ) + .await?; let os_suffix = match consts::OS { "macos" => "mac", "linux" => "linux", diff --git a/crates/languages/src/css.rs b/crates/languages/src/css.rs index 2480d4026883ab5b6e3af7f8a4d8bbbb59757879..5cea35084d54f86c6a2b47385bce628b73aa29c7 100644 --- a/crates/languages/src/css.rs +++ b/crates/languages/src/css.rs @@ -61,6 +61,7 @@ impl LspAdapter for CssLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new( self.node diff --git a/crates/languages/src/go.rs b/crates/languages/src/go.rs index 86f8e1faaa969449f45f38ee5cf8e8cde9ccff29..8c116c899f6456d1d3a12a741ca391a2cbaec41d 100644 --- a/crates/languages/src/go.rs +++ b/crates/languages/src/go.rs @@ -59,6 +59,7 @@ impl super::LspAdapter for GoLspAdapter { async fn fetch_latest_server_version( &self, delegate: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { let release = latest_github_release("golang/tools", false, false, delegate.http_client()).await?; diff --git a/crates/languages/src/json.rs b/crates/languages/src/json.rs index 4fcf865568b11ea0f8b40d6a7d57cc354e85a680..a33f5c9836f621a59b45aba7a249f7b1c2d1489d 100644 --- a/crates/languages/src/json.rs +++ b/crates/languages/src/json.rs @@ -321,6 +321,7 @@ impl LspAdapter for JsonLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new( self.node @@ -494,6 +495,7 @@ impl LspAdapter for NodeVersionAdapter { async fn fetch_latest_server_version( &self, delegate: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { let release = latest_github_release( "zed-industries/package-version-server", diff --git a/crates/languages/src/python.rs b/crates/languages/src/python.rs index bd3a7b34cf873328e480012ca96fcbe9fc3eff95..5e6f5e414f001209d3b4447ae8326a12953c45ac 100644 --- a/crates/languages/src/python.rs +++ b/crates/languages/src/python.rs @@ -157,6 +157,7 @@ impl LspAdapter for PythonLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new( self.node @@ -1111,6 +1112,7 @@ impl LspAdapter for PyLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new(()) as Box<_>) } @@ -1422,6 +1424,7 @@ impl LspAdapter for BasedPyrightLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new(()) as Box<_>) } diff --git a/crates/languages/src/rust.rs b/crates/languages/src/rust.rs index a5acc0043298cab49264dac75d51e6a69e5149fe..3d5ff1cd06149594e54de03d454bef64483b7e47 100644 --- a/crates/languages/src/rust.rs +++ b/crates/languages/src/rust.rs @@ -147,11 +147,16 @@ impl LspAdapter for RustLspAdapter { async fn fetch_latest_server_version( &self, delegate: &dyn LspAdapterDelegate, + cx: &AsyncApp, ) -> Result> { let release = latest_github_release( "rust-lang/rust-analyzer", true, - false, + ProjectSettings::try_read_global(cx, |s| { + s.lsp.get(&SERVER_NAME)?.fetch.as_ref()?.pre_release + }) + .flatten() + .unwrap_or(false), delegate.http_client(), ) .await?; diff --git a/crates/languages/src/tailwind.rs b/crates/languages/src/tailwind.rs index 7215dc0d591daae93ca0ee37043bc1372fa32cd2..af7653ea9e3059a40e0023e5d5d2ccd3c8b02556 100644 --- a/crates/languages/src/tailwind.rs +++ b/crates/languages/src/tailwind.rs @@ -66,6 +66,7 @@ impl LspAdapter for TailwindLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new( self.node diff --git a/crates/languages/src/typescript.rs b/crates/languages/src/typescript.rs index 77cf1a64f1f5586e727ca2b7ccc55dbe8a6183cf..15adea6070ada89e21de7d7d347f183c1aa010ab 100644 --- a/crates/languages/src/typescript.rs +++ b/crates/languages/src/typescript.rs @@ -563,6 +563,7 @@ impl LspAdapter for TypeScriptLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new(TypeScriptVersions { typescript_version: self.node.npm_package_latest_version("typescript").await?, @@ -885,6 +886,7 @@ impl LspAdapter for EsLintLspAdapter { async fn fetch_latest_server_version( &self, _delegate: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { let url = build_asset_url( "zed-industries/vscode-eslint", diff --git a/crates/languages/src/vtsls.rs b/crates/languages/src/vtsls.rs index f7152b0b5df8e2249c43b1f2ffa2b490bf001961..1cf3c8aa52db7bbfc1e784afecc62972884a3d47 100644 --- a/crates/languages/src/vtsls.rs +++ b/crates/languages/src/vtsls.rs @@ -73,6 +73,7 @@ impl LspAdapter for VtslsLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new(TypeScriptVersions { typescript_version: self.node.npm_package_latest_version("typescript").await?, diff --git a/crates/languages/src/yaml.rs b/crates/languages/src/yaml.rs index b9197b12ae85af5ee2a9aa2b5807a4f0410a1dda..bf634aafbab9fb3312f63fa818a55ddae90a05f3 100644 --- a/crates/languages/src/yaml.rs +++ b/crates/languages/src/yaml.rs @@ -44,6 +44,7 @@ impl LspAdapter for YamlLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { Ok(Box::new( self.node diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 6e06c2dd95fa9bf8d3b1a0670fb119a0ef552de1..36ec338fb71ca1a130657dca1db037051691ad9d 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -13070,6 +13070,7 @@ impl LspAdapter for SshLspAdapter { async fn fetch_latest_server_version( &self, _: &dyn LspAdapterDelegate, + _: &AsyncApp, ) -> Result> { anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version") } diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index 40874638111eb3b85d4f65ad0b531072ab082624..c98065116e00fd6c643a2c809cf6e8fb1c51532b 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -516,6 +516,12 @@ pub struct BinarySettings { pub ignore_system_version: Option, } +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Hash)] +pub struct FetchSettings { + // Whether to consider pre-releases for fetching + pub pre_release: Option, +} + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Hash)] #[serde(rename_all = "snake_case")] pub struct LspSettings { @@ -527,6 +533,7 @@ pub struct LspSettings { /// Default: true #[serde(default = "default_true")] pub enable_lsp_tasks: bool, + pub fetch: Option, } impl Default for LspSettings { @@ -536,6 +543,7 @@ impl Default for LspSettings { initialization_options: None, settings: None, enable_lsp_tasks: true, + fetch: None, } } } diff --git a/docs/src/languages/cpp.md b/docs/src/languages/cpp.md index e84bb6ea507f264240a40e986f41c5cd3a23610d..91395b5a94ca3e84699edcb731209ca9e260753c 100644 --- a/docs/src/languages/cpp.md +++ b/docs/src/languages/cpp.md @@ -9,22 +9,23 @@ C++ support is available natively in Zed. You can configure which `clangd` binary Zed should use. -To use a binary in a custom location, add the following to your `settings.json`: +By default, Zed will try to find a `clangd` in your `$PATH` and try to use that. If that binary successfully executes, it's used. Otherwise, Zed will fall back to installing its own `clangd` version and use that. + +If you want to install a pre-release `clangd` version instead you can instruct Zed to do so by setting `pre_release` to `true` in your `settings.json`: ```json { "lsp": { "clangd": { - "binary": { - "path": "/path/to/clangd", - "arguments": [] + "fetch": { + "pre_release": true } } } } ``` -If you want to disable Zed looking for a `clangd` binary, you can set `ignore_system_version` to `true`: +If you want to disable Zed looking for a `clangd` binary, you can set `ignore_system_version` to `true` in your `settings.json`: ```json { @@ -38,6 +39,23 @@ If you want to disable Zed looking for a `clangd` binary, you can set `ignore_sy } ``` +If you want to use a binary in a custom location, you can specify a `path` and optional `arguments`: + +```json +{ + "lsp": { + "cangd": { + "binary": { + "path": "/path/to/clangd", + "arguments": [] + } + } + } +} +``` + +This `"path"` has to be an absolute path. + ## Arguments You can pass any number of arguments to clangd. To see a full set of available options, run `clangd --help` from the command line. For example with `--function-arg-placeholders=0` completions contain only parentheses for function calls, while the default (`--function-arg-placeholders=1`) completions also contain placeholders for method parameters. diff --git a/docs/src/languages/rust.md b/docs/src/languages/rust.md index 0bfa3ecac75f1371b38e1609090315841ea97a4c..c8dd1ac550150573a6e476b75b1cee4645a49619 100644 --- a/docs/src/languages/rust.md +++ b/docs/src/languages/rust.md @@ -63,7 +63,21 @@ A `true` setting will set the target directory to `target/rust-analyzer`. You ca You can configure which `rust-analyzer` binary Zed should use. -By default, Zed will try to find a `rust-analyzer` in your `$PATH` and try to use that. If that binary successfully executes `rust-analyzer --help`, it's used. Otherwise, Zed will fall back to installing its own `rust-analyzer` version and using that. +By default, Zed will try to find a `rust-analyzer` in your `$PATH` and try to use that. If that binary successfully executes `rust-analyzer --help`, it's used. Otherwise, Zed will fall back to installing its own stable `rust-analyzer` version and use that. + +If you want to install pre-release `rust-analyzer` version instead you can instruct Zed to do so by setting `pre_release` to `true` in your `settings.json`: + +```json +{ + "lsp": { + "rust-analyzer": { + "fetch": { + "pre_release": true + } + } + } +} +``` If you want to disable Zed looking for a `rust-analyzer` binary, you can set `ignore_system_version` to `true` in your `settings.json`: