From 0c4d4632ef6c7892e3818b653dbba53d15132035 Mon Sep 17 00:00:00 2001 From: pwygab <88221256+merelymyself@users.noreply.github.com> Date: Tue, 13 Dec 2022 20:45:33 +0800 Subject: [PATCH] let `UnknownFlag` error list out available flags (#7443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Fixes #6773. ``` /home/gabriel/CodingProjects/nushell〉ls -r 12/12/2022 02:57:35 PM Error: nu::parser::unknown_flag (link) × The `ls` command doesn't have flag `-r`. ╭─[entry #1:1:1] 1 │ ls -r · ┬ · ╰── unknown flag ╰──── help: Available flags: --help(-h), --all(-a), --long(-l), --short-names(-s), --full-paths(-f), --du(-d), --directory(-D). Use `--help` for more information. ``` # User-Facing Changes Different error for unknown flag. # 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. --- crates/nu-command/tests/commands/ls.rs | 14 ++++++++++++ crates/nu-parser/src/errors.rs | 10 +++------ crates/nu-parser/src/parser.rs | 5 +++++ crates/nu-protocol/src/signature.rs | 31 ++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/crates/nu-command/tests/commands/ls.rs b/crates/nu-command/tests/commands/ls.rs index 4a8c3f8784..3053fa7784 100644 --- a/crates/nu-command/tests/commands/ls.rs +++ b/crates/nu-command/tests/commands/ls.rs @@ -559,3 +559,17 @@ fn list_ignores_ansi() { assert!(actual.err.is_empty()); }) } + +#[test] +fn list_unknown_flag() { + let actual = nu!( + cwd: ".", pipeline( + r#" + ls -r + "# + )); + + assert!(actual + .err + .contains("Available flags: --help(-h), --all(-a),")); +} diff --git a/crates/nu-parser/src/errors.rs b/crates/nu-parser/src/errors.rs index f121d71218..cdfdb0441b 100644 --- a/crates/nu-parser/src/errors.rs +++ b/crates/nu-parser/src/errors.rs @@ -251,12 +251,8 @@ pub enum ParseError { NonUtf8(#[label = "non-UTF8 string"] Span), #[error("The `{0}` command doesn't have flag `{1}`.")] - #[diagnostic( - code(nu::parser::unknown_flag), - url(docsrs), - help("use {0} --help for a list of flags") - )] - UnknownFlag(String, String, #[label = "unknown flag"] Span), + #[diagnostic(code(nu::parser::unknown_flag), url(docsrs), help("{3}"))] + UnknownFlag(String, String, #[label = "unknown flag"] Span, String), #[error("Unknown type.")] #[diagnostic(code(nu::parser::unknown_type), url(docsrs))] @@ -422,7 +418,7 @@ impl ParseError { ParseError::DuplicateCommandDef(s) => *s, ParseError::UnknownCommand(s) => *s, ParseError::NonUtf8(s) => *s, - ParseError::UnknownFlag(_, _, s) => *s, + ParseError::UnknownFlag(_, _, s, _) => *s, ParseError::RequiredAfterOptional(_, s) => *s, ParseError::UnknownType(s) => *s, ParseError::MissingFlagParam(_, s) => *s, diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 9b86b531c1..8e0b1e7516 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -432,6 +432,7 @@ fn parse_long_flag( sig.name.clone(), long_name.clone(), arg_span, + sig.clone().formatted_flags(), )), ) } @@ -497,6 +498,7 @@ fn parse_short_flags( sig.name.clone(), format!("-{}", String::from_utf8_lossy(contents)), *first, + sig.clone().formatted_flags(), )) }); } @@ -507,6 +509,7 @@ fn parse_short_flags( sig.name.clone(), format!("-{}", String::from_utf8_lossy(contents)), *first, + sig.clone().formatted_flags(), )) }); } @@ -517,6 +520,7 @@ fn parse_short_flags( sig.name.clone(), format!("-{}", String::from_utf8_lossy(contents)), *first, + sig.clone().formatted_flags(), )) }); } @@ -528,6 +532,7 @@ fn parse_short_flags( sig.name.clone(), format!("-{}", String::from_utf8_lossy(contents)), *first, + sig.clone().formatted_flags(), )) }); } diff --git a/crates/nu-protocol/src/signature.rs b/crates/nu-protocol/src/signature.rs index 4d919a327b..1a2d5b5440 100644 --- a/crates/nu-protocol/src/signature.rs +++ b/crates/nu-protocol/src/signature.rs @@ -610,6 +610,37 @@ impl Signature { block_id, }) } + + pub fn formatted_flags(self) -> String { + if self.named.len() < 11 { + let mut s = "Available flags:".to_string(); + for flag in self.named { + if let Some(short) = flag.short { + let _ = write!(s, " --{}(-{}),", flag.long, short); + } else { + let _ = write!(s, " --{},", flag.long); + } + } + s.remove(s.len() - 1); + let _ = write!(s, ". Use `--help` for more information."); + s + } else { + let mut s = "Some available flags:".to_string(); + for flag in self.named { + if let Some(short) = flag.short { + let _ = write!(s, " --{}(-{}),", flag.long, short); + } else { + let _ = write!(s, " --{},", flag.long); + } + } + s.remove(s.len() - 1); + let _ = write!( + s, + "... Use `--help` for a full list of flags and more information." + ); + s + } + } } #[derive(Clone)]