diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index ba4c81592d3b6e4030d45cb5da1dc4299673d14a..29684a282476b438e8e60b74e0fccf340cd17edf 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -9174,30 +9174,35 @@ pub async fn find_existing_workspace( let mut open_visible = OpenVisible::All; let mut best_match = None; - if open_options.open_new_workspace != Some(true) { - cx.update(|cx| { - for window in workspace_windows_for_location(location, cx) { - if let Ok(multi_workspace) = window.read(cx) { - for workspace in multi_workspace.workspaces() { - let project = workspace.read(cx).project.read(cx); - let m = project.visibility_for_paths( - abs_paths, - open_options.open_new_workspace == None, - cx, - ); - if m > best_match { - existing = Some((window, workspace.clone())); - best_match = m; - } else if best_match.is_none() - && open_options.open_new_workspace == Some(false) - { - existing = Some((window, workspace.clone())) - } + cx.update(|cx| { + for window in workspace_windows_for_location(location, cx) { + if let Ok(multi_workspace) = window.read(cx) { + for workspace in multi_workspace.workspaces() { + let project = workspace.read(cx).project.read(cx); + let m = project.visibility_for_paths( + abs_paths, + open_options.open_new_workspace == None, + cx, + ); + if m > best_match { + existing = Some((window, workspace.clone())); + best_match = m; + } else if best_match.is_none() && open_options.open_new_workspace == Some(false) + { + existing = Some((window, workspace.clone())) } } } - }); + } + }); + + // With -n, only reuse a window if the path is genuinely contained + // within an existing worktree (don't fall back to any arbitrary window). + if open_options.open_new_workspace == Some(true) && best_match.is_none() { + existing = None; + } + if open_options.open_new_workspace != Some(true) { let all_paths_are_files = existing .as_ref() .and_then(|(_, target_workspace)| { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 293125c0089e0a4315eb9c28f30be5f840bd6052..e572b5de0dd77931e72065fafa8866cd80a8f2fc 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -2667,6 +2667,7 @@ mod tests { .unwrap(); assert_eq!(cx.update(|cx| cx.windows().len()), 1); + // Opening a file inside the existing worktree with -n reuses the window. cx.update(|cx| { open_paths( &[PathBuf::from(path!("/root/dir/c"))], @@ -2680,6 +2681,22 @@ mod tests { }) .await .unwrap(); + assert_eq!(cx.update(|cx| cx.windows().len()), 1); + + // Opening a path NOT in any existing worktree with -n creates a new window. + cx.update(|cx| { + open_paths( + &[PathBuf::from(path!("/root/b"))], + app_state.clone(), + workspace::OpenOptions { + open_new_workspace: Some(true), + ..Default::default() + }, + cx, + ) + }) + .await + .unwrap(); assert_eq!(cx.update(|cx| cx.windows().len()), 2); } @@ -2733,7 +2750,7 @@ mod tests { .unwrap(); assert_eq!(cx.update(|cx| cx.windows().len()), 1); - // Opening a directory with -n creates a new window. + // Opening a directory already in a worktree with -n reuses the window. cx.update(|cx| { open_paths( &[PathBuf::from(path!("/root/dir2"))], @@ -2747,6 +2764,22 @@ mod tests { }) .await .unwrap(); + assert_eq!(cx.update(|cx| cx.windows().len()), 1); + + // Opening a directory NOT in any worktree with -n creates a new window. + cx.update(|cx| { + open_paths( + &[PathBuf::from(path!("/root"))], + app_state.clone(), + workspace::OpenOptions { + open_new_workspace: Some(true), + ..Default::default() + }, + cx, + ) + }) + .await + .unwrap(); assert_eq!(cx.update(|cx| cx.windows().len()), 2); } diff --git a/crates/zed/src/zed/open_listener.rs b/crates/zed/src/zed/open_listener.rs index 0a302291cacc8caa9e0618da00b8d7c6370ccf0e..16d220c56093a2645db9f5bdc3114e16814138ac 100644 --- a/crates/zed/src/zed/open_listener.rs +++ b/crates/zed/src/zed/open_listener.rs @@ -1043,7 +1043,7 @@ mod tests { }) .unwrap(); - // Now open a file inside that workspace, but tell Zed to open a new window + // Opening a file inside the existing worktree with -n reuses the window. open_workspace_file( path!("/root/dir1/file1.txt"), Some(true), @@ -1052,18 +1052,7 @@ mod tests { ) .await; - assert_eq!(cx.windows().len(), 2); - - let multi_workspace_2 = cx.windows()[1].downcast::().unwrap(); - multi_workspace_2 - .update(cx, |multi_workspace, _, cx| { - multi_workspace.workspace().update(cx, |workspace, cx| { - assert!(workspace.active_item_as::(cx).is_some()); - let items = workspace.items(cx).collect::>(); - assert_eq!(items.len(), 1, "Workspace should have two items"); - }); - }) - .unwrap(); + assert_eq!(cx.windows().len(), 1); } #[gpui::test]