Skip to content

Commit

Permalink
lsp: Use project-local settings if available (zed-industries#17753)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
2 people authored and thataboy committed Sep 14, 2024
1 parent 543ebbe commit 2601b47
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 70 deletions.
8 changes: 2 additions & 6 deletions crates/languages/src/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use gpui::AsyncAppContext;
use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
pub use language::*;
use lsp::LanguageServerBinary;
use project::project_settings::{BinarySettings, ProjectSettings};
use settings::Settings;
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};
Expand All @@ -29,10 +28,7 @@ impl super::LspAdapter for CLspAdapter {
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let configured_binary = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
.and_then(|s| s.binary.clone())
language_server_settings(delegate, Self::SERVER_NAME, cx).and_then(|s| s.binary.clone())
});

match configured_binary {
Expand Down
8 changes: 2 additions & 6 deletions crates/languages/src/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ use gpui::{AppContext, AsyncAppContext, Task};
use http_client::github::latest_github_release;
pub use language::*;
use lsp::LanguageServerBinary;
use project::project_settings::{BinarySettings, ProjectSettings};
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
use regex::Regex;
use serde_json::json;
use settings::Settings;
use smol::{fs, process};
use std::{
any::Any,
Expand Down Expand Up @@ -71,10 +70,7 @@ impl super::LspAdapter for GoLspAdapter {
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let configured_binary = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
.and_then(|s| s.binary.clone())
language_server_settings(delegate, Self::SERVER_NAME, cx).and_then(|s| s.binary.clone())
});

match configured_binary {
Expand Down
10 changes: 4 additions & 6 deletions crates/languages/src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use gpui::AsyncAppContext;
use language::{ContextProvider, LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::LanguageServerBinary;
use node_runtime::NodeRuntime;
use project::project_settings::ProjectSettings;
use project::lsp_store::language_server_settings;
use serde_json::Value;
use settings::Settings;

use std::{
any::Any,
borrow::Cow,
Expand Down Expand Up @@ -177,13 +177,11 @@ impl LspAdapter for PythonLspAdapter {

async fn workspace_configuration(
self: Arc<Self>,
_: &Arc<dyn LspAdapterDelegate>,
adapter: &Arc<dyn LspAdapterDelegate>,
cx: &mut AsyncAppContext,
) -> Result<Value> {
cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
language_server_settings(adapter.as_ref(), Self::SERVER_NAME, cx)
.and_then(|s| s.settings.clone())
.unwrap_or_default()
})
Expand Down
8 changes: 2 additions & 6 deletions crates/languages/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ use http_client::github::{latest_github_release, GitHubLspBinaryVersion};
pub use language::*;
use language_settings::all_language_settings;
use lsp::LanguageServerBinary;
use project::project_settings::{BinarySettings, ProjectSettings};
use project::{lsp_store::language_server_settings, project_settings::BinarySettings};
use regex::Regex;
use settings::Settings;
use smol::fs::{self, File};
use std::{
any::Any,
Expand Down Expand Up @@ -40,10 +39,7 @@ impl LspAdapter for RustLspAdapter {
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let configured_binary = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
.and_then(|s| s.binary.clone())
language_server_settings(delegate, Self::SERVER_NAME, cx).and_then(|s| s.binary.clone())
});

match configured_binary {
Expand Down
15 changes: 5 additions & 10 deletions crates/languages/src/tailwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ use gpui::AsyncAppContext;
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::LanguageServerBinary;
use node_runtime::NodeRuntime;
use project::project_settings::ProjectSettings;
use project::lsp_store::language_server_settings;
use serde_json::{json, Value};
use settings::Settings;
use smol::fs;
use std::{
any::Any,
Expand Down Expand Up @@ -53,14 +52,12 @@ impl LspAdapter for TailwindLspAdapter {

async fn check_if_user_installed(
&self,
_delegate: &dyn LspAdapterDelegate,
delegate: &dyn LspAdapterDelegate,
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let configured_binary = cx
.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
language_server_settings(delegate, Self::SERVER_NAME, cx)
.and_then(|s| s.binary.clone())
})
.ok()??;
Expand Down Expand Up @@ -171,13 +168,11 @@ impl LspAdapter for TailwindLspAdapter {

async fn workspace_configuration(
self: Arc<Self>,
_: &Arc<dyn LspAdapterDelegate>,
delegate: &Arc<dyn LspAdapterDelegate>,
cx: &mut AsyncAppContext,
) -> Result<Value> {
let tailwind_user_settings = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
.and_then(|s| s.settings.clone())
.unwrap_or_default()
})?;
Expand Down
13 changes: 4 additions & 9 deletions crates/languages/src/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ use http_client::github::{build_asset_url, AssetKind, GitHubLspBinaryVersion};
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::{CodeActionKind, LanguageServerBinary};
use node_runtime::NodeRuntime;
use project::project_settings::ProjectSettings;
use project::lsp_store::language_server_settings;
use project::ContextProviderWithTasks;
use serde_json::{json, Value};
use settings::Settings;
use smol::{fs, io::BufReader, stream::StreamExt};
use std::{
any::Any,
Expand Down Expand Up @@ -236,13 +235,11 @@ impl LspAdapter for TypeScriptLspAdapter {

async fn workspace_configuration(
self: Arc<Self>,
_: &Arc<dyn LspAdapterDelegate>,
delegate: &Arc<dyn LspAdapterDelegate>,
cx: &mut AsyncAppContext,
) -> Result<Value> {
let override_options = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
.and_then(|s| s.initialization_options.clone())
})?;
if let Some(options) = override_options {
Expand Down Expand Up @@ -334,9 +331,7 @@ impl LspAdapter for EsLintLspAdapter {
let workspace_root = delegate.worktree_root_path();

let eslint_user_settings = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
.and_then(|s| s.settings.clone())
.unwrap_or_default()
})?;
Expand Down
24 changes: 6 additions & 18 deletions crates/languages/src/vtsls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ use gpui::AsyncAppContext;
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
use lsp::{CodeActionKind, LanguageServerBinary};
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 settings::{Settings, SettingsLocation};
use std::{
any::Any,
ffi::OsString,
Expand Down Expand Up @@ -75,10 +74,7 @@ impl LspAdapter for VtslsLspAdapter {
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let configured_binary = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(SERVER_NAME)
.and_then(|s| s.binary.clone())
language_server_settings(delegate, SERVER_NAME, cx).and_then(|s| s.binary.clone())
});

match configured_binary {
Expand Down Expand Up @@ -270,26 +266,18 @@ impl LspAdapter for VtslsLspAdapter {

async fn workspace_configuration(
self: Arc<Self>,
adapter: &Arc<dyn LspAdapterDelegate>,
delegate: &Arc<dyn LspAdapterDelegate>,
cx: &mut AsyncAppContext,
) -> Result<Value> {
let override_options = cx.update(|cx| {
ProjectSettings::get(
Some(SettingsLocation {
worktree_id: adapter.worktree_id(),
path: adapter.worktree_root_path(),
}),
cx,
)
.lsp
.get(SERVER_NAME)
.and_then(|s| s.initialization_options.clone())
language_server_settings(delegate.as_ref(), SERVER_NAME, cx)
.and_then(|s| s.initialization_options.clone())
})?;
if let Some(options) = override_options {
return Ok(options);
}
let mut initialization_options = self
.initialization_options(adapter)
.initialization_options(delegate)
.await
.map(|o| o.unwrap())?;

Expand Down
12 changes: 4 additions & 8 deletions crates/languages/src/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use language::{
};
use lsp::LanguageServerBinary;
use node_runtime::NodeRuntime;
use project::project_settings::ProjectSettings;
use project::lsp_store::language_server_settings;
use serde_json::Value;
use settings::{Settings, SettingsLocation};
use smol::fs;
Expand Down Expand Up @@ -44,14 +44,12 @@ impl LspAdapter for YamlLspAdapter {

async fn check_if_user_installed(
&self,
_delegate: &dyn LspAdapterDelegate,
delegate: &dyn LspAdapterDelegate,
cx: &AsyncAppContext,
) -> Option<LanguageServerBinary> {
let configured_binary = cx
.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
language_server_settings(delegate, Self::SERVER_NAME, cx)
.and_then(|s| s.binary.clone())
})
.ok()??;
Expand Down Expand Up @@ -147,9 +145,7 @@ impl LspAdapter for YamlLspAdapter {
let mut options = serde_json::json!({"[yaml]": {"editor.tabSize": tab_size}});

let project_options = cx.update(|cx| {
ProjectSettings::get_global(cx)
.lsp
.get(Self::SERVER_NAME)
language_server_settings(delegate.as_ref(), Self::SERVER_NAME, cx)
.and_then(|s| s.initialization_options.clone())
})?;
if let Some(override_options) = project_options {
Expand Down
19 changes: 18 additions & 1 deletion crates/project/src/lsp_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
environment::ProjectEnvironment,
lsp_command::{self, *},
lsp_ext_command,
project_settings::ProjectSettings,
project_settings::{LspSettings, ProjectSettings},
relativize_path, resolve_path,
worktree_store::{WorktreeStore, WorktreeStoreEvent},
yarn::YarnPathStore,
Expand Down Expand Up @@ -7035,6 +7035,23 @@ impl HttpClient for BlockedHttpClient {
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]
impl LspAdapterDelegate for ProjectLspAdapterDelegate {
fn show_notification(&self, message: &str, cx: &mut AppContext) {
Expand Down

0 comments on commit 2601b47

Please sign in to comment.