@@ -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<Self>) {
+ fn delete(&mut self, action: &Delete, cx: &mut ViewContext<Self>) {
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<ProjectPanel>, 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<Workspace>,
cx: &mut VisualTestContext,