Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to mark arguments as to be ignored by suggestions. #5097

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 45 additions & 0 deletions clap_builder/src/builder/arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2349,6 +2349,46 @@ impl Arg {
}
}

/// Do not include the argument in didyoumean suggestions.
///
/// # Examples
///
/// Setting `ExcludeDidYouMean` will not consider the argument
/// when making suggestions for mistyped arguments.
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let m = Command::new("prog")
/// .arg(Arg::new("cfg")
/// .long("config")
/// .didyoumean(false)
/// .get_matches_from(vec![
/// "prog", "--conf"
/// ]);
/// # }
/// ```
///
/// The above example will not display the usual `a similar argument ...`
/// message
///
/// ```text
/// error: unexpected argument '--conf' found
///
/// Usage: prog [OPTIONS]
///
/// For more information, try '--help'.
/// ```
#[inline]
#[must_use]
pub fn didyoumean(self, yes: bool) -> Self {
if yes {
self.unset_setting(ArgSettings::ExcludeDidYouMean)
} else {
self.setting(ArgSettings::ExcludeDidYouMean)
}
}

/// Do not display the [possible values][crate::builder::ValueParser::possible_values] in the help message.
///
/// This is useful for args with many values, or ones which are explained elsewhere in the
Expand Down Expand Up @@ -4153,6 +4193,11 @@ impl Arg {
self.is_set(ArgSettings::HideEnv)
}

/// dont did you mean
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self, needs docs.

pub fn is_didyoumean_set(&self) -> bool {
!self.is_set(ArgSettings::ExcludeDidYouMean)
}

/// Report whether [`Arg::hide_env_values`] is set
#[cfg(feature = "env")]
pub fn is_hide_env_values_set(&self) -> bool {
Expand Down
1 change: 1 addition & 0 deletions clap_builder/src/builder/arg_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub(crate) enum ArgSettings {
HiddenShortHelp,
HiddenLongHelp,
Exclusive,
ExcludeDidYouMean,
}

impl ArgSettings {
Expand Down
20 changes: 14 additions & 6 deletions clap_builder/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1503,13 +1503,21 @@ impl<'cmd> Parser<'cmd> {
) -> ClapError {
debug!("Parser::did_you_mean_error: arg={arg}");
// Didn't match a flag or option
let longs = self
.cmd
.get_keymap()
let keymap = self.cmd.get_keymap();
let longs = keymap
.keys()
.filter_map(|x| match x {
KeyType::Long(l) => Some(l.to_string_lossy().into_owned()),
_ => None,
.filter_map(|key| {
let arg = keymap.get(key)?;
match (key, arg) {
(KeyType::Long(l), arg) => {
if arg.is_didyoumean_set() {
Some(l.to_string_lossy().into_owned())
} else {
None
}
}
(_, _) => None,
}
})
.collect::<Vec<_>>();
debug!("Parser::did_you_mean_error: longs={longs:?}");
Expand Down
16 changes: 16 additions & 0 deletions tests/builder/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,22 @@ For more information, try '--help'.
utils::assert_output(utils::complex_app(), "clap-test --optio=foo", DYM, true);
}

#[test]
#[cfg(feature = "suggestions")]
#[cfg(feature = "error-context")]
fn did_you_mean_disabled() {
static DYM: &str = "\
error: unexpected argument '--conf' found

Usage: clap-test [OPTIONS]

For more information, try '--help'.
";

let c = Command::new("clap-test").arg(Arg::new("cfg").long("config").didyoumean(false));
utils::assert_output(c, "clap-test --conf", DYM, true);
}

#[test]
fn issue_1047_min_zero_vals_default_val() {
let m = Command::new("foo")
Expand Down