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.
This commit is contained in:
ishaksebsib 2026-03-08 20:48:08 +03:00 committed by GitHub
parent 598f8ac486
commit 8762b7f503
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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<Workspace>,
) {
let existing = workspace.items_of_type::<Editor>(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::<MultiWorkspace>().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());