lsp: Use project-local settings if available (#17753)
Release Notes: - Changed built-in language support (Rust, Go, C, YAML, ...) to lookup language-server specific settings locally in project directory first before falling back to global value. --------- Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
parent
092f29d394
commit
9db68ee6ae
9 changed files with 47 additions and 70 deletions
|
@ -5,8 +5,7 @@ use gpui::AsyncAppContext;
|
||||||
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||||
pub use language::*;
|
pub use language::*;
|
||||||
use lsp::LanguageServerBinary;
|
use lsp::LanguageServerBinary;
|
||||||
use project::project_settings::{BinarySettings, ProjectSettings};
|
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||||
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::{fs::remove_matching, maybe, ResultExt};
|
use util::{fs::remove_matching, maybe, ResultExt};
|
||||||
|
@ -29,10 +28,7 @@ impl super::LspAdapter for CLspAdapter {
|
||||||
cx: &AsyncAppContext,
|
cx: &AsyncAppContext,
|
||||||
) -> Option<LanguageServerBinary> {
|
) -> Option<LanguageServerBinary> {
|
||||||
let configured_binary = cx.update(|cx| {
|
let configured_binary = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate, Self::SERVER_NAME, cx).and_then(|s| s.binary.clone())
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.binary.clone())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match configured_binary {
|
match configured_binary {
|
||||||
|
|
|
@ -5,10 +5,9 @@ use gpui::{AppContext, AsyncAppContext, Task};
|
||||||
use http_client::github::latest_github_release;
|
use http_client::github::latest_github_release;
|
||||||
pub use language::*;
|
pub use language::*;
|
||||||
use lsp::LanguageServerBinary;
|
use lsp::LanguageServerBinary;
|
||||||
use project::project_settings::{BinarySettings, ProjectSettings};
|
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use settings::Settings;
|
|
||||||
use smol::{fs, process};
|
use smol::{fs, process};
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
@ -71,10 +70,7 @@ impl super::LspAdapter for GoLspAdapter {
|
||||||
cx: &AsyncAppContext,
|
cx: &AsyncAppContext,
|
||||||
) -> Option<LanguageServerBinary> {
|
) -> Option<LanguageServerBinary> {
|
||||||
let configured_binary = cx.update(|cx| {
|
let configured_binary = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate, Self::SERVER_NAME, cx).and_then(|s| s.binary.clone())
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.binary.clone())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match configured_binary {
|
match configured_binary {
|
||||||
|
|
|
@ -5,9 +5,9 @@ use gpui::AsyncAppContext;
|
||||||
use language::{ContextProvider, LanguageServerName, LspAdapter, LspAdapterDelegate};
|
use language::{ContextProvider, LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||||
use lsp::LanguageServerBinary;
|
use lsp::LanguageServerBinary;
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use project::project_settings::ProjectSettings;
|
use project::lsp_store::language_server_settings;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use settings::Settings;
|
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
@ -177,13 +177,11 @@ impl LspAdapter for PythonLspAdapter {
|
||||||
|
|
||||||
async fn workspace_configuration(
|
async fn workspace_configuration(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
_: &Arc<dyn LspAdapterDelegate>,
|
adapter: &Arc<dyn LspAdapterDelegate>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Result<Value> {
|
) -> Result<Value> {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(adapter.as_ref(), Self::SERVER_NAME, cx)
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.settings.clone())
|
.and_then(|s| s.settings.clone())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,9 +7,8 @@ use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||||
pub use language::*;
|
pub use language::*;
|
||||||
use language_settings::all_language_settings;
|
use language_settings::all_language_settings;
|
||||||
use lsp::LanguageServerBinary;
|
use lsp::LanguageServerBinary;
|
||||||
use project::project_settings::{BinarySettings, ProjectSettings};
|
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use settings::Settings;
|
|
||||||
use smol::fs::{self, File};
|
use smol::fs::{self, File};
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
@ -40,10 +39,7 @@ impl LspAdapter for RustLspAdapter {
|
||||||
cx: &AsyncAppContext,
|
cx: &AsyncAppContext,
|
||||||
) -> Option<LanguageServerBinary> {
|
) -> Option<LanguageServerBinary> {
|
||||||
let configured_binary = cx.update(|cx| {
|
let configured_binary = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate, Self::SERVER_NAME, cx).and_then(|s| s.binary.clone())
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.binary.clone())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match configured_binary {
|
match configured_binary {
|
||||||
|
|
|
@ -6,9 +6,8 @@ use gpui::AsyncAppContext;
|
||||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||||
use lsp::LanguageServerBinary;
|
use lsp::LanguageServerBinary;
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use project::project_settings::ProjectSettings;
|
use project::lsp_store::language_server_settings;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use settings::Settings;
|
|
||||||
use smol::fs;
|
use smol::fs;
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
@ -53,14 +52,12 @@ impl LspAdapter for TailwindLspAdapter {
|
||||||
|
|
||||||
async fn check_if_user_installed(
|
async fn check_if_user_installed(
|
||||||
&self,
|
&self,
|
||||||
_delegate: &dyn LspAdapterDelegate,
|
delegate: &dyn LspAdapterDelegate,
|
||||||
cx: &AsyncAppContext,
|
cx: &AsyncAppContext,
|
||||||
) -> Option<LanguageServerBinary> {
|
) -> Option<LanguageServerBinary> {
|
||||||
let configured_binary = cx
|
let configured_binary = cx
|
||||||
.update(|cx| {
|
.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate, Self::SERVER_NAME, cx)
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.binary.clone())
|
.and_then(|s| s.binary.clone())
|
||||||
})
|
})
|
||||||
.ok()??;
|
.ok()??;
|
||||||
|
@ -171,13 +168,11 @@ impl LspAdapter for TailwindLspAdapter {
|
||||||
|
|
||||||
async fn workspace_configuration(
|
async fn workspace_configuration(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
_: &Arc<dyn LspAdapterDelegate>,
|
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Result<Value> {
|
) -> Result<Value> {
|
||||||
let tailwind_user_settings = cx.update(|cx| {
|
let tailwind_user_settings = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.settings.clone())
|
.and_then(|s| s.settings.clone())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -8,10 +8,9 @@ use http_client::github::{build_asset_url, AssetKind, GitHubLspBinaryVersion};
|
||||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||||
use lsp::{CodeActionKind, LanguageServerBinary};
|
use lsp::{CodeActionKind, LanguageServerBinary};
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use project::project_settings::ProjectSettings;
|
use project::lsp_store::language_server_settings;
|
||||||
use project::ContextProviderWithTasks;
|
use project::ContextProviderWithTasks;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use settings::Settings;
|
|
||||||
use smol::{fs, io::BufReader, stream::StreamExt};
|
use smol::{fs, io::BufReader, stream::StreamExt};
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
|
@ -236,13 +235,11 @@ impl LspAdapter for TypeScriptLspAdapter {
|
||||||
|
|
||||||
async fn workspace_configuration(
|
async fn workspace_configuration(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
_: &Arc<dyn LspAdapterDelegate>,
|
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Result<Value> {
|
) -> Result<Value> {
|
||||||
let override_options = cx.update(|cx| {
|
let override_options = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.initialization_options.clone())
|
.and_then(|s| s.initialization_options.clone())
|
||||||
})?;
|
})?;
|
||||||
if let Some(options) = override_options {
|
if let Some(options) = override_options {
|
||||||
|
@ -334,9 +331,7 @@ impl LspAdapter for EsLintLspAdapter {
|
||||||
let workspace_root = delegate.worktree_root_path();
|
let workspace_root = delegate.worktree_root_path();
|
||||||
|
|
||||||
let eslint_user_settings = cx.update(|cx| {
|
let eslint_user_settings = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.settings.clone())
|
.and_then(|s| s.settings.clone())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -5,9 +5,8 @@ use gpui::AsyncAppContext;
|
||||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||||
use lsp::{CodeActionKind, LanguageServerBinary};
|
use lsp::{CodeActionKind, LanguageServerBinary};
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use project::project_settings::{BinarySettings, ProjectSettings};
|
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use settings::{Settings, SettingsLocation};
|
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
|
@ -75,10 +74,7 @@ impl LspAdapter for VtslsLspAdapter {
|
||||||
cx: &AsyncAppContext,
|
cx: &AsyncAppContext,
|
||||||
) -> Option<LanguageServerBinary> {
|
) -> Option<LanguageServerBinary> {
|
||||||
let configured_binary = cx.update(|cx| {
|
let configured_binary = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate, SERVER_NAME, cx).and_then(|s| s.binary.clone())
|
||||||
.lsp
|
|
||||||
.get(SERVER_NAME)
|
|
||||||
.and_then(|s| s.binary.clone())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match configured_binary {
|
match configured_binary {
|
||||||
|
@ -270,26 +266,18 @@ impl LspAdapter for VtslsLspAdapter {
|
||||||
|
|
||||||
async fn workspace_configuration(
|
async fn workspace_configuration(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
adapter: &Arc<dyn LspAdapterDelegate>,
|
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Result<Value> {
|
) -> Result<Value> {
|
||||||
let override_options = cx.update(|cx| {
|
let override_options = cx.update(|cx| {
|
||||||
ProjectSettings::get(
|
language_server_settings(delegate.as_ref(), SERVER_NAME, cx)
|
||||||
Some(SettingsLocation {
|
.and_then(|s| s.initialization_options.clone())
|
||||||
worktree_id: adapter.worktree_id(),
|
|
||||||
path: adapter.worktree_root_path(),
|
|
||||||
}),
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
.lsp
|
|
||||||
.get(SERVER_NAME)
|
|
||||||
.and_then(|s| s.initialization_options.clone())
|
|
||||||
})?;
|
})?;
|
||||||
if let Some(options) = override_options {
|
if let Some(options) = override_options {
|
||||||
return Ok(options);
|
return Ok(options);
|
||||||
}
|
}
|
||||||
let mut initialization_options = self
|
let mut initialization_options = self
|
||||||
.initialization_options(adapter)
|
.initialization_options(delegate)
|
||||||
.await
|
.await
|
||||||
.map(|o| o.unwrap())?;
|
.map(|o| o.unwrap())?;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use language::{
|
||||||
};
|
};
|
||||||
use lsp::LanguageServerBinary;
|
use lsp::LanguageServerBinary;
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use project::project_settings::ProjectSettings;
|
use project::lsp_store::language_server_settings;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use settings::{Settings, SettingsLocation};
|
use settings::{Settings, SettingsLocation};
|
||||||
use smol::fs;
|
use smol::fs;
|
||||||
|
@ -44,14 +44,12 @@ impl LspAdapter for YamlLspAdapter {
|
||||||
|
|
||||||
async fn check_if_user_installed(
|
async fn check_if_user_installed(
|
||||||
&self,
|
&self,
|
||||||
_delegate: &dyn LspAdapterDelegate,
|
delegate: &dyn LspAdapterDelegate,
|
||||||
cx: &AsyncAppContext,
|
cx: &AsyncAppContext,
|
||||||
) -> Option<LanguageServerBinary> {
|
) -> Option<LanguageServerBinary> {
|
||||||
let configured_binary = cx
|
let configured_binary = cx
|
||||||
.update(|cx| {
|
.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate, Self::SERVER_NAME, cx)
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.binary.clone())
|
.and_then(|s| s.binary.clone())
|
||||||
})
|
})
|
||||||
.ok()??;
|
.ok()??;
|
||||||
|
@ -147,9 +145,7 @@ impl LspAdapter for YamlLspAdapter {
|
||||||
let mut options = serde_json::json!({"[yaml]": {"editor.tabSize": tab_size}});
|
let mut options = serde_json::json!({"[yaml]": {"editor.tabSize": tab_size}});
|
||||||
|
|
||||||
let project_options = cx.update(|cx| {
|
let project_options = cx.update(|cx| {
|
||||||
ProjectSettings::get_global(cx)
|
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
|
||||||
.lsp
|
|
||||||
.get(Self::SERVER_NAME)
|
|
||||||
.and_then(|s| s.initialization_options.clone())
|
.and_then(|s| s.initialization_options.clone())
|
||||||
})?;
|
})?;
|
||||||
if let Some(override_options) = project_options {
|
if let Some(override_options) = project_options {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
||||||
environment::ProjectEnvironment,
|
environment::ProjectEnvironment,
|
||||||
lsp_command::{self, *},
|
lsp_command::{self, *},
|
||||||
lsp_ext_command,
|
lsp_ext_command,
|
||||||
project_settings::ProjectSettings,
|
project_settings::{LspSettings, ProjectSettings},
|
||||||
relativize_path, resolve_path,
|
relativize_path, resolve_path,
|
||||||
worktree_store::{WorktreeStore, WorktreeStoreEvent},
|
worktree_store::{WorktreeStore, WorktreeStoreEvent},
|
||||||
yarn::YarnPathStore,
|
yarn::YarnPathStore,
|
||||||
|
@ -7035,6 +7035,23 @@ impl HttpClient for BlockedHttpClient {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn language_server_settings<'a, 'b: 'a>(
|
||||||
|
delegate: &'a dyn LspAdapterDelegate,
|
||||||
|
language: &str,
|
||||||
|
cx: &'b AppContext,
|
||||||
|
) -> Option<&'a LspSettings> {
|
||||||
|
ProjectSettings::get(
|
||||||
|
Some(SettingsLocation {
|
||||||
|
worktree_id: delegate.worktree_id(),
|
||||||
|
path: delegate.worktree_root_path(),
|
||||||
|
}),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.lsp
|
||||||
|
.get(language)
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl LspAdapterDelegate for ProjectLspAdapterDelegate {
|
impl LspAdapterDelegate for ProjectLspAdapterDelegate {
|
||||||
fn show_notification(&self, message: &str, cx: &mut AppContext) {
|
fn show_notification(&self, message: &str, cx: &mut AppContext) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue