From bdaf096e1c1fe36df2d37542344aa7f679dc75ec Mon Sep 17 00:00:00 2001 From: Tyler Calder Date: Tue, 23 Aug 2022 20:09:16 -0600 Subject: [PATCH] fix: Add possible vals to man for positional args Noticed that possible values would not show up for Positional arguments as well. Decided to add the changes for those as well. --- clap_mangen/src/render.rs | 93 +++++++++++++------ clap_mangen/tests/common.rs | 29 ++++-- .../tests/snapshots/feature_sample.bash.roff | 2 + .../tests/snapshots/possible_values.bash.roff | 17 +++- .../snapshots/special_commands.bash.roff | 2 + .../tests/snapshots/sub_subcommands.bash.roff | 2 + .../tests/snapshots/value_hint.bash.roff | 2 +- 7 files changed, 105 insertions(+), 42 deletions(-) diff --git a/clap_mangen/src/render.rs b/clap_mangen/src/render.rs index 1dab84914318..bed1d8046ac0 100644 --- a/clap_mangen/src/render.rs +++ b/clap_mangen/src/render.rs @@ -110,9 +110,9 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) { } let mut body = vec![]; - let mut help_written = false; + let mut arg_help_written = false; if let Some(help) = opt.get_long_help().or_else(|| opt.get_help()) { - help_written = true; + arg_help_written = true; body.push(roman(help)); } @@ -120,43 +120,29 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) { roff.text(header); roff.text(body); - let possibles: Vec = opt - .get_value_parser() - .possible_values() - .map(|pvs| pvs.collect()) - .unwrap_or_default(); - let possibles: Vec<&clap::builder::PossibleValue> = - possibles.iter().filter(|pos| !pos.is_hide_set()).collect(); - - if !(possibles.is_empty() || opt.is_hide_possible_values_set()) { - if help_written { + if let Some((possible_values_text, with_help)) = get_possible_values(opt) { + if arg_help_written { // It looks nice to have a separation between the help and the values roff.text([Inline::LineBreak]); } - // with help for each possible value - - if possibles.iter().any(|p| p.get_help().is_some()) { + if with_help { roff.text([Inline::LineBreak, italic("Possible values:")]); - // Need to indent twice to get it to look right, - // because .TP heading indents, but that indent doesn't - // Carry over to the .IP for the bullets. - // The standard shift size is 7 for terminal devices + // Need to indent twice to get it to look right, because .TP heading indents, but + // that indent doesn't Carry over to the .IP for the bullets. The standard shift + // size is 7 for terminal devices roff.control("RS", ["14"]); - for line in format_possible_values(&possibles) { + for line in possible_values_text { roff.control("IP", ["\\(bu", "2"]); roff.text([roman(line)]); } roff.control("RE", []); - } - - // without help for each possible value - else { - let possible_list = format_possible_values(&possibles); + } else { let possible_value_text: Vec = vec![ Inline::LineBreak, - italic("[possible values: "), - roman(possible_list.join(", ")), + roman("["), + italic("possible values: "), + roman(possible_values_text.join(", ")), roman("]"), ]; roff.text(possible_value_text); @@ -186,8 +172,10 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) { } let mut body = vec![]; + let mut arg_help_written = false; if let Some(help) = pos.get_long_help().or_else(|| pos.get_help()) { body.push(roman(&help.to_string())); + arg_help_written = true; } roff.control("TP", []); @@ -199,6 +187,35 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) { roff.text(env); roff.control("RE", []); } + // If possible options are available + if let Some((possible_values_text, with_help)) = get_possible_values(pos) { + if arg_help_written { + // It looks nice to have a separation between the help and the values + roff.text([Inline::LineBreak]); + } + if with_help { + roff.text([Inline::LineBreak, italic("Possible values:")]); + + // Need to indent twice to get it to look right, because .TP heading indents, but + // that indent doesn't Carry over to the .IP for the bullets. The standard shift + // size is 7 for terminal devices + roff.control("RS", ["14"]); + for line in possible_values_text { + roff.control("IP", ["\\(bu", "2"]); + roff.text([roman(line)]); + } + roff.control("RE", []); + } else { + let possible_value_text: Vec = vec![ + Inline::LineBreak, + roman("["), + italic("possible values: "), + roman(possible_values_text.join(", ")), + roman("]"), + ]; + roff.text(possible_value_text); + } + } } } @@ -288,9 +305,25 @@ fn option_default_values(opt: &clap::Arg) -> Option { None } -fn format_possible_values(possibles: &Vec<&clap::builder::PossibleValue>) -> Vec { +fn get_possible_values(arg: &clap::Arg) -> Option<(Vec, bool)> { + let possibles = arg.get_value_parser().possible_values(); + + if let Some(possible_vals) = possibles { + let possibles: Vec<_> = possible_vals.collect(); + let shown_possibles: Vec<_> = possibles.iter().filter(|pos| !pos.is_hide_set()).collect(); + + if !(shown_possibles.is_empty() || arg.is_hide_possible_values_set()) { + return Some(format_possible_values(&shown_possibles)); + } + return None; + } + None +} + +fn format_possible_values(possibles: &Vec<&clap::builder::PossibleValue>) -> (Vec, bool) { let mut lines = vec![]; - if possibles.iter().any(|p| p.get_help().is_some()) { + let with_help = possibles.iter().any(|p| p.get_help().is_some()); + if with_help { for value in possibles { let val_name = value.get_name(); match value.get_help() { @@ -301,5 +334,5 @@ fn format_possible_values(possibles: &Vec<&clap::builder::PossibleValue>) -> Vec } else { lines.append(&mut possibles.iter().map(|p| p.get_name().to_string()).collect()); } - lines + (lines, with_help) } diff --git a/clap_mangen/tests/common.rs b/clap_mangen/tests/common.rs index 23e1628be43b..836f9c5a69e4 100644 --- a/clap_mangen/tests/common.rs +++ b/clap_mangen/tests/common.rs @@ -1,7 +1,6 @@ use clap::builder::PossibleValue; pub fn basic_command(name: &'static str) -> clap::Command<'static> { - clap::Command::new(name) .arg(clap::Arg::new("config").short('c').global(true)) .arg(clap::Arg::new("v").short('v').conflicts_with("config")) @@ -256,7 +255,7 @@ pub fn assert_matches_path(expected_path: impl AsRef, cmd: clap .matches_path(expected_path, buf); } -pub fn possible_values_command(name: &'static str) -> clap::Command<'static> { +pub fn possible_values_command(name: &'static str) -> clap::Command { clap::Command::new(name) .trailing_var_arg(true) .arg( @@ -267,12 +266,24 @@ pub fn possible_values_command(name: &'static str) -> clap::Command<'static> { ) .arg( clap::Arg::new("method") - .long("method") - .action(clap::ArgAction::Set) - .value_parser([ - PossibleValue::new("fast").help("use the Fast method"), - PossibleValue::new("slow").help("use the slow method"), - PossibleValue::new("normal").help("use normal mode").hide(true) - ]) + .long("method") + .action(clap::ArgAction::Set) + .value_parser([ + PossibleValue::new("fast").help("use the Fast method"), + PossibleValue::new("slow").help("use the slow method"), + PossibleValue::new("normal") + .help("use normal mode") + .hide(true), + ]), + ) + .arg( + clap::Arg::new("positional_choice") + .action(clap::ArgAction::Set) + .help("Pick the Position you want the command to run in") + .value_parser([ + PossibleValue::new("left").help("run left adjusted"), + PossibleValue::new("right"), + PossibleValue::new("center").hide(true), + ]), ) } diff --git a/clap_mangen/tests/snapshots/feature_sample.bash.roff b/clap_mangen/tests/snapshots/feature_sample.bash.roff index ae9be971f3a6..4c43af3f5a57 100644 --- a/clap_mangen/tests/snapshots/feature_sample.bash.roff +++ b/clap_mangen/tests/snapshots/feature_sample.bash.roff @@ -23,6 +23,8 @@ some input file .TP [/fIchoice/fR] +.br +[/fIpossible values: /fRfirst, second] .SH SUBCOMMANDS .TP my/-app/-test(1) diff --git a/clap_mangen/tests/snapshots/possible_values.bash.roff b/clap_mangen/tests/snapshots/possible_values.bash.roff index 8e12bd13f3fe..b150a540f344 100644 --- a/clap_mangen/tests/snapshots/possible_values.bash.roff +++ b/clap_mangen/tests/snapshots/possible_values.bash.roff @@ -4,7 +4,7 @@ .SH NAME my/-app .SH SYNOPSIS -/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-/-choice/fR] [/fB/-/-method/fR] +/fBmy/-app/fR [/fB/-h/fR|/fB/-/-help/fR] [/fB/-/-choice/fR] [/fB/-/-method/fR] [/fIpositional_choice/fR] .SH DESCRIPTION .SH OPTIONS .TP @@ -14,7 +14,7 @@ Print help information /fB/-/-choice/fR .br -/fI[possible values: /fRbash, fish, zsh] +[/fIpossible values: /fRbash, fish, zsh] .TP /fB/-/-method/fR @@ -26,3 +26,16 @@ fast: use the Fast method .IP /(bu 2 slow: use the slow method .RE +.TP +[/fIpositional_choice/fR] +Pick the Position you want the command to run in +.br + +.br +/fIPossible values:/fR +.RS 14 +.IP /(bu 2 +left: run left adjusted +.IP /(bu 2 +right +.RE diff --git a/clap_mangen/tests/snapshots/special_commands.bash.roff b/clap_mangen/tests/snapshots/special_commands.bash.roff index 08d364d8bc31..47c1c473b43c 100644 --- a/clap_mangen/tests/snapshots/special_commands.bash.roff +++ b/clap_mangen/tests/snapshots/special_commands.bash.roff @@ -23,6 +23,8 @@ some input file .TP [/fIchoice/fR] +.br +[/fIpossible values: /fRfirst, second] .SH SUBCOMMANDS .TP my/-app/-test(1) diff --git a/clap_mangen/tests/snapshots/sub_subcommands.bash.roff b/clap_mangen/tests/snapshots/sub_subcommands.bash.roff index e364240fe719..f23a250285d3 100644 --- a/clap_mangen/tests/snapshots/sub_subcommands.bash.roff +++ b/clap_mangen/tests/snapshots/sub_subcommands.bash.roff @@ -23,6 +23,8 @@ some input file .TP [/fIchoice/fR] +.br +[/fIpossible values: /fRfirst, second] .SH SUBCOMMANDS .TP my/-app/-test(1) diff --git a/clap_mangen/tests/snapshots/value_hint.bash.roff b/clap_mangen/tests/snapshots/value_hint.bash.roff index 6debf91487d9..3ff1f76e1a77 100644 --- a/clap_mangen/tests/snapshots/value_hint.bash.roff +++ b/clap_mangen/tests/snapshots/value_hint.bash.roff @@ -14,7 +14,7 @@ Print help information /fB/-/-choice/fR .br -/fI[possible values: /fRbash, fish, zsh] +[/fIpossible values: /fRbash, fish, zsh] .TP /fB/-/-unknown/fR