mirror of
https://github.com/zed-industries/zed.git
synced 2026-10-19 11:04:06 +00:00
Allow builtin language servers to be disabled by default (#65049)
## Summary This addresses the concern mentioned in https://github.com/zed-industries/zed/pull/65030#pullrequestreview-5380076060 Release Notes: - N/A
This commit is contained in:
parent
2a97fbf22b
commit
35bba8eef7
9 changed files with 40 additions and 21 deletions
|
|
@ -34,7 +34,7 @@ pub fn register_fake_definition_server(
|
|||
arguments: Vec::new(),
|
||||
env: None,
|
||||
},
|
||||
enabled_by_default: true,
|
||||
opt_in_languages: Default::default(),
|
||||
capabilities: lsp::ServerCapabilities {
|
||||
definition_provider: Some(lsp::OneOf::Left(true)),
|
||||
type_definition_provider: Some(lsp::TypeDefinitionProviderCapability::Simple(true)),
|
||||
|
|
|
|||
|
|
@ -334,7 +334,6 @@ pub struct CachedLspAdapter {
|
|||
pub disk_based_diagnostic_sources: Vec<String>,
|
||||
pub disk_based_diagnostics_progress_token: Option<String>,
|
||||
language_ids: HashMap<LanguageName, String>,
|
||||
pub enabled_by_default: bool,
|
||||
pub adapter: Arc<dyn LspAdapter>,
|
||||
cached_binary: Arc<ServerBinaryCache>,
|
||||
}
|
||||
|
|
@ -352,7 +351,6 @@ impl Debug for CachedLspAdapter {
|
|||
&self.disk_based_diagnostics_progress_token,
|
||||
)
|
||||
.field("language_ids", &self.language_ids)
|
||||
.field("enabled_by_default", &self.enabled_by_default)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
|
@ -363,14 +361,12 @@ impl CachedLspAdapter {
|
|||
let disk_based_diagnostic_sources = adapter.disk_based_diagnostic_sources();
|
||||
let disk_based_diagnostics_progress_token = adapter.disk_based_diagnostics_progress_token();
|
||||
let language_ids = adapter.language_ids();
|
||||
let enabled_by_default = adapter.enabled_by_default();
|
||||
|
||||
Arc::new(CachedLspAdapter {
|
||||
name,
|
||||
disk_based_diagnostic_sources,
|
||||
disk_based_diagnostics_progress_token,
|
||||
language_ids,
|
||||
enabled_by_default,
|
||||
adapter,
|
||||
cached_binary: Default::default(),
|
||||
})
|
||||
|
|
@ -380,6 +376,12 @@ impl CachedLspAdapter {
|
|||
self.adapter.name()
|
||||
}
|
||||
|
||||
/// Returns whether the language server only starts for the given language
|
||||
/// when it is explicitly listed in the `language_servers` setting.
|
||||
pub fn is_opt_in_for(&self, language: &LanguageName) -> bool {
|
||||
self.adapter.is_opt_in_for(language)
|
||||
}
|
||||
|
||||
pub async fn get_language_server_command(
|
||||
self: Arc<Self>,
|
||||
delegate: Arc<dyn LspAdapterDelegate>,
|
||||
|
|
@ -660,10 +662,11 @@ pub trait LspAdapter: 'static + Send + Sync + DynLspInstaller {
|
|||
HashMap::default()
|
||||
}
|
||||
|
||||
/// Whether the `...` wildcard in the `language_servers` setting includes this
|
||||
/// language server. If `false`, it only starts when listed explicitly.
|
||||
fn enabled_by_default(&self) -> bool {
|
||||
true
|
||||
/// Whether the `...` wildcard in the `language_servers` setting excludes this
|
||||
/// language server for the given language, so that it only starts when
|
||||
/// listed explicitly.
|
||||
fn is_opt_in_for(&self, _language: &LanguageName) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Support custom initialize params.
|
||||
|
|
@ -933,7 +936,7 @@ pub struct FakeLspAdapter {
|
|||
pub disk_based_diagnostics_progress_token: Option<String>,
|
||||
pub disk_based_diagnostics_sources: Vec<String>,
|
||||
pub language_server_binary: LanguageServerBinary,
|
||||
pub enabled_by_default: bool,
|
||||
pub opt_in_languages: HashSet<LanguageName>,
|
||||
|
||||
pub capabilities: lsp::ServerCapabilities,
|
||||
pub initializer: Option<Box<dyn 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer)>>,
|
||||
|
|
@ -1561,7 +1564,7 @@ impl Default for FakeLspAdapter {
|
|||
arguments: vec![],
|
||||
env: Default::default(),
|
||||
},
|
||||
enabled_by_default: true,
|
||||
opt_in_languages: HashSet::default(),
|
||||
label_for_completion: None,
|
||||
}
|
||||
}
|
||||
|
|
@ -1664,8 +1667,8 @@ impl LspAdapter for FakeLspAdapter {
|
|||
label_for_completion(item, language)
|
||||
}
|
||||
|
||||
fn enabled_by_default(&self) -> bool {
|
||||
self.enabled_by_default
|
||||
fn is_opt_in_for(&self, language: &LanguageName) -> bool {
|
||||
self.opt_in_languages.contains(language)
|
||||
}
|
||||
|
||||
fn is_extension(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -305,12 +305,12 @@ impl LspAdapter for ExtensionLspAdapter {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn enabled_by_default(&self) -> bool {
|
||||
fn is_opt_in_for(&self, language: &LanguageName) -> bool {
|
||||
self.extension
|
||||
.manifest()
|
||||
.language_servers
|
||||
.get(&self.language_server_id)
|
||||
.is_none_or(|server| !server.is_opt_in_for(&self.language_name))
|
||||
.is_some_and(|server| server.is_opt_in_for(language))
|
||||
}
|
||||
|
||||
async fn initialization_options(
|
||||
|
|
|
|||
|
|
@ -372,6 +372,10 @@ impl LspAdapter for TyLspAdapter {
|
|||
Self::SERVER_NAME
|
||||
}
|
||||
|
||||
fn is_opt_in_for(&self, language: &LanguageName) -> bool {
|
||||
language == "Python"
|
||||
}
|
||||
|
||||
async fn label_for_completion(
|
||||
&self,
|
||||
item: &lsp::CompletionItem,
|
||||
|
|
@ -665,6 +669,10 @@ impl LspAdapter for PyrightLspAdapter {
|
|||
Self::SERVER_NAME
|
||||
}
|
||||
|
||||
fn is_opt_in_for(&self, language: &LanguageName) -> bool {
|
||||
language == "Python"
|
||||
}
|
||||
|
||||
async fn initialization_options(
|
||||
self: Arc<Self>,
|
||||
_: &Arc<dyn LspAdapterDelegate>,
|
||||
|
|
@ -1816,6 +1824,10 @@ impl LspAdapter for PyLspAdapter {
|
|||
Self::SERVER_NAME
|
||||
}
|
||||
|
||||
fn is_opt_in_for(&self, language: &LanguageName) -> bool {
|
||||
language == "Python"
|
||||
}
|
||||
|
||||
async fn process_completions(&self, items: &mut [lsp::CompletionItem]) {
|
||||
for item in items {
|
||||
let is_named_argument = item.label.ends_with('=');
|
||||
|
|
|
|||
|
|
@ -875,6 +875,10 @@ impl LspAdapter for TypeScriptLspAdapter {
|
|||
(LanguageName::new_static("TSX"), "typescriptreact".into()),
|
||||
])
|
||||
}
|
||||
|
||||
fn is_opt_in_for(&self, language: &LanguageName) -> bool {
|
||||
matches!(language.as_ref(), "TypeScript" | "JavaScript" | "TSX")
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_cached_ts_server_binary(
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ impl LanguageServerTree {
|
|||
let available_lsp_adapters = self.languages.lsp_adapters(language_name);
|
||||
let available_language_servers = available_lsp_adapters
|
||||
.iter()
|
||||
.filter(|lsp_adapter| lsp_adapter.enabled_by_default)
|
||||
.filter(|lsp_adapter| !lsp_adapter.is_opt_in_for(language_name))
|
||||
.map(|lsp_adapter| lsp_adapter.name.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
|
|
|||
|
|
@ -2089,7 +2089,7 @@ async fn test_language_servers_disabled_by_default(cx: &mut gpui::TestAppContext
|
|||
"Rust",
|
||||
FakeLspAdapter {
|
||||
name: "opt-in-server",
|
||||
enabled_by_default: false,
|
||||
opt_in_languages: HashSet::from_iter([LanguageName::new_static("Rust")]),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ In this example:
|
|||
|
||||
The `"..."` entry acts as a wildcard that includes any registered language server you haven't explicitly mentioned. Servers you list by name keep their position, and `"..."` fills in the remaining ones at that point in the list. Servers prefixed with `!` are excluded entirely. This means that if a new language server extension is installed or a new server is registered for a language, `"..."` will automatically include it. If you want full control over which servers are enabled, omit `"..."` — only the servers you list by name will be used.
|
||||
|
||||
Extensions can also mark a language server as [disabled by default](./extensions/languages.md#opt-in-language-servers) for some of its languages. Such servers are never included by `"..."`, regardless of your configuration, and only start when you list them by name, e.g. `["my-alternative-server", "..."]`.
|
||||
Some language servers are disabled by default for some of their languages, e.g. `typescript-language-server` for TypeScript, or `ty` for Python. Extensions can also mark their language servers as [disabled by default](./extensions/languages.md#opt-in-language-servers). Such servers are never included by `"..."`, regardless of your configuration, and only start when you list them by name, e.g. `["my-alternative-server", "..."]`.
|
||||
|
||||
#### Examples
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ Other built-in language servers are:
|
|||
- [Pyright](https://github.com/microsoft/pyright)—The basis for basedpyright.
|
||||
- [PyLSP](https://github.com/python-lsp/python-lsp-server)—A plugin-based language server that integrates with tools like `pycodestyle`, `autopep8`, and `yapf`.
|
||||
|
||||
These are disabled by default, but can be enabled in your settings.
|
||||
These are disabled by default and are not included by `"..."`. Enable them by listing them by name in your settings.
|
||||
|
||||
Configure language servers in Settings ({#kb zed::OpenSettings}) under Languages > Python, or add to your settings file:
|
||||
|
||||
|
|
@ -89,8 +89,8 @@ Configure language servers in Settings ({#kb zed::OpenSettings}) under Languages
|
|||
"languages": {
|
||||
"Python": {
|
||||
"language_servers": [
|
||||
// Enable ty, disable basedpyright, and enable all
|
||||
// other registered language servers (ruff, pylsp, pyright).
|
||||
// Enable ty, disable basedpyright, and enable all other
|
||||
// language servers that are enabled by default (e.g. ruff).
|
||||
"ty",
|
||||
"!basedpyright",
|
||||
"..."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue