diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 5402686ecf..fbbb517c93 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -21,6 +21,7 @@ "alt-cmd-right": "pane::ActivateNextItem", "cmd-w": "pane::CloseActiveItem", "alt-cmd-t": "pane::CloseInactiveItems", + "cmd-k u": "pane::CloseCleanItems", "cmd-k cmd-w": "pane::CloseAllItems", "cmd-shift-w": "workspace::CloseWindow", "cmd-s": "workspace::Save", diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 4b787af20d..0bd4befd77 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -44,6 +44,7 @@ actions!( ActivateLastItem, CloseActiveItem, CloseInactiveItems, + CloseCleanItems, CloseAllItems, ReopenClosedItem, SplitLeft, @@ -123,6 +124,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_clean_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)?; @@ -263,6 +265,7 @@ pub enum ReorderBehavior { enum ItemType { Active, Inactive, + Clean, All, } @@ -723,6 +726,14 @@ impl Pane { Self::close_main(workspace, ItemType::All, cx) } + pub fn close_clean_items( + workspace: &mut Workspace, + _: &CloseCleanItems, + cx: &mut ViewContext, + ) -> Option>> { + Self::close_main(workspace, ItemType::Clean, cx) + } + fn close_main( workspace: &mut Workspace, close_item_type: ItemType, @@ -731,26 +742,32 @@ impl Pane { let pane_handle = workspace.active_pane().clone(); let pane = pane_handle.read(cx); if pane.items.is_empty() { - None - } else { - let active_item_id = pane.items[pane.active_item_index].id(); - let task = - 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(()) - })) + return None; } + + let active_item_id = pane.items[pane.active_item_index].id(); + let clean_buffers: Vec<_> = pane + .items() + .filter(|item| !item.is_dirty(cx)) + .map(|item| item.id()) + .collect(); + let task = + 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::Clean => clean_buffers.contains(&item_id), + ItemType::All => true, + }, + ); + + Some(cx.foreground().spawn(async move { + task.await?; + Ok(()) + })) } pub fn close_item(