@@ -9325,7 +9325,7 @@ pub fn open_workspace_by_id(
pub fn open_paths(
abs_paths: &[PathBuf],
app_state: Arc<AppState>,
- open_options: OpenOptions,
+ mut open_options: OpenOptions,
cx: &mut App,
) -> Task<anyhow::Result<OpenResult>> {
let abs_paths = abs_paths.to_vec();
@@ -9350,10 +9350,9 @@ pub fn open_paths(
let all_metadatas = futures::future::join_all(all_paths)
.await
.into_iter()
- .filter_map(|result| result.ok().flatten())
- .collect::<Vec<_>>();
+ .filter_map(|result| result.ok().flatten());
- if all_metadatas.iter().all(|file| !file.is_dir) {
+ if all_metadatas.into_iter().all(|file| !file.is_dir) {
cx.update(|cx| {
let windows = workspace_windows_for_location(
&SerializedWorkspaceLocation::Local,
@@ -9375,6 +9374,35 @@ pub fn open_paths(
}
}
+ // Fallback for directories: when no flag is specified and no existing
+ // workspace matched, add the directory as a new workspace in the
+ // active window's MultiWorkspace (instead of opening a new window).
+ if open_options.open_new_workspace.is_none() && existing.is_none() {
+ let target_window = cx.update(|cx| {
+ let windows = workspace_windows_for_location(
+ &SerializedWorkspaceLocation::Local,
+ cx,
+ );
+ let window = cx
+ .active_window()
+ .and_then(|window| window.downcast::<MultiWorkspace>())
+ .filter(|window| windows.contains(window))
+ .or_else(|| windows.into_iter().next());
+ window.filter(|window| {
+ window.read(cx).is_ok_and(|mw| mw.multi_workspace_enabled(cx))
+ })
+ });
+
+ if let Some(window) = target_window {
+ open_options.requesting_window = Some(window);
+ window
+ .update(cx, |multi_workspace, _, cx| {
+ multi_workspace.open_sidebar(cx);
+ })
+ .log_err();
+ }
+ }
+
let open_in_dev_container = open_options.open_in_dev_container;
let result = if let Some((existing, target_workspace)) = existing {
@@ -2606,18 +2606,33 @@ mod tests {
})
.await
.unwrap();
- assert_eq!(cx.read(|cx| cx.windows().len()), 2);
-
- // Replace existing windows
- let window = cx
- .update(|cx| cx.windows()[0].downcast::<MultiWorkspace>())
+ assert_eq!(cx.read(|cx| cx.windows().len()), 1);
+ cx.run_until_parked();
+ multi_workspace_1
+ .update(cx, |multi_workspace, _window, cx| {
+ assert_eq!(multi_workspace.workspaces().len(), 2);
+ assert!(multi_workspace.sidebar_open());
+ let workspace = multi_workspace.workspace().read(cx);
+ assert_eq!(
+ workspace
+ .worktrees(cx)
+ .map(|w| w.read(cx).abs_path())
+ .collect::<Vec<_>>(),
+ &[
+ Path::new(path!("/root/c")).into(),
+ Path::new(path!("/root/d")).into(),
+ ]
+ );
+ })
.unwrap();
+
+ // Opening with -n (open_new_workspace: Some(true)) still creates a new window.
cx.update(|cx| {
open_paths(
&[PathBuf::from(path!("/root/e"))],
app_state,
workspace::OpenOptions {
- requesting_window: Some(window),
+ open_new_workspace: Some(true),
..Default::default()
},
cx,
@@ -2627,23 +2642,6 @@ mod tests {
.unwrap();
cx.background_executor.run_until_parked();
assert_eq!(cx.read(|cx| cx.windows().len()), 2);
- let multi_workspace_1 = cx
- .update(|cx| cx.windows()[0].downcast::<MultiWorkspace>())
- .unwrap();
- multi_workspace_1
- .update(cx, |multi_workspace, window, cx| {
- let workspace = multi_workspace.workspace().read(cx);
- assert_eq!(
- workspace
- .worktrees(cx)
- .map(|w| w.read(cx).abs_path())
- .collect::<Vec<_>>(),
- &[Path::new(path!("/root/e")).into()]
- );
- assert!(workspace.right_dock().read(cx).is_open());
- assert!(workspace.active_pane().focus_handle(cx).is_focused(window));
- })
- .unwrap();
}
#[gpui::test]
@@ -2724,7 +2722,6 @@ mod tests {
.await
.unwrap();
assert_eq!(cx.update(|cx| cx.windows().len()), 1);
- let window1 = cx.update(|cx| cx.active_window().unwrap());
cx.update(|cx| {
open_paths(
@@ -2738,6 +2735,8 @@ mod tests {
.unwrap();
assert_eq!(cx.update(|cx| cx.windows().len()), 1);
+ // Opening a directory with default options adds to the existing window
+ // rather than creating a new one.
cx.update(|cx| {
open_paths(
&[PathBuf::from(path!("/root/dir2"))],
@@ -2748,25 +2747,23 @@ mod tests {
})
.await
.unwrap();
- assert_eq!(cx.update(|cx| cx.windows().len()), 2);
- let window2 = cx.update(|cx| cx.active_window().unwrap());
- assert!(window1 != window2);
- cx.update_window(window1, |_, window, _| window.activate_window())
- .unwrap();
+ assert_eq!(cx.update(|cx| cx.windows().len()), 1);
+ // Opening a directory with -n creates a new window.
cx.update(|cx| {
open_paths(
- &[PathBuf::from(path!("/root/dir2/c"))],
+ &[PathBuf::from(path!("/root/dir2"))],
app_state.clone(),
- workspace::OpenOptions::default(),
+ workspace::OpenOptions {
+ open_new_workspace: Some(true),
+ ..Default::default()
+ },
cx,
)
})
.await
.unwrap();
assert_eq!(cx.update(|cx| cx.windows().len()), 2);
- // should have opened in window2 because that has dir2 visibly open (window1 has it open, but not in the project panel)
- assert!(cx.update(|cx| cx.active_window().unwrap()) == window2);
}
#[gpui::test]