settings_content: Fix globally excluded language servers starting (#60984)

Closes https://github.com/zed-industries/zed/issues/60763

Follow-up to #60000. Global language server exclusions were added to
per-language settings without removing an explicit enable for the same
server, allowing it to still start.

For example, this setting should disable `vtsls` for every language:

```json
{
  "language_servers": ["!vtsls", "..."]
}
```

However, TypeScript’s default configuration explicitly enables `vtsls`,
causing it to still start.

Release Notes:

- Fixed language servers starting despite being disabled globally.
This commit is contained in:
Smit Barmase authored and GitHub committed 2026-07-14 17:15:05 +00:00
1 parent ef2430c8f3
commit ba0eea3f49
1 file changed
+55
+55
View File
@@ -67,6 +67,12 @@ impl merge_from::MergeFrom for AllLanguageSettingsContent {
language_settings.merge_from(&other.defaults);
if let Some(mut language_server_overrides) = language_server_overrides {
if let Some(disabled) = &globally_disabled_servers {
for disabled_server in disabled {
if let Some(enabled_server) = disabled_server.strip_prefix('!') {
language_server_overrides.retain(|entry| entry != enabled_server);
}
}
let insert_before = language_server_overrides
.iter()
.position(|entry| entry == REST_OF_LANGUAGE_SERVERS)
@@ -1327,6 +1333,55 @@ mod test {
);
}
#[test]
fn test_global_language_server_disable_overrides_per_language_enable() {
let mut base = AllLanguageSettingsContent {
defaults: LanguageSettingsContent {
language_servers: Some(vec![REST_OF_LANGUAGE_SERVERS.into()]),
..LanguageSettingsContent::default()
},
languages: LanguageToSettingsMap(
[(
"TypeScript".into(),
LanguageSettingsContent {
language_servers: Some(vec![
"!typescript-language-server".into(),
"vtsls".into(),
REST_OF_LANGUAGE_SERVERS.into(),
]),
..LanguageSettingsContent::default()
},
)]
.into_iter()
.collect(),
),
..AllLanguageSettingsContent::default()
};
let user = AllLanguageSettingsContent {
defaults: LanguageSettingsContent {
language_servers: Some(vec!["!vtsls".into(), REST_OF_LANGUAGE_SERVERS.into()]),
..LanguageSettingsContent::default()
},
..AllLanguageSettingsContent::default()
};
base.merge_from(&user);
let expected = vec![
"!typescript-language-server".to_string(),
"!vtsls".to_string(),
REST_OF_LANGUAGE_SERVERS.to_string(),
];
assert_eq!(
base.languages
.0
.get("TypeScript")
.and_then(|settings| settings.language_servers.as_deref()),
Some(expected.as_slice()),
);
}
#[test]
fn test_language_servers_merge_no_per_language_config_uses_global() {
let mut base = AllLanguageSettingsContent {