lsp: Remove reinstall, update config (#18318)
Release Notes: - Fixed overriding the path of a language server binary for all language servers. `{"lsp":{"<lsp-name>":{"binary":{"path": "_"}}}}` will now work for all language servers including those defined by extensions. - (breaking change) To disable finding lsp adapters in your path, you must now specify `{"lsp":{"<lsp-name>":{"binary":{"ignore_system_version": true}}}}`. Previously this was `{"lsp":{"<lsp-name>":{"binary":{"path_lookup": false}}}}`. Note that this setting still does not apply to extensions. - Removed automatic reinstallation of language servers. (It mostly didn't work) --------- Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
1f54fde4d2
commit
dc48af0ca1
21 changed files with 405 additions and 940 deletions
|
@ -5,7 +5,6 @@ use gpui::AsyncAppContext;
|
|||
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||
pub use language::*;
|
||||
use lsp::LanguageServerBinary;
|
||||
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||
use smol::fs::{self, File};
|
||||
use std::{any::Any, env::consts, path::PathBuf, sync::Arc};
|
||||
use util::{fs::remove_matching, maybe, ResultExt};
|
||||
|
@ -25,41 +24,14 @@ impl super::LspAdapter for CLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
cx: &AsyncAppContext,
|
||||
_: &AsyncAppContext,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let configured_binary = cx.update(|cx| {
|
||||
language_server_settings(delegate, &Self::SERVER_NAME, cx)
|
||||
.and_then(|s| s.binary.clone())
|
||||
});
|
||||
|
||||
match configured_binary {
|
||||
Ok(Some(BinarySettings {
|
||||
path: Some(path),
|
||||
arguments,
|
||||
..
|
||||
})) => Some(LanguageServerBinary {
|
||||
path: path.into(),
|
||||
arguments: arguments
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|arg| arg.into())
|
||||
.collect(),
|
||||
env: None,
|
||||
}),
|
||||
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),
|
||||
})
|
||||
}
|
||||
}
|
||||
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
|
||||
Some(LanguageServerBinary {
|
||||
path,
|
||||
arguments: vec![],
|
||||
env: None,
|
||||
})
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
|
@ -141,18 +113,6 @@ impl super::LspAdapter for CLspAdapter {
|
|||
get_cached_server_binary(container_dir).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir)
|
||||
.await
|
||||
.map(|mut binary| {
|
||||
binary.arguments = vec!["--help".into()];
|
||||
binary
|
||||
})
|
||||
}
|
||||
|
||||
async fn label_for_completion(
|
||||
&self,
|
||||
completion: &lsp::CompletionItem,
|
||||
|
|
|
@ -84,13 +84,6 @@ impl LspAdapter for CssLspAdapter {
|
|||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn initialization_options(
|
||||
self: Arc<Self>,
|
||||
_: &Arc<dyn LspAdapterDelegate>,
|
||||
|
|
|
@ -6,7 +6,6 @@ use gpui::{AppContext, AsyncAppContext, Task};
|
|||
use http_client::github::latest_github_release;
|
||||
pub use language::*;
|
||||
use lsp::LanguageServerBinary;
|
||||
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||
use regex::Regex;
|
||||
use serde_json::json;
|
||||
use smol::{fs, process};
|
||||
|
@ -68,41 +67,14 @@ impl super::LspAdapter for GoLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
cx: &AsyncAppContext,
|
||||
_: &AsyncAppContext,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let configured_binary = cx.update(|cx| {
|
||||
language_server_settings(delegate, &Self::SERVER_NAME, cx)
|
||||
.and_then(|s| s.binary.clone())
|
||||
});
|
||||
|
||||
match configured_binary {
|
||||
Ok(Some(BinarySettings {
|
||||
path: Some(path),
|
||||
arguments,
|
||||
..
|
||||
})) => Some(LanguageServerBinary {
|
||||
path: path.into(),
|
||||
arguments: arguments
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|arg| arg.into())
|
||||
.collect(),
|
||||
env: None,
|
||||
}),
|
||||
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),
|
||||
})
|
||||
}
|
||||
}
|
||||
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
|
||||
Some(LanguageServerBinary {
|
||||
path,
|
||||
arguments: server_binary_arguments(),
|
||||
env: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn will_fetch_server(
|
||||
|
@ -214,18 +186,6 @@ impl super::LspAdapter for GoLspAdapter {
|
|||
get_cached_server_binary(container_dir).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir)
|
||||
.await
|
||||
.map(|mut binary| {
|
||||
binary.arguments = vec!["--help".into()];
|
||||
binary
|
||||
})
|
||||
}
|
||||
|
||||
async fn initialization_options(
|
||||
self: Arc<Self>,
|
||||
_: &Arc<dyn LspAdapterDelegate>,
|
||||
|
|
|
@ -186,13 +186,6 @@ impl LspAdapter for JsonLspAdapter {
|
|||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn initialization_options(
|
||||
self: Arc<Self>,
|
||||
_: &Arc<dyn LspAdapterDelegate>,
|
||||
|
@ -374,18 +367,6 @@ impl LspAdapter for NodeVersionAdapter {
|
|||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_version_server_binary(container_dir).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_version_server_binary(container_dir)
|
||||
.await
|
||||
.map(|mut binary| {
|
||||
binary.arguments = vec!["--version".into()];
|
||||
binary
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_cached_version_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
|
|
|
@ -97,13 +97,6 @@ impl LspAdapter for PythonLspAdapter {
|
|||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn process_completions(&self, items: &mut [lsp::CompletionItem]) {
|
||||
// Pyright assigns each completion item a `sortText` of the form `XX.YYYY.name`.
|
||||
// Where `XX` is the sorting category, `YYYY` is based on most recent usage,
|
||||
|
|
|
@ -8,7 +8,6 @@ use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
|||
pub use language::*;
|
||||
use language_settings::all_language_settings;
|
||||
use lsp::LanguageServerBinary;
|
||||
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||
use regex::Regex;
|
||||
use smol::fs::{self, File};
|
||||
use std::{
|
||||
|
@ -37,77 +36,34 @@ impl LspAdapter for RustLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
cx: &AsyncAppContext,
|
||||
_: &AsyncAppContext,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let configured_binary = cx
|
||||
.update(|cx| {
|
||||
language_server_settings(delegate, &Self::SERVER_NAME, cx)
|
||||
.and_then(|s| s.binary.clone())
|
||||
let path = delegate.which("rust-analyzer".as_ref()).await?;
|
||||
let env = delegate.shell_env().await;
|
||||
|
||||
// It is surprisingly common for ~/.cargo/bin/rust-analyzer to be a symlink to
|
||||
// /usr/bin/rust-analyzer that fails when you run it; so we need to test it.
|
||||
log::info!("found rust-analyzer in PATH. trying to run `rust-analyzer --help`");
|
||||
let result = delegate
|
||||
.try_exec(LanguageServerBinary {
|
||||
path: path.clone(),
|
||||
arguments: vec!["--help".into()],
|
||||
env: Some(env.clone()),
|
||||
})
|
||||
.ok()?;
|
||||
.await;
|
||||
if let Err(err) = result {
|
||||
log::error!(
|
||||
"failed to run rust-analyzer after detecting it in PATH: binary: {:?}: {}",
|
||||
path,
|
||||
err
|
||||
);
|
||||
return None;
|
||||
}
|
||||
|
||||
let (path, env, arguments) = match configured_binary {
|
||||
// If nothing is configured, or path_lookup explicitly enabled,
|
||||
// we lookup the binary in the path.
|
||||
None
|
||||
| Some(BinarySettings {
|
||||
path: None,
|
||||
path_lookup: Some(true),
|
||||
..
|
||||
})
|
||||
| Some(BinarySettings {
|
||||
path: None,
|
||||
path_lookup: None,
|
||||
..
|
||||
}) => {
|
||||
let path = delegate.which("rust-analyzer".as_ref()).await;
|
||||
let env = delegate.shell_env().await;
|
||||
|
||||
if let Some(path) = path {
|
||||
// It is surprisingly common for ~/.cargo/bin/rust-analyzer to be a symlink to
|
||||
// /usr/bin/rust-analyzer that fails when you run it; so we need to test it.
|
||||
log::info!("found rust-analyzer in PATH. trying to run `rust-analyzer --help`");
|
||||
match delegate
|
||||
.try_exec(LanguageServerBinary {
|
||||
path: path.clone(),
|
||||
arguments: vec!["--help".into()],
|
||||
env: Some(env.clone()),
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(()) => (Some(path), Some(env), None),
|
||||
Err(err) => {
|
||||
log::error!("failed to run rust-analyzer after detecting it in PATH: binary: {:?}: {}", path, err);
|
||||
(None, None, None)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(None, None, None)
|
||||
}
|
||||
}
|
||||
// Otherwise, we use the configured binary.
|
||||
Some(BinarySettings {
|
||||
path: Some(path),
|
||||
arguments,
|
||||
path_lookup,
|
||||
}) => {
|
||||
if path_lookup.is_some() {
|
||||
log::warn!("Both `path` and `path_lookup` are set, ignoring `path_lookup`");
|
||||
}
|
||||
(Some(path.into()), None, arguments)
|
||||
}
|
||||
|
||||
_ => (None, None, None),
|
||||
};
|
||||
|
||||
path.map(|path| LanguageServerBinary {
|
||||
Some(LanguageServerBinary {
|
||||
path,
|
||||
env,
|
||||
arguments: arguments
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|arg| arg.into())
|
||||
.collect(),
|
||||
env: Some(env),
|
||||
arguments: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -186,18 +142,6 @@ impl LspAdapter for RustLspAdapter {
|
|||
get_cached_server_binary(container_dir).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir)
|
||||
.await
|
||||
.map(|mut binary| {
|
||||
binary.arguments = vec!["--help".into()];
|
||||
binary
|
||||
})
|
||||
}
|
||||
|
||||
fn disk_based_diagnostic_sources(&self) -> Vec<String> {
|
||||
vec!["rustc".into()]
|
||||
}
|
||||
|
|
|
@ -46,38 +46,6 @@ impl LspAdapter for TailwindLspAdapter {
|
|||
Self::SERVER_NAME.clone()
|
||||
}
|
||||
|
||||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
cx: &AsyncAppContext,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let configured_binary = cx
|
||||
.update(|cx| {
|
||||
language_server_settings(delegate, &Self::SERVER_NAME, cx)
|
||||
.and_then(|s| s.binary.clone())
|
||||
})
|
||||
.ok()??;
|
||||
|
||||
let path = if let Some(configured_path) = configured_binary.path.map(PathBuf::from) {
|
||||
configured_path
|
||||
} else {
|
||||
self.node.binary_path().await.ok()?
|
||||
};
|
||||
|
||||
let arguments = configured_binary
|
||||
.arguments
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|arg| arg.into())
|
||||
.collect();
|
||||
|
||||
Some(LanguageServerBinary {
|
||||
path,
|
||||
arguments,
|
||||
env: None,
|
||||
})
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
&self,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
|
@ -125,13 +93,6 @@ impl LspAdapter for TailwindLspAdapter {
|
|||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn initialization_options(
|
||||
self: Arc<Self>,
|
||||
_: &Arc<dyn LspAdapterDelegate>,
|
||||
|
|
|
@ -164,13 +164,6 @@ impl LspAdapter for TypeScriptLspAdapter {
|
|||
get_cached_ts_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_ts_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
|
||||
Some(vec![
|
||||
CodeActionKind::QUICKFIX,
|
||||
|
@ -509,19 +502,6 @@ impl LspAdapter for EsLintLspAdapter {
|
|||
arguments: eslint_server_binary_arguments(&server_path),
|
||||
})
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let server_path =
|
||||
Self::build_destination_path(&container_dir).join(EsLintLspAdapter::SERVER_PATH);
|
||||
Some(LanguageServerBinary {
|
||||
path: self.node.binary_path().await.ok()?,
|
||||
env: None,
|
||||
arguments: eslint_server_binary_arguments(&server_path),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
|
|
|
@ -5,7 +5,7 @@ use gpui::AsyncAppContext;
|
|||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary};
|
||||
use node_runtime::NodeRuntime;
|
||||
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||
use project::lsp_store::language_server_settings;
|
||||
use serde_json::Value;
|
||||
use std::{
|
||||
any::Any,
|
||||
|
@ -71,40 +71,15 @@ impl LspAdapter for VtslsLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
cx: &AsyncAppContext,
|
||||
_: &AsyncAppContext,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let configured_binary = cx.update(|cx| {
|
||||
language_server_settings(delegate, &SERVER_NAME, cx).and_then(|s| s.binary.clone())
|
||||
});
|
||||
|
||||
match configured_binary {
|
||||
Ok(Some(BinarySettings {
|
||||
path: Some(path),
|
||||
arguments,
|
||||
..
|
||||
})) => Some(LanguageServerBinary {
|
||||
path: path.into(),
|
||||
arguments: arguments
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|arg| arg.into())
|
||||
.collect(),
|
||||
env: None,
|
||||
}),
|
||||
Ok(Some(BinarySettings {
|
||||
path_lookup: Some(false),
|
||||
..
|
||||
})) => None,
|
||||
_ => {
|
||||
let env = delegate.shell_env().await;
|
||||
let path = delegate.which(SERVER_NAME.as_ref()).await?;
|
||||
Some(LanguageServerBinary {
|
||||
path: path.clone(),
|
||||
arguments: typescript_server_binary_arguments(&path),
|
||||
env: Some(env),
|
||||
})
|
||||
}
|
||||
}
|
||||
let env = delegate.shell_env().await;
|
||||
let path = delegate.which(SERVER_NAME.as_ref()).await?;
|
||||
Some(LanguageServerBinary {
|
||||
path: path.clone(),
|
||||
arguments: typescript_server_binary_arguments(&path),
|
||||
env: Some(env),
|
||||
})
|
||||
}
|
||||
|
||||
async fn fetch_server_binary(
|
||||
|
@ -157,13 +132,6 @@ impl LspAdapter for VtslsLspAdapter {
|
|||
get_cached_ts_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_ts_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
|
||||
Some(vec![
|
||||
CodeActionKind::QUICKFIX,
|
||||
|
|
|
@ -42,37 +42,6 @@ impl LspAdapter for YamlLspAdapter {
|
|||
Self::SERVER_NAME.clone()
|
||||
}
|
||||
|
||||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
cx: &AsyncAppContext,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let configured_binary = cx
|
||||
.update(|cx| {
|
||||
language_server_settings(delegate, &Self::SERVER_NAME, cx)
|
||||
.and_then(|s| s.binary.clone())
|
||||
})
|
||||
.ok()??;
|
||||
|
||||
let path = if let Some(configured_path) = configured_binary.path.map(PathBuf::from) {
|
||||
configured_path
|
||||
} else {
|
||||
self.node.binary_path().await.ok()?
|
||||
};
|
||||
|
||||
let arguments = configured_binary
|
||||
.arguments
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|arg| arg.into())
|
||||
.collect();
|
||||
Some(LanguageServerBinary {
|
||||
path,
|
||||
arguments,
|
||||
env: None,
|
||||
})
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
&self,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
|
@ -120,13 +89,6 @@ impl LspAdapter for YamlLspAdapter {
|
|||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir, &self.node).await
|
||||
}
|
||||
|
||||
async fn workspace_configuration(
|
||||
self: Arc<Self>,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue