From 8762b7f503fda985f481ccd301960cf01adbecb8 Mon Sep 17 00:00:00 2001 From: ishaksebsib <121272992+ishaksebsib@users.noreply.github.com> Date: Sun, 8 Mar 2026 20:48:08 +0300 Subject: [PATCH] Reuse existing bundled file editors (#51053) Closes #46837 Reuse the existing read-only bundled editor when opening default settings or default key bindings again, instead of creating a duplicate tab each time. Also adds a regression test covering repeated `OpenDefaultSettings` dispatches. ### Before https://github.com/user-attachments/assets/ac2477b0-dc57-451c-a400-667c3613da2c ### After https://github.com/user-attachments/assets/309fbd32-6dad-40a0-a864-b638a583ef52 Before you mark this PR as ready for review, make sure that you have: - [x] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - Fixed default settings and default key bindings reopening duplicate tabs instead of reusing the existing tab. --- crates/zed/src/zed.rs | 66 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 562786fb3f01ff4c0781319e155bc47fda6a4822..079a78225c248e341121f1980a368b37f85eea84 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -2008,13 +2008,29 @@ fn open_local_file( } fn open_bundled_file( - workspace: &Workspace, + workspace: &mut Workspace, text: Cow<'static, str>, title: &'static str, language: &'static str, window: &mut Window, cx: &mut Context, ) { + let existing = workspace.items_of_type::(cx).find(|editor| { + editor.read_with(cx, |editor, cx| { + editor.read_only(cx) + && editor.title(cx).as_ref() == title + && editor + .buffer() + .read(cx) + .as_singleton() + .is_some_and(|buffer| buffer.read(cx).file().is_none()) + }) + }); + if let Some(existing) = existing { + workspace.activate_item(&existing, true, true, window, cx); + return; + } + let language = workspace.app_state().languages.language_for_name(language); cx.spawn_in(window, async move |workspace, cx| { let language = language.await.log_err(); @@ -4965,6 +4981,54 @@ mod tests { ); } + #[gpui::test] + async fn test_bundled_files_reuse_existing_editor(cx: &mut TestAppContext) { + let app_state = init_test(cx); + cx.update(init); + + let project = Project::test(app_state.fs.clone(), [], cx).await; + let _window = cx.add_window(|window, cx| MultiWorkspace::test_new(project, window, cx)); + + cx.update(|cx| { + cx.dispatch_action(&OpenDefaultSettings); + }); + cx.run_until_parked(); + + let multi_workspace = cx.windows()[0].downcast::().unwrap(); + let first_item_id = multi_workspace + .update(cx, |multi_workspace, _, cx| { + multi_workspace.workspace().update(cx, |workspace, cx| { + workspace + .active_item(cx) + .expect("default settings should be open") + .item_id() + }) + }) + .unwrap(); + + cx.update(|cx| { + cx.dispatch_action(&OpenDefaultSettings); + }); + cx.run_until_parked(); + + let (second_item_id, item_count) = multi_workspace + .update(cx, |multi_workspace, _, cx| { + multi_workspace.workspace().update(cx, |workspace, cx| { + let pane = workspace.active_pane().read(cx); + ( + pane.active_item() + .expect("default settings should still be open") + .item_id(), + pane.items_len(), + ) + }) + }) + .unwrap(); + + assert_eq!(first_item_id, second_item_id); + assert_eq!(item_count, 1); + } + #[gpui::test] async fn test_bundled_languages(cx: &mut TestAppContext) { let fs = fs::FakeFs::new(cx.background_executor.clone());