Add close all items command

Joseph Lyons created

Change summary

assets/keymaps/default.json  |  3 +
crates/workspace/src/pane.rs | 51 ++++++++++++++++++++++++++-----------
2 files changed, 38 insertions(+), 16 deletions(-)

Detailed changes

assets/keymaps/default.json 🔗

@@ -20,8 +20,9 @@
             "alt-cmd-left": "pane::ActivatePrevItem",
             "alt-cmd-right": "pane::ActivateNextItem",
             "cmd-w": "pane::CloseActiveItem",
-            "cmd-shift-w": "workspace::CloseWindow",
             "alt-cmd-t": "pane::CloseInactiveItems",
+            "cmd-k cmd-w": "pane::CloseAllItems",
+            "cmd-shift-w": "workspace::CloseWindow",
             "cmd-s": "workspace::Save",
             "cmd-shift-s": "workspace::SaveAs",
             "cmd-=": "zed::IncreaseBufferFontSize",

crates/workspace/src/pane.rs 🔗

@@ -44,6 +44,7 @@ actions!(
         ActivateLastItem,
         CloseActiveItem,
         CloseInactiveItems,
+        CloseAllItems,
         ReopenClosedItem,
         SplitLeft,
         SplitUp,
@@ -122,6 +123,7 @@ pub fn init(cx: &mut MutableAppContext) {
     });
     cx.add_async_action(Pane::close_active_item);
     cx.add_async_action(Pane::close_inactive_items);
+    cx.add_async_action(Pane::close_all_items);
     cx.add_async_action(|workspace: &mut Workspace, action: &CloseItem, cx| {
         let pane = action.pane.upgrade(cx)?;
         let task = Pane::close_item(workspace, pane, action.item_id, cx);
@@ -258,6 +260,12 @@ pub enum ReorderBehavior {
     MoveToIndex(usize),
 }
 
+enum ItemType {
+    Active,
+    Inactive,
+    All,
+}
+
 impl Pane {
     pub fn new(docked: Option<DockAnchor>, cx: &mut ViewContext<Self>) -> Self {
         let handle = cx.weak_handle();
@@ -696,26 +704,29 @@ impl Pane {
         _: &CloseActiveItem,
         cx: &mut ViewContext<Workspace>,
     ) -> Option<Task<Result<()>>> {
-        let pane_handle = workspace.active_pane().clone();
-        let pane = pane_handle.read(cx);
-        if pane.items.is_empty() {
-            None
-        } else {
-            let item_id_to_close = pane.items[pane.active_item_index].id();
-            let task = Self::close_items(workspace, pane_handle, cx, move |item_id| {
-                item_id == item_id_to_close
-            });
-            Some(cx.foreground().spawn(async move {
-                task.await?;
-                Ok(())
-            }))
-        }
+        Self::close_main(workspace, ItemType::Active, cx)
     }
 
     pub fn close_inactive_items(
         workspace: &mut Workspace,
         _: &CloseInactiveItems,
         cx: &mut ViewContext<Workspace>,
+    ) -> Option<Task<Result<()>>> {
+        Self::close_main(workspace, ItemType::Inactive, cx)
+    }
+
+    pub fn close_all_items(
+        workspace: &mut Workspace,
+        _: &CloseAllItems,
+        cx: &mut ViewContext<Workspace>,
+    ) -> Option<Task<Result<()>>> {
+        Self::close_main(workspace, ItemType::All, cx)
+    }
+
+    fn close_main(
+        workspace: &mut Workspace,
+        close_item_type: ItemType,
+        cx: &mut ViewContext<Workspace>,
     ) -> Option<Task<Result<()>>> {
         let pane_handle = workspace.active_pane().clone();
         let pane = pane_handle.read(cx);
@@ -724,7 +735,17 @@ impl Pane {
         } else {
             let active_item_id = pane.items[pane.active_item_index].id();
             let task =
-                Self::close_items(workspace, pane_handle, cx, move |id| id != active_item_id);
+                Self::close_items(
+                    workspace,
+                    pane_handle,
+                    cx,
+                    move |item_id| match close_item_type {
+                        ItemType::Active => item_id == active_item_id,
+                        ItemType::Inactive => item_id != active_item_id,
+                        ItemType::All => true,
+                    },
+                );
+
             Some(cx.foreground().spawn(async move {
                 task.await?;
                 Ok(())