Detailed changes
@@ -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)| {
@@ -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);
}
@@ -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::<MultiWorkspace>().unwrap();
- multi_workspace_2
- .update(cx, |multi_workspace, _, cx| {
- multi_workspace.workspace().update(cx, |workspace, cx| {
- assert!(workspace.active_item_as::<Editor>(cx).is_some());
- let items = workspace.items(cx).collect::<Vec<_>>();
- assert_eq!(items.len(), 1, "Workspace should have two items");
- });
- })
- .unwrap();
+ assert_eq!(cx.windows().len(), 1);
}
#[gpui::test]