From 821a4880bd2c601a494db0e564ce941158638e8c Mon Sep 17 00:00:00 2001 From: Dino Date: Mon, 27 Oct 2025 15:58:41 +0000 Subject: [PATCH] cli: Use --wait to prefer focused window (#41051) Introduce a new `prefer_focused_window` field to the `workspace::OpenOptions` struct that, when provided, will make it so that Zed opens the provided path in the currently focused window. This will now automatically be set to true when the `--wait` flag is used with the CLI. Closes #40551 Release Notes: - Improved the `--wait` flag in Zed's CLI so as to always open the provided file in the currently focused window --------- Co-authored-by: Conrad Irwin --- crates/workspace/src/workspace.rs | 3 +- crates/zed/src/zed.rs | 59 +++++++++++++++++++++++++++++ crates/zed/src/zed/open_listener.rs | 1 + 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 6933a6bcda8baffee618c219c3b05263f11738f5..e34f9f628507681b4977c2abbe716d83d8bf97c9 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -7323,6 +7323,7 @@ pub struct OpenOptions { pub visible: Option, pub focus: Option, pub open_new_workspace: Option, + pub prefer_focused_window: bool, pub replace_window: Option>, pub env: Option>, } @@ -7379,7 +7380,7 @@ pub fn open_paths( })?; if open_options.open_new_workspace.is_none() - && existing.is_none() + && (existing.is_none() || open_options.prefer_focused_window) && all_metadatas.iter().all(|file| !file.is_dir) { cx.update(|cx| { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index ee29e93da38e4de6d32a00f11b171401d8d4f2c4..8a0afad60890eba0469d1ae60f43af45bd36ffb4 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -5086,4 +5086,63 @@ mod tests { "BUG FOUND: Project settings were overwritten when opening via command - original custom content was lost" ); } + + #[gpui::test] + async fn test_prefer_focused_window(cx: &mut gpui::TestAppContext) { + let app_state = init_test(cx); + let paths = [PathBuf::from(path!("/dir/document.txt"))]; + + app_state + .fs + .as_fake() + .insert_tree( + path!("/dir"), + json!({ + "document.txt": "Some of the documentation's content." + }), + ) + .await; + + let project_a = Project::test(app_state.fs.clone(), [path!("/dir").as_ref()], cx).await; + let window_a = + cx.add_window(|window, cx| Workspace::test_new(project_a.clone(), window, cx)); + + let project_b = Project::test(app_state.fs.clone(), [path!("/dir").as_ref()], cx).await; + let window_b = + cx.add_window(|window, cx| Workspace::test_new(project_b.clone(), window, cx)); + + let project_c = Project::test(app_state.fs.clone(), [path!("/dir").as_ref()], cx).await; + let window_c = + cx.add_window(|window, cx| Workspace::test_new(project_c.clone(), window, cx)); + + for window in [window_a, window_b, window_c] { + let _ = cx.update_window(*window, |_, window, _| { + window.activate_window(); + }); + + cx.update(|cx| { + let open_options = OpenOptions { + prefer_focused_window: true, + ..Default::default() + }; + + workspace::open_paths(&paths, app_state.clone(), open_options, cx) + }) + .await + .unwrap(); + + cx.update_window(*window, |_, window, _| assert!(window.is_window_active())) + .unwrap(); + + let _ = window.read_with(cx, |workspace, cx| { + let pane = workspace.active_pane().read(cx); + let project_path = pane.active_item().unwrap().project_path(cx).unwrap(); + + assert_eq!( + project_path.path.as_ref().as_std_path().to_str().unwrap(), + path!("document.txt") + ) + }); + } + } } diff --git a/crates/zed/src/zed/open_listener.rs b/crates/zed/src/zed/open_listener.rs index 618849b3474e60f8a3737facf7c502f6e5f1cf52..855c8d39e7328a7246774de931404d25dd073f6f 100644 --- a/crates/zed/src/zed/open_listener.rs +++ b/crates/zed/src/zed/open_listener.rs @@ -531,6 +531,7 @@ async fn open_local_workspace( workspace::OpenOptions { open_new_workspace: effective_open_new_workspace, replace_window, + prefer_focused_window: wait, env: env.cloned(), ..Default::default() },