Merge pull request #2388 from zed-industries/cmd-o-new-window

Max Brunsfeld created

When opening projects, only reuse the current window if it is empty

Change summary

crates/recent_projects/src/recent_projects.rs |  2 
crates/workspace/src/workspace.rs             | 24 +++++++++++++++-----
2 files changed, 19 insertions(+), 7 deletions(-)

Detailed changes

crates/recent_projects/src/recent_projects.rs 🔗

@@ -167,7 +167,7 @@ impl PickerDelegate for RecentProjectsView {
     fn confirm(&mut self, cx: &mut ViewContext<Self>) {
         if let Some(selected_match) = &self.matches.get(self.selected_index()) {
             let workspace_location = &self.workspace_locations[selected_match.candidate_id];
-            cx.dispatch_global_action(OpenPaths {
+            cx.dispatch_action(OpenPaths {
                 paths: workspace_location.paths().as_ref().clone(),
             });
             cx.emit(Event::Dismissed);

crates/workspace/src/workspace.rs 🔗

@@ -302,14 +302,26 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
             let app_state = app_state.upgrade()?;
             let window_id = cx.window_id();
             let action = action.clone();
-            let close = workspace.prepare_to_close(false, cx);
+            let is_remote = workspace.project.read(cx).is_remote();
+            let has_worktree = workspace.project.read(cx).worktrees(cx).next().is_some();
+            let has_dirty_items = workspace.items(cx).any(|item| item.is_dirty(cx));
+            let close_task = if is_remote || has_worktree || has_dirty_items {
+                None
+            } else {
+                Some(workspace.prepare_to_close(false, cx))
+            };
 
             Some(cx.spawn_weak(|_, mut cx| async move {
-                let can_close = close.await?;
-                if can_close {
-                    cx.update(|cx| open_paths(&action.paths, &app_state, Some(window_id), cx))
-                        .await;
-                }
+                let window_id_to_replace = if let Some(close_task) = close_task {
+                    if !close_task.await? {
+                        return Ok(());
+                    }
+                    Some(window_id)
+                } else {
+                    None
+                };
+                cx.update(|cx| open_paths(&action.paths, &app_state, window_id_to_replace, cx))
+                    .await;
                 Ok(())
             }))
         }