diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index d687703bc3..7d640b4e30 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -514,6 +514,9 @@ "f2": "project_panel::Rename", "enter": "project_panel::Rename", "backspace": "project_panel::Delete", + "delete": "project_panel::Delete", + "ctrl-backspace": ["project_panel::Delete", { "skip_prompt": true }], + "ctrl-delete": ["project_panel::Delete", { "skip_prompt": true }], "ctrl-alt-r": "project_panel::RevealInFinder", "alt-shift-f": "project_panel::NewSearchInDirectory" } diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index d2a9a5af0f..5620a0362f 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -561,8 +561,10 @@ "alt-cmd-shift-c": "project_panel::CopyRelativePath", "f2": "project_panel::Rename", "enter": "project_panel::Rename", + "backspace": "project_panel::Delete", "delete": "project_panel::Delete", - "cmd-backspace": "project_panel::Delete", + "cmd-backspace": ["project_panel::Delete", { "skip_prompt": true }], + "cmd-delete": ["project_panel::Delete", { "skip_prompt": true }], "alt-cmd-r": "project_panel::RevealInFinder", "alt-shift-f": "project_panel::NewSearchInDirectory" } diff --git a/crates/gpui/src/app/entity_map.rs b/crates/gpui/src/app/entity_map.rs index 6383cdad7b..2b04dec5e1 100644 --- a/crates/gpui/src/app/entity_map.rs +++ b/crates/gpui/src/app/entity_map.rs @@ -394,7 +394,7 @@ impl Model { /// /// The update function receives a context appropriate for its environment. /// When updating in an `AppContext`, it receives a `ModelContext`. - /// When updating an a `WindowContext`, it receives a `ViewContext`. + /// When updating in a `WindowContext`, it receives a `ViewContext`. pub fn update( &self, cx: &mut C, diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 4d3ddb265c..d8dc6c731d 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -10,11 +10,11 @@ use file_associations::FileAssociations; use anyhow::{anyhow, Result}; use collections::{hash_map, HashMap}; use gpui::{ - actions, div, overlay, px, uniform_list, Action, AppContext, AssetSource, AsyncWindowContext, - ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, InteractiveElement, - KeyContext, Model, MouseButton, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, - Render, Stateful, Styled, Subscription, Task, UniformListScrollHandle, View, ViewContext, - VisualContext as _, WeakView, WindowContext, + actions, div, impl_actions, overlay, px, uniform_list, Action, AppContext, AssetSource, + AsyncWindowContext, ClipboardItem, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, + InteractiveElement, KeyContext, Model, MouseButton, MouseDownEvent, ParentElement, Pixels, + Point, PromptLevel, Render, Stateful, Styled, Subscription, Task, UniformListScrollHandle, + View, ViewContext, VisualContext as _, WeakView, WindowContext, }; use menu::{Confirm, SelectNext, SelectPrev}; use project::{ @@ -106,6 +106,13 @@ pub struct EntryDetails { is_dotenv: bool, } +#[derive(PartialEq, Clone, Default, Debug, Deserialize)] +pub struct Delete { + pub skip_prompt: bool, +} + +impl_actions!(project_panel, [Delete]); + actions!( project_panel, [ @@ -121,7 +128,6 @@ actions!( OpenInTerminal, Cut, Paste, - Delete, Rename, Open, ToggleFocus, @@ -448,7 +454,9 @@ impl ProjectPanel { }) .separator() .action("Rename", Box::new(Rename)) - .when(!is_root, |menu| menu.action("Delete", Box::new(Delete))) + .when(!is_root, |menu| { + menu.action("Delete", Box::new(Delete { skip_prompt: false })) + }) }, ) }); @@ -793,22 +801,26 @@ impl ProjectPanel { } } - fn delete(&mut self, _: &Delete, cx: &mut ViewContext) { + fn delete(&mut self, action: &Delete, cx: &mut ViewContext) { maybe!({ let Selection { entry_id, .. } = self.selection?; let path = self.project.read(cx).path_for_entry(entry_id, cx)?.path; let file_name = path.file_name()?; - let answer = cx.prompt( - PromptLevel::Info, - &format!("Delete {file_name:?}?"), - None, - &["Delete", "Cancel"], - ); + let answer = (!action.skip_prompt).then(|| { + cx.prompt( + PromptLevel::Info, + &format!("Delete {file_name:?}?"), + None, + &["Delete", "Cancel"], + ) + }); cx.spawn(|this, mut cx| async move { - if answer.await != Ok(0) { - return Ok(()); + if let Some(answer) = answer { + if answer.await != Ok(0) { + return Ok(()); + } } this.update(&mut cx, |this, cx| { this.project @@ -2691,7 +2703,7 @@ mod tests { open_editor.update(cx, |editor, cx| editor.set_text("Another text!", cx)); }) .unwrap(); - submit_deletion(&panel, cx); + submit_deletion_skipping_prompt(&panel, cx); assert_eq!( visible_entries_as_strings(&panel, 0..10, cx), &["v src", " v test", " third.rs"], @@ -3652,7 +3664,9 @@ mod tests { !cx.has_pending_prompt(), "Should have no prompts before the deletion" ); - panel.update(cx, |panel, cx| panel.delete(&Delete, cx)); + panel.update(cx, |panel, cx| { + panel.delete(&Delete { skip_prompt: false }, cx) + }); assert!( cx.has_pending_prompt(), "Should have a prompt after the deletion" @@ -3665,6 +3679,18 @@ mod tests { cx.executor().run_until_parked(); } + fn submit_deletion_skipping_prompt(panel: &View, cx: &mut VisualTestContext) { + assert!( + !cx.has_pending_prompt(), + "Should have no prompts before the deletion" + ); + panel.update(cx, |panel, cx| { + panel.delete(&Delete { skip_prompt: true }, cx) + }); + assert!(!cx.has_pending_prompt(), "Should have received no prompts"); + cx.executor().run_until_parked(); + } + fn ensure_no_open_items_and_panes( workspace: &WindowHandle, cx: &mut VisualTestContext, diff --git a/docs/src/configuring_zed__key_bindings.md b/docs/src/configuring_zed__key_bindings.md index 186534432c..1e676fe863 100644 --- a/docs/src/configuring_zed__key_bindings.md +++ b/docs/src/configuring_zed__key_bindings.md @@ -378,6 +378,7 @@ But, it was impossible to take into account the `{` and `}` when he was typing s | Copy relative path | Project Panel | `Alt` + `⌘` + `Shift` + `C` | | Cut | Project Panel | `⌘` + `X` | | Delete | Project Panel | `Backspace` | +| Delete (no prompt) | Project Panel | `⌘` + `Backspace` | | Expand selected entry | Project Panel | `Right` | | New directory | Project Panel | `Alt` + `⌘` + `N` | | New file | Project Panel | `Command + N` |