add interact-once switch to rm (#7432)

# Description

Fixes: #7216 

Adds `interact-once` switch which numbers out the number of files to
delete and asks the user for confirmation.

```
/home/gabriel/test〉ls                                                                                                                                                  12/11/2022 11:25:42 AM
╭───┬───────┬──────┬──────┬──────────╮
│ # │ name  │ type │ size │ modified │
├───┼───────┼──────┼──────┼──────────┤
│ 0 │ a.txt │ file │  0 B │ now      │
│ 1 │ b.txt │ file │  0 B │ now      │
│ 2 │ c.txt │ file │  0 B │ now      │
╰───┴───────┴──────┴──────┴──────────╯
/home/gabriel/test〉rm *.txt -I                                                                                                                                         12/11/2022 11:25:42 AM
rm: remove 3 files? : y

/home/gabriel/test〉ls                                                                                                                                                  12/11/2022 11:25:51 AM
/home/gabriel/test〉                                                                                                                                                    12/11/2022 11:25:54 AM
```

# User-Facing Changes

_(List of all changes that impact the user experience here. This helps
us keep track of breaking changes.)_

# Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass

# After Submitting

If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
pwygab 2022-12-12 05:22:27 +08:00 committed by GitHub
parent 585ab56ea4
commit 5036672a58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 9 deletions

View File

@ -322,8 +322,10 @@ fn interactive_copy(
span: Span,
copy_impl: impl Fn(PathBuf, PathBuf, Span) -> Value,
) -> Value {
let (interaction, confirmed) =
try_interaction(interactive, "cp: overwrite", &dst.to_string_lossy());
let (interaction, confirmed) = try_interaction(
interactive,
format!("cp: overwrite '{}'? ", dst.to_string_lossy()),
);
if let Err(e) = interaction {
Value::Error {
error: ShellError::GenericError(

View File

@ -283,8 +283,10 @@ fn move_file(
}
if interactive && to.exists() {
let (interaction, confirmed) =
try_interaction(interactive, "mv: overwrite", &to.to_string_lossy());
let (interaction, confirmed) = try_interaction(
interactive,
format!("mv: overwrite '{}'? ", to.to_string_lossy()),
);
if let Err(e) = interaction {
return Err(ShellError::GenericError(
format!("Error during interaction: {:}", e),

View File

@ -65,6 +65,11 @@ impl Command for Rm {
.switch("force", "suppress error when no file", Some('f'))
.switch("verbose", "print names of deleted files", Some('v'))
.switch("interactive", "ask user to confirm action", Some('i'))
.switch(
"interactive-once",
"ask user to confirm action only once",
Some('I'),
)
.rest(
"rest",
SyntaxShape::GlobPattern,
@ -138,6 +143,7 @@ fn rm(
let force = call.has_flag("force");
let verbose = call.has_flag("verbose");
let interactive = call.has_flag("interactive");
let interactive_once = call.has_flag("interactive-once") && !interactive;
let ctrlc = engine_state.ctrlc.clone();
@ -299,6 +305,24 @@ fn rm(
));
}
if interactive_once {
let (interaction, confirmed) = try_interaction(
interactive_once,
format!("rm: remove {} files? ", all_targets.len()),
);
if let Err(e) = interaction {
return Err(ShellError::GenericError(
format!("Error during interaction: {:}", e),
"could not move".into(),
None,
None,
Vec::new(),
));
} else if !confirmed {
return Ok(PipelineData::Empty);
}
}
Ok(all_targets
.into_keys()
.map(move |f| {
@ -325,8 +349,10 @@ fn rm(
|| is_fifo
|| is_empty()
{
let (interaction, confirmed) =
try_interaction(interactive, "rm: remove", &f.to_string_lossy());
let (interaction, confirmed) = try_interaction(
interactive,
format!("rm: remove '{}'? ", f.to_string_lossy()),
);
let result;
#[cfg(all(

View File

@ -90,11 +90,9 @@ impl Resource {}
pub fn try_interaction(
interactive: bool,
prompt_msg: &str,
file_name: &str,
prompt: String,
) -> (Result<Option<bool>, Box<dyn Error>>, bool) {
let interaction = if interactive {
let prompt = format!("{} '{}'? ", prompt_msg, file_name);
match get_interactive_confirmation(prompt) {
Ok(i) => Ok(Some(i)),
Err(e) => Err(e),