From 351914f4bd783fa2dc4fcddf02f54c51afedeb8d Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 23 Jan 2024 11:34:51 +0200 Subject: [PATCH] Clean up LSP servers on worktree release --- crates/gpui/src/text_system.rs | 4 ++ crates/project/src/prettier_support.rs | 6 ++- crates/project/src/project.rs | 53 +++++++++++++++++++++++++- crates/workspace/src/workspace.rs | 3 +- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/crates/gpui/src/text_system.rs b/crates/gpui/src/text_system.rs index 6cc56e306b3e0d19f11ea4d8fe72a4bee18c3daa..a43b96ef908fea57a795db465161831a3dc73170 100644 --- a/crates/gpui/src/text_system.rs +++ b/crates/gpui/src/text_system.rs @@ -70,6 +70,10 @@ impl TextSystem { /// Get a list of all available font names from the operating system. pub fn all_font_names(&self) -> Vec { + eprintln!( + "~~~~~~~~~~~~~ all_font_names called {}", + std::backtrace::Backtrace::capture() + ); let mut names: BTreeSet<_> = self .platform_text_system .all_font_names() diff --git a/crates/project/src/prettier_support.rs b/crates/project/src/prettier_support.rs index c176c79a91f2e76ae84c6fcb25d95fd9b8568106..098fe2b39a996f2e21436a7604896161f63fb7e1 100644 --- a/crates/project/src/prettier_support.rs +++ b/crates/project/src/prettier_support.rs @@ -16,7 +16,7 @@ use language::{ language_settings::{Formatter, LanguageSettings}, Buffer, Language, LanguageServerName, LocalFile, }; -use lsp::LanguageServerId; +use lsp::{LanguageServer, LanguageServerId}; use node_runtime::NodeRuntime; use prettier::Prettier; use util::{paths::DEFAULT_PRETTIER_DIR, ResultExt, TryFutureExt}; @@ -212,6 +212,10 @@ impl PrettierInstance { }, }) } + + pub async fn server(&self) -> Option> { + self.prettier.clone()?.await.ok()?.server().cloned() + } } fn start_default_prettier( diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index de69a93ba6fd90047cd312f220ec4fb7545aa89e..1f5a5a8c642bd94ef3f5d44781e28c50998deb90 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -632,7 +632,7 @@ impl Project { let copilot_lsp_subscription = Copilot::global(cx).map(|copilot| subscribe_for_copilot_events(&copilot, cx)); Self { - worktrees: Default::default(), + worktrees: Vec::new(), buffer_ordered_messages_tx: tx, collaborators: Default::default(), next_buffer_id: 0, @@ -973,7 +973,7 @@ impl Project { } // Start all the newly-enabled language servers. - for (worktree, language) in language_servers_to_start { + for (worktree, language) in dbg!(language_servers_to_start) { let worktree_path = worktree.read(cx).abs_path(); self.start_language_servers(&worktree, worktree_path, language, cx); } @@ -6370,6 +6370,55 @@ impl Project { } pub fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut ModelContext) { + let mut servers_to_remove = HashMap::default(); + let mut servers_to_preserve = HashSet::default(); + for ((worktree_id, server_name), &server_id) in &self.language_server_ids { + if worktree_id == &id_to_remove { + servers_to_remove.insert(server_id, server_name.clone()); + } else { + servers_to_preserve.insert(server_id); + } + } + servers_to_remove.retain(|server_id, _| !servers_to_preserve.contains(server_id)); + for (server_id_to_remove, server_name) in servers_to_remove { + self.language_server_ids + .remove(&(id_to_remove, server_name)); + self.language_server_statuses.remove(&server_id_to_remove); + self.last_workspace_edits_by_language_server + .remove(&server_id_to_remove); + self.language_servers.remove(&server_id_to_remove); + cx.emit(Event::LanguageServerRemoved(server_id_to_remove)); + } + + let mut prettier_instances_to_clean = FuturesUnordered::new(); + if let Some(prettier_paths) = self.prettiers_per_worktree.remove(&id_to_remove) { + for path in prettier_paths.iter().flatten() { + if let Some(prettier_instance) = self.prettier_instances.remove(path) { + prettier_instances_to_clean.push(async move { + prettier_instance + .server() + .await + .map(|server| server.server_id()) + }); + } + } + } + cx.spawn(|project, mut cx| async move { + while let Some(prettier_server_id) = prettier_instances_to_clean.next().await { + if let Some(prettier_server_id) = prettier_server_id { + project + .update(&mut cx, |project, cx| { + project + .supplementary_language_servers + .remove(&prettier_server_id); + cx.emit(Event::LanguageServerRemoved(prettier_server_id)); + }) + .ok(); + } + } + }) + .detach(); + self.worktrees.retain(|worktree| { if let Some(worktree) = worktree.upgrade() { let id = worktree.read(cx).id(); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index a552d9c5af645d5a76ba8010b52dae79139b022a..c51852b5117cca99f7e3058b7a179d1b1688c52e 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1355,7 +1355,7 @@ impl Workspace { Some(visible) => match this .update(&mut cx, |this, cx| { Workspace::project_path_for_path( - this.project.clone(), + dbg!(this.project.clone()), abs_path, visible, cx, @@ -1368,6 +1368,7 @@ impl Workspace { }, None => None, }; + dbg!(&project_path); let this = this.clone(); let abs_path = abs_path.clone();