lsp: Identify language servers by their configuration (#35270)
- **WIP: reorganize dispositions** - **Introduce a LocalToolchainStore trait and use it for LspAdapter methods** Closes #35782 Closes #27331 Release Notes: - Python: Improved propagation of a selected virtual environment into the LSP configuration. This should the make all language-related features such as Go to definition or Find all references more reliable. --------- Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Lukas Wirth <lukas@zed.dev>
This commit is contained in:
parent
42ffa8900a
commit
b8a106632f
32 changed files with 1037 additions and 1085 deletions
|
@ -28,7 +28,7 @@ impl super::LspAdapter for CLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
|
||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::{Context as _, Result};
|
|||
use async_trait::async_trait;
|
||||
use futures::StreamExt;
|
||||
use gpui::AsyncApp;
|
||||
use language::{LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use language::{LspAdapter, LspAdapterDelegate, Toolchain};
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::{NodeRuntime, VersionStrategy};
|
||||
use project::{Fs, lsp_store::language_server_settings};
|
||||
|
@ -43,7 +43,7 @@ impl LspAdapter for CssLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate
|
||||
|
@ -144,7 +144,7 @@ impl LspAdapter for CssLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<serde_json::Value> {
|
||||
let mut default_config = json!({
|
||||
|
|
|
@ -75,7 +75,7 @@ impl super::LspAdapter for GoLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
|
||||
|
|
|
@ -8,8 +8,8 @@ use futures::StreamExt;
|
|||
use gpui::{App, AsyncApp, Task};
|
||||
use http_client::github::{GitHubLspBinaryVersion, latest_github_release};
|
||||
use language::{
|
||||
ContextProvider, LanguageName, LanguageRegistry, LanguageToolchainStore, LocalFile as _,
|
||||
LspAdapter, LspAdapterDelegate,
|
||||
ContextProvider, LanguageName, LanguageRegistry, LocalFile as _, LspAdapter,
|
||||
LspAdapterDelegate, Toolchain,
|
||||
};
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::{NodeRuntime, VersionStrategy};
|
||||
|
@ -303,7 +303,7 @@ impl LspAdapter for JsonLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate
|
||||
|
@ -404,7 +404,7 @@ impl LspAdapter for JsonLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let mut config = self.get_or_init_workspace_config(cx).await?;
|
||||
|
@ -529,7 +529,7 @@ impl LspAdapter for NodeVersionAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Context as _;
|
||||
use feature_flags::{FeatureFlag, FeatureFlagAppExt as _};
|
||||
use gpui::{App, UpdateGlobal};
|
||||
use gpui::{App, SharedString, UpdateGlobal};
|
||||
use node_runtime::NodeRuntime;
|
||||
use python::PyprojectTomlManifestProvider;
|
||||
use rust::CargoManifestProvider;
|
||||
|
@ -177,11 +177,13 @@ pub fn init(languages: Arc<LanguageRegistry>, node: NodeRuntime, cx: &mut App) {
|
|||
adapters: vec![python_lsp_adapter.clone(), py_lsp_adapter.clone()],
|
||||
context: Some(python_context_provider),
|
||||
toolchain: Some(python_toolchain_provider),
|
||||
manifest_name: Some(SharedString::new_static("pyproject.toml").into()),
|
||||
},
|
||||
LanguageInfo {
|
||||
name: "rust",
|
||||
adapters: vec![rust_lsp_adapter],
|
||||
context: Some(rust_context_provider),
|
||||
manifest_name: Some(SharedString::new_static("Cargo.toml").into()),
|
||||
..Default::default()
|
||||
},
|
||||
LanguageInfo {
|
||||
|
@ -234,6 +236,7 @@ pub fn init(languages: Arc<LanguageRegistry>, node: NodeRuntime, cx: &mut App) {
|
|||
registration.adapters,
|
||||
registration.context,
|
||||
registration.toolchain,
|
||||
registration.manifest_name,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -340,7 +343,7 @@ pub fn init(languages: Arc<LanguageRegistry>, node: NodeRuntime, cx: &mut App) {
|
|||
Arc::from(PyprojectTomlManifestProvider),
|
||||
];
|
||||
for provider in manifest_providers {
|
||||
project::ManifestProviders::global(cx).register(provider);
|
||||
project::ManifestProvidersStore::global(cx).register(provider);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,6 +353,7 @@ struct LanguageInfo {
|
|||
adapters: Vec<Arc<dyn LspAdapter>>,
|
||||
context: Option<Arc<dyn ContextProvider>>,
|
||||
toolchain: Option<Arc<dyn ToolchainLister>>,
|
||||
manifest_name: Option<ManifestName>,
|
||||
}
|
||||
|
||||
fn register_language(
|
||||
|
@ -358,6 +362,7 @@ fn register_language(
|
|||
adapters: Vec<Arc<dyn LspAdapter>>,
|
||||
context: Option<Arc<dyn ContextProvider>>,
|
||||
toolchain: Option<Arc<dyn ToolchainLister>>,
|
||||
manifest_name: Option<ManifestName>,
|
||||
) {
|
||||
let config = load_config(name);
|
||||
for adapter in adapters {
|
||||
|
@ -368,12 +373,14 @@ fn register_language(
|
|||
config.grammar.clone(),
|
||||
config.matcher.clone(),
|
||||
config.hidden,
|
||||
manifest_name.clone(),
|
||||
Arc::new(move || {
|
||||
Ok(LoadedLanguage {
|
||||
config: config.clone(),
|
||||
queries: load_queries(name),
|
||||
context_provider: context.clone(),
|
||||
toolchain_provider: toolchain.clone(),
|
||||
manifest_name: manifest_name.clone(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -127,7 +127,7 @@ impl LspAdapter for PythonLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
if let Some(pyright_bin) = delegate.which("pyright-langserver".as_ref()).await {
|
||||
|
@ -319,17 +319,9 @@ impl LspAdapter for PythonLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
adapter: &Arc<dyn LspAdapterDelegate>,
|
||||
toolchains: Arc<dyn LanguageToolchainStore>,
|
||||
toolchain: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let toolchain = toolchains
|
||||
.active_toolchain(
|
||||
adapter.worktree_id(),
|
||||
Arc::from("".as_ref()),
|
||||
LanguageName::new("Python"),
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
cx.update(move |cx| {
|
||||
let mut user_settings =
|
||||
language_server_settings(adapter.as_ref(), &Self::SERVER_NAME, cx)
|
||||
|
@ -397,9 +389,7 @@ impl LspAdapter for PythonLspAdapter {
|
|||
user_settings
|
||||
})
|
||||
}
|
||||
fn manifest_name(&self) -> Option<ManifestName> {
|
||||
Some(SharedString::new_static("pyproject.toml").into())
|
||||
}
|
||||
|
||||
fn workspace_folders_content(&self) -> WorkspaceFoldersContent {
|
||||
WorkspaceFoldersContent::WorktreeRoot
|
||||
}
|
||||
|
@ -1046,8 +1036,8 @@ impl LspAdapter for PyLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
toolchains: Arc<dyn LanguageToolchainStore>,
|
||||
cx: &AsyncApp,
|
||||
toolchain: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
if let Some(pylsp_bin) = delegate.which(Self::SERVER_NAME.as_ref()).await {
|
||||
let env = delegate.shell_env().await;
|
||||
|
@ -1057,14 +1047,7 @@ impl LspAdapter for PyLspAdapter {
|
|||
arguments: vec![],
|
||||
})
|
||||
} else {
|
||||
let venv = toolchains
|
||||
.active_toolchain(
|
||||
delegate.worktree_id(),
|
||||
Arc::from("".as_ref()),
|
||||
LanguageName::new("Python"),
|
||||
&mut cx.clone(),
|
||||
)
|
||||
.await?;
|
||||
let venv = toolchain?;
|
||||
let pylsp_path = Path::new(venv.path.as_ref()).parent()?.join("pylsp");
|
||||
pylsp_path.exists().then(|| LanguageServerBinary {
|
||||
path: venv.path.to_string().into(),
|
||||
|
@ -1211,17 +1194,9 @@ impl LspAdapter for PyLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
adapter: &Arc<dyn LspAdapterDelegate>,
|
||||
toolchains: Arc<dyn LanguageToolchainStore>,
|
||||
toolchain: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let toolchain = toolchains
|
||||
.active_toolchain(
|
||||
adapter.worktree_id(),
|
||||
Arc::from("".as_ref()),
|
||||
LanguageName::new("Python"),
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
cx.update(move |cx| {
|
||||
let mut user_settings =
|
||||
language_server_settings(adapter.as_ref(), &Self::SERVER_NAME, cx)
|
||||
|
@ -1282,9 +1257,6 @@ impl LspAdapter for PyLspAdapter {
|
|||
user_settings
|
||||
})
|
||||
}
|
||||
fn manifest_name(&self) -> Option<ManifestName> {
|
||||
Some(SharedString::new_static("pyproject.toml").into())
|
||||
}
|
||||
fn workspace_folders_content(&self) -> WorkspaceFoldersContent {
|
||||
WorkspaceFoldersContent::WorktreeRoot
|
||||
}
|
||||
|
@ -1377,8 +1349,8 @@ impl LspAdapter for BasedPyrightLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
toolchains: Arc<dyn LanguageToolchainStore>,
|
||||
cx: &AsyncApp,
|
||||
toolchain: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
if let Some(bin) = delegate.which(Self::BINARY_NAME.as_ref()).await {
|
||||
let env = delegate.shell_env().await;
|
||||
|
@ -1388,15 +1360,7 @@ impl LspAdapter for BasedPyrightLspAdapter {
|
|||
arguments: vec!["--stdio".into()],
|
||||
})
|
||||
} else {
|
||||
let venv = toolchains
|
||||
.active_toolchain(
|
||||
delegate.worktree_id(),
|
||||
Arc::from("".as_ref()),
|
||||
LanguageName::new("Python"),
|
||||
&mut cx.clone(),
|
||||
)
|
||||
.await?;
|
||||
let path = Path::new(venv.path.as_ref())
|
||||
let path = Path::new(toolchain?.path.as_ref())
|
||||
.parent()?
|
||||
.join(Self::BINARY_NAME);
|
||||
path.exists().then(|| LanguageServerBinary {
|
||||
|
@ -1543,17 +1507,9 @@ impl LspAdapter for BasedPyrightLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
adapter: &Arc<dyn LspAdapterDelegate>,
|
||||
toolchains: Arc<dyn LanguageToolchainStore>,
|
||||
toolchain: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let toolchain = toolchains
|
||||
.active_toolchain(
|
||||
adapter.worktree_id(),
|
||||
Arc::from("".as_ref()),
|
||||
LanguageName::new("Python"),
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
cx.update(move |cx| {
|
||||
let mut user_settings =
|
||||
language_server_settings(adapter.as_ref(), &Self::SERVER_NAME, cx)
|
||||
|
@ -1622,10 +1578,6 @@ impl LspAdapter for BasedPyrightLspAdapter {
|
|||
})
|
||||
}
|
||||
|
||||
fn manifest_name(&self) -> Option<ManifestName> {
|
||||
Some(SharedString::new_static("pyproject.toml").into())
|
||||
}
|
||||
|
||||
fn workspace_folders_content(&self) -> WorkspaceFoldersContent {
|
||||
WorkspaceFoldersContent::WorktreeRoot
|
||||
}
|
||||
|
|
|
@ -109,14 +109,10 @@ impl LspAdapter for RustLspAdapter {
|
|||
SERVER_NAME.clone()
|
||||
}
|
||||
|
||||
fn manifest_name(&self) -> Option<ManifestName> {
|
||||
Some(SharedString::new_static("Cargo.toml").into())
|
||||
}
|
||||
|
||||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate.which("rust-analyzer".as_ref()).await?;
|
||||
|
|
|
@ -3,7 +3,7 @@ use async_trait::async_trait;
|
|||
use collections::HashMap;
|
||||
use futures::StreamExt;
|
||||
use gpui::AsyncApp;
|
||||
use language::{LanguageName, LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use language::{LanguageName, LspAdapter, LspAdapterDelegate, Toolchain};
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::{NodeRuntime, VersionStrategy};
|
||||
use project::{Fs, lsp_store::language_server_settings};
|
||||
|
@ -50,7 +50,7 @@ impl LspAdapter for TailwindLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
|
||||
|
@ -155,7 +155,7 @@ impl LspAdapter for TailwindLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let mut tailwind_user_settings = cx.update(|cx| {
|
||||
|
|
|
@ -7,7 +7,7 @@ use gpui::{App, AppContext, AsyncApp, Task};
|
|||
use http_client::github::{AssetKind, GitHubLspBinaryVersion, build_asset_url};
|
||||
use language::{
|
||||
ContextLocation, ContextProvider, File, LanguageName, LanguageToolchainStore, LspAdapter,
|
||||
LspAdapterDelegate,
|
||||
LspAdapterDelegate, Toolchain,
|
||||
};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::{NodeRuntime, VersionStrategy};
|
||||
|
@ -722,7 +722,7 @@ impl LspAdapter for TypeScriptLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let override_options = cx.update(|cx| {
|
||||
|
@ -822,7 +822,7 @@ impl LspAdapter for EsLintLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let workspace_root = delegate.worktree_root_path();
|
||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
|||
use async_trait::async_trait;
|
||||
use collections::HashMap;
|
||||
use gpui::AsyncApp;
|
||||
use language::{LanguageName, LanguageToolchainStore, LspAdapter, LspAdapterDelegate};
|
||||
use language::{LanguageName, LspAdapter, LspAdapterDelegate, Toolchain};
|
||||
use lsp::{CodeActionKind, LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::{NodeRuntime, VersionStrategy};
|
||||
use project::{Fs, lsp_store::language_server_settings};
|
||||
|
@ -86,7 +86,7 @@ impl LspAdapter for VtslsLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let env = delegate.shell_env().await;
|
||||
|
@ -211,7 +211,7 @@ impl LspAdapter for VtslsLspAdapter {
|
|||
self: Arc<Self>,
|
||||
fs: &dyn Fs,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let tsdk_path = Self::tsdk_path(fs, delegate).await;
|
||||
|
|
|
@ -2,9 +2,7 @@ use anyhow::{Context as _, Result};
|
|||
use async_trait::async_trait;
|
||||
use futures::StreamExt;
|
||||
use gpui::AsyncApp;
|
||||
use language::{
|
||||
LanguageToolchainStore, LspAdapter, LspAdapterDelegate, language_settings::AllLanguageSettings,
|
||||
};
|
||||
use language::{LspAdapter, LspAdapterDelegate, Toolchain, language_settings::AllLanguageSettings};
|
||||
use lsp::{LanguageServerBinary, LanguageServerName};
|
||||
use node_runtime::{NodeRuntime, VersionStrategy};
|
||||
use project::{Fs, lsp_store::language_server_settings};
|
||||
|
@ -57,7 +55,7 @@ impl LspAdapter for YamlLspAdapter {
|
|||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
_: &AsyncApp,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
let path = delegate.which(Self::SERVER_NAME.as_ref()).await?;
|
||||
|
@ -135,7 +133,7 @@ impl LspAdapter for YamlLspAdapter {
|
|||
self: Arc<Self>,
|
||||
_: &dyn Fs,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
_: Arc<dyn LanguageToolchainStore>,
|
||||
_: Option<Toolchain>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<Value> {
|
||||
let location = SettingsLocation {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue