summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAzad <49314270+Akmadan23@users.noreply.github.com>2023-08-13 17:16:13 +0200
committerGitHub <noreply@github.com>2023-08-13 11:16:13 -0400
commit3141bd24c31d9ca9419c109e7f89bdb009e3b5bc (patch)
treed2133f17ee012e4d7bf0912084147281b95e1914
parent756070e9cb5e82151632f60281f569efc7ae7f36 (diff)
feat: add `noconfirm` option to `delete_files` command (#400)
-rw-r--r--docs/configuration/keymap.toml.md2
-rw-r--r--src/commands/delete_files.rs100
-rw-r--r--src/key_command/command.rs1
-rw-r--r--src/key_command/impl_appexecute.rs9
-rw-r--r--src/key_command/impl_display.rs6
-rw-r--r--src/key_command/impl_from_str.rs4
6 files changed, 71 insertions, 51 deletions
diff --git a/docs/configuration/keymap.toml.md b/docs/configuration/keymap.toml.md
index 75929f3..b926c1a 100644
--- a/docs/configuration/keymap.toml.md
+++ b/docs/configuration/keymap.toml.md
@@ -269,6 +269,8 @@ function joshuto() {
- `--foreground=true`: will delete files in the foreground
- `--permanently`: force permanent deletion regardless of `use_trash` value.
+- `--noconfirm`: files will be deleted without asking for confirmation
+ (can be dangerous when `use_trash` is `false`)
- will **_permanently_** delete files if `use_trash` is `false` in
[joshuto.toml](https://github.com/kamiyaa/joshuto)/wiki/Configuration#joshutotoml)
- if `use_trash` is `true`, `joshuto` will try to use
diff --git a/src/commands/delete_files.rs b/src/commands/delete_files.rs
index 4f062bc..2f336fa 100644
--- a/src/commands/delete_files.rs
+++ b/src/commands/delete_files.rs
@@ -10,27 +10,7 @@ use crate::io::{FileOperation, FileOperationOptions, IoWorkerThread};
use crate::ui::widgets::TuiPrompt;
use crate::ui::AppBackend;
-fn delete_files(
- context: &mut AppContext,
- backend: &mut AppBackend,
- background: bool,
- permanently: bool,
-) -> JoshutoResult<()> {
- let paths = context
- .tab_context_ref()
- .curr_tab_ref()
- .curr_list_ref()
- .map(|s| s.get_selected_paths())
- .unwrap_or_default();
- let paths_len = paths.len();
- if paths_len == 0 {
- let err = JoshutoError::new(
- JoshutoErrorKind::InvalidParameters,
- "no files selected".to_string(),
- );
- return Err(err);
- }
-
+fn prompt(context: &mut AppContext, backend: &mut AppBackend, paths_len: usize) -> bool {
let ch = {
let prompt_str = format!("Delete {} files? (Y/n)", paths_len);
let mut prompt = TuiPrompt::new(&prompt_str);
@@ -39,7 +19,7 @@ fn delete_files(
match ch {
Key::Char('Y') | Key::Char('y') | Key::Char('\n') => {
- let confirm_delete = if paths_len > 1 {
+ if paths_len > 1 {
// prompt user again for deleting multiple files
let ch = {
let prompt_str = "Are you sure? (y/N)";
@@ -49,42 +29,68 @@ fn delete_files(
ch == Key::Char('y')
} else {
true
- };
- if confirm_delete {
- let file_op = FileOperation::Delete;
- let options = FileOperationOptions {
- overwrite: false,
- skip_exist: false,
- permanently: !context.config_ref().use_trash || permanently,
- };
-
- let dest = path::PathBuf::new();
- let worker_thread = IoWorkerThread::new(file_op, paths.clone(), dest, options);
- if background {
- context.worker_context_mut().push_worker(worker_thread);
- } else {
- let (wtx, _) = mpsc::channel();
- worker_thread.start(wtx)?;
- }
-
- let history = context.tab_context_mut().curr_tab_mut().history_mut();
- for path in paths.iter().filter(|p| p.is_dir()) {
- history.remove(path);
- }
}
- Ok(())
}
- _ => Ok(()),
+ _ => false,
}
}
+fn delete_files(
+ context: &mut AppContext,
+ paths: Vec<path::PathBuf>,
+ background: bool,
+ permanently: bool,
+) -> JoshutoResult<()> {
+ let file_op = FileOperation::Delete;
+ let options = FileOperationOptions {
+ overwrite: false,
+ skip_exist: false,
+ permanently: !context.config_ref().use_trash || permanently,
+ };
+
+ let dest = path::PathBuf::new();
+ let worker_thread = IoWorkerThread::new(file_op, paths.clone(), dest, options);
+ if background {
+ context.worker_context_mut().push_worker(worker_thread);
+ } else {
+ let (wtx, _) = mpsc::channel();
+ worker_thread.start(wtx)?;
+ }
+
+ let history = context.tab_context_mut().curr_tab_mut().history_mut();
+ for path in paths.iter().filter(|p| p.is_dir()) {
+ history.remove(path);
+ }
+
+ Ok(())
+}
+
pub fn delete_selected_files(
context: &mut AppContext,
backend: &mut AppBackend,
background: bool,
permanently: bool,
+ noconfirm: bool,
) -> JoshutoResult {
- delete_files(context, backend, background, permanently)?;
+ let paths = context
+ .tab_context_ref()
+ .curr_tab_ref()
+ .curr_list_ref()
+ .map(|s| s.get_selected_paths())
+ .unwrap_or_default();
+
+ let paths_len = paths.len();
+ if paths_len == 0 {
+ let err = JoshutoError::new(
+ JoshutoErrorKind::InvalidParameters,
+ "no files selected".to_string(),
+ );
+ return Err(err);
+ }
+
+ if noconfirm || prompt(context, backend, paths_len) {
+ delete_files(context, paths, background, permanently)?;
+ }
let curr_tab = context.tab_context_ref().curr_tab_ref();
let options = context.config_ref().display_options_ref().clone();
diff --git a/src/key_command/command.rs b/src/key_command/command.rs
index 16734f1..d4710eb 100644
--- a/src/key_command/command.rs
+++ b/src/key_command/command.rs
@@ -44,6 +44,7 @@ pub enum Command {
DeleteFiles {
background: bool,
permanently: bool,
+ noconfirm: bool,
},
CursorMoveUp {
diff --git a/src/key_command/impl_appexecute.rs b/src/key_command/impl_appexecute.rs
index 4f4d346..1786e96 100644
--- a/src/key_command/impl_appexecute.rs
+++ b/src/key_command/impl_appexecute.rs
@@ -53,7 +53,14 @@ impl AppExecute for Command {
Self::DeleteFiles {
background,
permanently,
- } => delete_files::delete_selected_files(context, backend, *background, *permanently),
+ noconfirm,
+ } => delete_files::delete_selected_files(
+ context,
+ backend,
+ *background,
+ *permanently,
+ *noconfirm,
+ ),
Self::CursorMoveUp { offset } => cursor_move::up(context, *offset),
Self::CursorMoveDown { offset } => cursor_move::down(context, *offset),
diff --git a/src/key_command/impl_display.rs b/src/key_command/impl_display.rs
index 6049467..b15fd43 100644
--- a/src/key_command/impl_display.rs
+++ b/src/key_command/impl_display.rs
@@ -27,17 +27,19 @@ impl std::fmt::Display for Command {
Self::DeleteFiles {
background,
permanently,
+ noconfirm,
} => {
write!(
f,
- "{}{}{}",
+ "{}{}{}{}",
self.command(),
if !background {
" --foreground=true"
} else {
""
},
- if *permanently { " --permanently" } else { "" }
+ if *permanently { " --permanently" } else { "" },
+ if *noconfirm { " --noconfirm" } else { "" },
)
}
diff --git a/src/key_command/impl_from_str.rs b/src/key_command/impl_from_str.rs
index 77a131d..0b76d38 100644
--- a/src/key_command/impl_from_str.rs
+++ b/src/key_command/impl_from_str.rs
@@ -265,12 +265,13 @@ impl std::str::FromStr for Command {
}
Ok(Self::PasteFiles { options })
} else if command == CMD_DELETE_FILES {
- let (mut permanently, mut background) = (false, false);
+ let [mut permanently, mut background, mut noconfirm] = [false; 3];
for arg in arg.split_whitespace() {
match arg {
"--background=true" => background = true,
"--background=false" => background = false,
"--permanently" => permanently = true,
+ "--noconfirm" => noconfirm = true,
_ => {
return Err(JoshutoError::new(
JoshutoErrorKind::UnrecognizedArgument,
@@ -282,6 +283,7 @@ impl std::str::FromStr for Command {
Ok(Self::DeleteFiles {
background,
permanently,
+ noconfirm,
})
} else if command == CMD_RENAME_FILE {
match arg {