Skip to content

Commit

Permalink
feat: Show user defined help flags in hints
Browse files Browse the repository at this point in the history
This allows display of user-defined help flags during "try 'help'" style
messages
  • Loading branch information
zanieb committed Jul 9, 2024
1 parent b24deb1 commit 2eb842c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
31 changes: 26 additions & 5 deletions clap_builder/src/error/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#![cfg_attr(not(feature = "error-context"), allow(dead_code))]
#![cfg_attr(not(feature = "error-context"), allow(unused_imports))]

use std::borrow::Cow;

use crate::builder::Command;
use crate::builder::StyledStr;
use crate::builder::Styles;
Expand All @@ -12,6 +14,7 @@ use crate::error::ContextKind;
use crate::error::ContextValue;
use crate::error::ErrorKind;
use crate::output::TAB;
use crate::ArgAction;

/// Defines how to format an error for displaying to the user
pub trait ErrorFormatter: Sized {
Expand Down Expand Up @@ -120,7 +123,7 @@ impl ErrorFormatter for RichFormatter {
put_usage(&mut styled, usage);
}

try_help(&mut styled, styles, error.inner.help_flag);
try_help(&mut styled, styles, error.inner.help_flag.as_deref());

styled
}
Expand Down Expand Up @@ -461,7 +464,7 @@ pub(crate) fn format_error_message(
put_usage(&mut styled, usage);
}
if let Some(cmd) = cmd {
try_help(&mut styled, styles, get_help_flag(cmd));
try_help(&mut styled, styles, get_help_flag(cmd).as_deref());
}
styled
}
Expand All @@ -480,16 +483,34 @@ fn put_usage(styled: &mut StyledStr, usage: &StyledStr) {
styled.push_styled(usage);
}

pub(crate) fn get_help_flag(cmd: &Command) -> Option<&'static str> {
pub(crate) fn get_help_flag(cmd: &Command) -> Option<Cow<'static, str>> {
if !cmd.is_disable_help_flag_set() {
Some("--help")
Some(Cow::Borrowed("--help"))
} else if let Some(flag) = get_user_help_flag(cmd) {
Some(Cow::Owned(flag))
} else if cmd.has_subcommands() && !cmd.is_disable_help_subcommand_set() {
Some("help")
Some(Cow::Borrowed("help"))
} else {
None
}
}

fn get_user_help_flag(cmd: &Command) -> Option<String> {
let arg = cmd.get_arguments().find(|arg| match arg.get_action() {
ArgAction::Help | ArgAction::HelpShort | ArgAction::HelpLong => true,
ArgAction::Append
| ArgAction::Count
| ArgAction::SetTrue
| ArgAction::SetFalse
| ArgAction::Set
| ArgAction::Version => false,
})?;

arg.get_long()
.map(|long| format!("--{long}"))
.or_else(|| arg.get_short().map(|short| format!("-{short}")))
}

fn try_help(styled: &mut StyledStr, styles: &Styles, help: Option<&str>) {
if let Some(help) = help {
use std::fmt::Write as _;
Expand Down
4 changes: 2 additions & 2 deletions clap_builder/src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct ErrorInner {
context: FlatMap<ContextKind, ContextValue>,
message: Option<Message>,
source: Option<Box<dyn error::Error + Send + Sync>>,
help_flag: Option<&'static str>,
help_flag: Option<Cow<'static, str>>,
styles: Styles,
color_when: ColorChoice,
color_help_when: ColorChoice,
Expand Down Expand Up @@ -319,7 +319,7 @@ impl<F: ErrorFormatter> Error<F> {
self
}

pub(crate) fn set_help_flag(mut self, help_flag: Option<&'static str>) -> Self {
pub(crate) fn set_help_flag(mut self, help_flag: Option<Cow<'static, str>>) -> Self {
self.inner.help_flag = help_flag;
self
}
Expand Down
8 changes: 7 additions & 1 deletion tests/builder/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ fn try_help_custom_flag() {
error: unexpected argument 'bar' found
Usage: ctest
For more information, try '--help'.
";

let cmd = Command::new("ctest")
Expand All @@ -394,6 +396,8 @@ fn try_help_custom_flag_short() {
error: unexpected argument 'bar' found
Usage: ctest
For more information, try '-h'.
";

let cmd = Command::new("ctest")
Expand All @@ -410,6 +414,8 @@ fn try_help_custom_flag_long() {
error: unexpected argument 'bar' found
Usage: ctest
For more information, try '--help'.
";

let cmd = Command::new("ctest")
Expand Down Expand Up @@ -461,7 +467,7 @@ error: unrecognized subcommand 'bar'
Usage: ctest [COMMAND]
For more information, try 'help'.
For more information, try '--help'.
";

let cmd = Command::new("ctest")
Expand Down

0 comments on commit 2eb842c

Please sign in to comment.