Refactor LSP restart logic

Instead of storing `initialization_options` in every LSP adapter as
before, store previous LSP settings in `Project` entirely.

This way, we can later have use multiple different project
configurations per single LSP with its associated adapter.

co-authored-by: Max Brunsfeld <max@zed.dev>
This commit is contained in:
Kirill Bulatov 2023-07-11 21:29:47 +03:00
parent efe8b8b6d0
commit 4b4d049b0a
4 changed files with 25 additions and 8 deletions

View file

@ -369,6 +369,7 @@ mod tests {
editor::init(cx); editor::init(cx);
workspace::init(app_state.clone(), cx); workspace::init(app_state.clone(), cx);
init(cx); init(cx);
Project::init_settings(cx);
app_state app_state
}) })
} }

View file

@ -50,7 +50,7 @@ use lsp::{
}; };
use lsp_command::*; use lsp_command::*;
use postage::watch; use postage::watch;
use project_settings::ProjectSettings; use project_settings::{LspSettings, ProjectSettings};
use rand::prelude::*; use rand::prelude::*;
use search::SearchQuery; use search::SearchQuery;
use serde::Serialize; use serde::Serialize;
@ -149,6 +149,7 @@ pub struct Project {
_maintain_workspace_config: Task<()>, _maintain_workspace_config: Task<()>,
terminals: Terminals, terminals: Terminals,
copilot_enabled: bool, copilot_enabled: bool,
current_lsp_settings: HashMap<Arc<str>, LspSettings>,
} }
struct DelayedDebounced { struct DelayedDebounced {
@ -614,6 +615,7 @@ impl Project {
local_handles: Vec::new(), local_handles: Vec::new(),
}, },
copilot_enabled: Copilot::global(cx).is_some(), copilot_enabled: Copilot::global(cx).is_some(),
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
} }
}) })
} }
@ -706,6 +708,7 @@ impl Project {
local_handles: Vec::new(), local_handles: Vec::new(),
}, },
copilot_enabled: Copilot::global(cx).is_some(), copilot_enabled: Copilot::global(cx).is_some(),
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
}; };
for worktree in worktrees { for worktree in worktrees {
let _ = this.add_worktree(&worktree, cx); let _ = this.add_worktree(&worktree, cx);
@ -779,7 +782,9 @@ impl Project {
let mut language_servers_to_stop = Vec::new(); let mut language_servers_to_stop = Vec::new();
let mut language_servers_to_restart = Vec::new(); let mut language_servers_to_restart = Vec::new();
let languages = self.languages.to_vec(); let languages = self.languages.to_vec();
let project_settings = settings::get::<ProjectSettings>(cx).clone();
let new_lsp_settings = settings::get::<ProjectSettings>(cx).lsp.clone();
let current_lsp_settings = &self.current_lsp_settings;
for (worktree_id, started_lsp_name) in self.language_server_ids.keys() { for (worktree_id, started_lsp_name) in self.language_server_ids.keys() {
let language = languages.iter().find_map(|l| { let language = languages.iter().find_map(|l| {
let adapter = l let adapter = l
@ -796,16 +801,25 @@ impl Project {
if !language_settings(Some(language), file.as_ref(), cx).enable_language_server { if !language_settings(Some(language), file.as_ref(), cx).enable_language_server {
language_servers_to_stop.push((*worktree_id, started_lsp_name.clone())); language_servers_to_stop.push((*worktree_id, started_lsp_name.clone()));
} else if let Some(worktree) = worktree { } else if let Some(worktree) = worktree {
let new_lsp_settings = project_settings let server_name = &adapter.name.0;
.lsp match (
.get(&adapter.name.0) current_lsp_settings.get(server_name),
.and_then(|s| s.initialization_options.as_ref()); new_lsp_settings.get(server_name),
if adapter.initialization_options.as_ref() != new_lsp_settings { ) {
language_servers_to_restart.push((worktree, Arc::clone(language))); (None, None) => {}
(Some(_), None) | (None, Some(_)) => {
language_servers_to_restart.push((worktree, Arc::clone(language)));
}
(Some(current_lsp_settings), Some(new_lsp_settings)) => {
if current_lsp_settings != new_lsp_settings {
language_servers_to_restart.push((worktree, Arc::clone(language)));
}
}
} }
} }
} }
} }
self.current_lsp_settings = new_lsp_settings;
// Stop all newly-disabled language servers. // Stop all newly-disabled language servers.
for (worktree_id, adapter_name) in language_servers_to_stop { for (worktree_id, adapter_name) in language_servers_to_stop {

View file

@ -907,6 +907,7 @@ mod tests {
let params = cx.update(AppState::test); let params = cx.update(AppState::test);
cx.update(|cx| { cx.update(|cx| {
theme::init((), cx); theme::init((), cx);
Project::init_settings(cx);
language::init(cx); language::init(cx);
}); });

View file

@ -2316,6 +2316,7 @@ mod tests {
cx.set_global(SettingsStore::test(cx)); cx.set_global(SettingsStore::test(cx));
theme::init((), cx); theme::init((), cx);
crate::init_settings(cx); crate::init_settings(cx);
Project::init_settings(cx);
}); });
} }