From ce78317a559702a1070d15891dfcb1621289cb28 Mon Sep 17 00:00:00 2001 From: Bennet Bo Fenner Date: Thu, 16 Apr 2026 13:01:16 +0200 Subject: [PATCH] Fix project group not being removed from sidebar when closing project (#54052) This fixes an issue where closing a project would not remove it from the sidebar, e.g. https://github.com/user-attachments/assets/286abf53-061c-4ff4-8697-41babd73191a Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A --- crates/zed/src/zed.rs | 60 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 48d6501f737155ad96bfc2f0d865c5a19b186c7e..c3c02b83cbc4bbdd6d10b59af4c3fac652a9599c 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1088,11 +1088,12 @@ fn register_actions( }) .register_action({ let app_state = app_state.clone(); - move |_workspace, _: &CloseProject, window, cx| { + move |workspace, _: &CloseProject, window, cx| { let Some(window_handle) = window.window_handle().downcast::() else { return; }; let app_state = app_state.clone(); + let old_group_key = workspace.project_group_key(cx); cx.spawn_in(window, async move |this, cx| { let should_continue = this .update_in(cx, |workspace, window, cx| { @@ -1131,7 +1132,11 @@ fn register_actions( }, ) })?; - task.await + task.await?; + window_handle.update(cx, |mw, window, cx| { + mw.remove_project_group(&old_group_key, window, cx) + })?.await.log_err(); + Ok::<(), anyhow::Error>(()) } else { Ok(()) } @@ -6446,4 +6451,55 @@ mod tests { }) .unwrap(); } + + #[gpui::test] + async fn test_close_project_removes_project_group(cx: &mut TestAppContext) { + use util::path_list::PathList; + use workspace::{OpenMode, ProjectGroupKey}; + + let app_state = init_test(cx); + app_state + .fs + .as_fake() + .insert_tree(path!("/my-project"), json!({})) + .await; + + let workspace::OpenResult { window, .. } = cx + .update(|cx| { + workspace::Workspace::new_local( + vec![path!("/my-project").into()], + app_state.clone(), + None, + None, + None, + OpenMode::Activate, + cx, + ) + }) + .await + .unwrap(); + + window.update(cx, |mw, _, cx| mw.open_sidebar(cx)).unwrap(); + cx.background_executor.run_until_parked(); + + let project_key = ProjectGroupKey::new(None, PathList::new(&[path!("/my-project")])); + let keys = window + .read_with(cx, |mw, _| mw.project_group_keys()) + .unwrap(); + assert_eq!( + keys, + vec![project_key], + "project group should exist before CloseProject: {keys:?}" + ); + + cx.dispatch_action(window.into(), CloseProject); + + let keys = window + .read_with(cx, |mw, _| mw.project_group_keys()) + .unwrap(); + assert!( + keys.is_empty(), + "project group should be removed after CloseProject: {keys:?}" + ); + } }