From fff65968bfb30bda31321a832ef2cd67d474cc8f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 6 Jul 2023 23:08:04 +0300 Subject: [PATCH] Restart LSP server on initialization options change --- crates/project/src/project.rs | 27 ++++++++++++++++++++++----- crates/workspace/src/workspace.rs | 1 + 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index d69e5cf21e..81db0c7ed7 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -777,20 +777,32 @@ impl Project { } let mut language_servers_to_stop = Vec::new(); + let mut language_servers_to_restart = Vec::new(); let languages = self.languages.to_vec(); + let project_settings = settings::get::(cx).clone(); for (worktree_id, started_lsp_name) in self.language_server_ids.keys() { - let language = languages.iter().find(|l| { - l.lsp_adapters() + let language = languages.iter().find_map(|l| { + let adapter = l + .lsp_adapters() .iter() - .any(|adapter| &adapter.name == started_lsp_name) + .find(|adapter| &adapter.name == started_lsp_name)?; + Some((l, adapter)) }); - if let Some(language) = language { + if let Some((language, adapter)) = language { let worktree = self.worktree_for_id(*worktree_id, cx); - let file = worktree.and_then(|tree| { + let file = worktree.as_ref().and_then(|tree| { tree.update(cx, |tree, cx| tree.root_file(cx).map(|f| f as _)) }); if !language_settings(Some(language), file.as_ref(), cx).enable_language_server { language_servers_to_stop.push((*worktree_id, started_lsp_name.clone())); + } else if let Some(worktree) = worktree { + let new_lsp_settings = project_settings + .lsp + .get(&adapter.name.0) + .and_then(|s| s.initialization_options.as_ref()); + if adapter.initialization_options.as_ref() != new_lsp_settings { + language_servers_to_restart.push((worktree, Arc::clone(language))); + } } } } @@ -807,6 +819,11 @@ impl Project { self.start_language_servers(&worktree, worktree_path, language, cx); } + // Restart all language servers with changed initialization options. + for (worktree, language) in language_servers_to_restart { + self.restart_language_servers(worktree, language, cx); + } + if !self.copilot_enabled && Copilot::global(cx).is_some() { self.copilot_enabled = true; for buffer in self.opened_buffers.values() { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 60aefe4213..01d80d141c 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -4809,6 +4809,7 @@ mod tests { theme::init((), cx); language::init(cx); crate::init_settings(cx); + Project::init_settings(cx); }); } }