diff options
author | Azad <49314270+Akmadan23@users.noreply.github.com> | 2023-08-13 17:16:13 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-13 11:16:13 -0400 |
commit | 3141bd24c31d9ca9419c109e7f89bdb009e3b5bc (patch) | |
tree | d2133f17ee012e4d7bf0912084147281b95e1914 | |
parent | 756070e9cb5e82151632f60281f569efc7ae7f36 (diff) |
feat: add `noconfirm` option to `delete_files` command (#400)
-rw-r--r-- | docs/configuration/keymap.toml.md | 2 | ||||
-rw-r--r-- | src/commands/delete_files.rs | 100 | ||||
-rw-r--r-- | src/key_command/command.rs | 1 | ||||
-rw-r--r-- | src/key_command/impl_appexecute.rs | 9 | ||||
-rw-r--r-- | src/key_command/impl_display.rs | 6 | ||||
-rw-r--r-- | src/key_command/impl_from_str.rs | 4 |
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 { |