Skip to content

Commit 66d2cb2

Browse files
authored
Adjust zed -n behavior (#53346)
When there's already a workspace that matches the paths provided, activate that workspace, otherwise create a new window. This is different from the default behavior of always adding to the sidebar. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A
1 parent 2d1137c commit 66d2cb2

File tree

3 files changed

+61
-34
lines changed

3 files changed

+61
-34
lines changed

crates/workspace/src/workspace.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9174,30 +9174,35 @@ pub async fn find_existing_workspace(
91749174
let mut open_visible = OpenVisible::All;
91759175
let mut best_match = None;
91769176

9177-
if open_options.open_new_workspace != Some(true) {
9178-
cx.update(|cx| {
9179-
for window in workspace_windows_for_location(location, cx) {
9180-
if let Ok(multi_workspace) = window.read(cx) {
9181-
for workspace in multi_workspace.workspaces() {
9182-
let project = workspace.read(cx).project.read(cx);
9183-
let m = project.visibility_for_paths(
9184-
abs_paths,
9185-
open_options.open_new_workspace == None,
9186-
cx,
9187-
);
9188-
if m > best_match {
9189-
existing = Some((window, workspace.clone()));
9190-
best_match = m;
9191-
} else if best_match.is_none()
9192-
&& open_options.open_new_workspace == Some(false)
9193-
{
9194-
existing = Some((window, workspace.clone()))
9195-
}
9177+
cx.update(|cx| {
9178+
for window in workspace_windows_for_location(location, cx) {
9179+
if let Ok(multi_workspace) = window.read(cx) {
9180+
for workspace in multi_workspace.workspaces() {
9181+
let project = workspace.read(cx).project.read(cx);
9182+
let m = project.visibility_for_paths(
9183+
abs_paths,
9184+
open_options.open_new_workspace == None,
9185+
cx,
9186+
);
9187+
if m > best_match {
9188+
existing = Some((window, workspace.clone()));
9189+
best_match = m;
9190+
} else if best_match.is_none() && open_options.open_new_workspace == Some(false)
9191+
{
9192+
existing = Some((window, workspace.clone()))
91969193
}
91979194
}
91989195
}
9199-
});
9196+
}
9197+
});
9198+
9199+
// With -n, only reuse a window if the path is genuinely contained
9200+
// within an existing worktree (don't fall back to any arbitrary window).
9201+
if open_options.open_new_workspace == Some(true) && best_match.is_none() {
9202+
existing = None;
9203+
}
92009204

9205+
if open_options.open_new_workspace != Some(true) {
92019206
let all_paths_are_files = existing
92029207
.as_ref()
92039208
.and_then(|(_, target_workspace)| {

crates/zed/src/zed.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2667,6 +2667,7 @@ mod tests {
26672667
.unwrap();
26682668
assert_eq!(cx.update(|cx| cx.windows().len()), 1);
26692669

2670+
// Opening a file inside the existing worktree with -n reuses the window.
26702671
cx.update(|cx| {
26712672
open_paths(
26722673
&[PathBuf::from(path!("/root/dir/c"))],
@@ -2680,6 +2681,22 @@ mod tests {
26802681
})
26812682
.await
26822683
.unwrap();
2684+
assert_eq!(cx.update(|cx| cx.windows().len()), 1);
2685+
2686+
// Opening a path NOT in any existing worktree with -n creates a new window.
2687+
cx.update(|cx| {
2688+
open_paths(
2689+
&[PathBuf::from(path!("/root/b"))],
2690+
app_state.clone(),
2691+
workspace::OpenOptions {
2692+
open_new_workspace: Some(true),
2693+
..Default::default()
2694+
},
2695+
cx,
2696+
)
2697+
})
2698+
.await
2699+
.unwrap();
26832700
assert_eq!(cx.update(|cx| cx.windows().len()), 2);
26842701
}
26852702

@@ -2733,7 +2750,7 @@ mod tests {
27332750
.unwrap();
27342751
assert_eq!(cx.update(|cx| cx.windows().len()), 1);
27352752

2736-
// Opening a directory with -n creates a new window.
2753+
// Opening a directory already in a worktree with -n reuses the window.
27372754
cx.update(|cx| {
27382755
open_paths(
27392756
&[PathBuf::from(path!("/root/dir2"))],
@@ -2747,6 +2764,22 @@ mod tests {
27472764
})
27482765
.await
27492766
.unwrap();
2767+
assert_eq!(cx.update(|cx| cx.windows().len()), 1);
2768+
2769+
// Opening a directory NOT in any worktree with -n creates a new window.
2770+
cx.update(|cx| {
2771+
open_paths(
2772+
&[PathBuf::from(path!("/root"))],
2773+
app_state.clone(),
2774+
workspace::OpenOptions {
2775+
open_new_workspace: Some(true),
2776+
..Default::default()
2777+
},
2778+
cx,
2779+
)
2780+
})
2781+
.await
2782+
.unwrap();
27502783
assert_eq!(cx.update(|cx| cx.windows().len()), 2);
27512784
}
27522785

crates/zed/src/zed/open_listener.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ mod tests {
10431043
})
10441044
.unwrap();
10451045

1046-
// Now open a file inside that workspace, but tell Zed to open a new window
1046+
// Opening a file inside the existing worktree with -n reuses the window.
10471047
open_workspace_file(
10481048
path!("/root/dir1/file1.txt"),
10491049
Some(true),
@@ -1052,18 +1052,7 @@ mod tests {
10521052
)
10531053
.await;
10541054

1055-
assert_eq!(cx.windows().len(), 2);
1056-
1057-
let multi_workspace_2 = cx.windows()[1].downcast::<MultiWorkspace>().unwrap();
1058-
multi_workspace_2
1059-
.update(cx, |multi_workspace, _, cx| {
1060-
multi_workspace.workspace().update(cx, |workspace, cx| {
1061-
assert!(workspace.active_item_as::<Editor>(cx).is_some());
1062-
let items = workspace.items(cx).collect::<Vec<_>>();
1063-
assert_eq!(items.len(), 1, "Workspace should have two items");
1064-
});
1065-
})
1066-
.unwrap();
1055+
assert_eq!(cx.windows().len(), 1);
10671056
}
10681057

10691058
#[gpui::test]

0 commit comments

Comments
 (0)