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.
This commit is contained in:
Tyler Calder 2022-08-23 20:09:16 -06:00
parent 069098cfcb
commit a55db43758
7 changed files with 101 additions and 39 deletions

View file

@ -1,5 +1,3 @@
use std::vec;
use roff::{bold, italic, roman, Inline, Roff}; use roff::{bold, italic, roman, Inline, Roff};
pub(crate) fn subcommand_heading(cmd: &clap::Command) -> &str { pub(crate) fn subcommand_heading(cmd: &clap::Command) -> &str {
@ -109,9 +107,9 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
} }
let mut body = vec![]; 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()) { if let Some(help) = opt.get_long_help().or_else(|| opt.get_help()) {
help_written = true; arg_help_written = true;
body.push(roman(help)); body.push(roman(help));
} }
@ -119,39 +117,29 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
roff.text(header); roff.text(header);
roff.text(body); roff.text(body);
let possibles = &opt.get_possible_values(); if let Some((possible_values_text, with_help)) = get_possible_values(opt) {
let possibles: Vec<&clap::builder::PossibleValue> = if arg_help_written {
possibles.iter().filter(|pos| !pos.is_hide_set()).collect();
if !(possibles.is_empty() || opt.is_hide_possible_values_set()) {
if help_written {
// It looks nice to have a separation between the help and the values // It looks nice to have a separation between the help and the values
roff.text([Inline::LineBreak]); roff.text([Inline::LineBreak]);
} }
// with help for each possible value if with_help {
if possibles.iter().any(|p| p.get_help().is_some()) {
roff.text([Inline::LineBreak, italic("Possible values:")]); roff.text([Inline::LineBreak, italic("Possible values:")]);
// Need to indent twice to get it to look right, // Need to indent twice to get it to look right, because .TP heading indents, but
// because .TP heading indents, but that indent doesn't // that indent doesn't Carry over to the .IP for the bullets. The standard shift
// Carry over to the .IP for the bullets. // size is 7 for terminal devices
// The standard shift size is 7 for terminal devices
roff.control("RS", ["14"]); roff.control("RS", ["14"]);
for line in format_possible_values(&possibles) { for line in possible_values_text {
roff.control("IP", ["\\(bu", "2"]); roff.control("IP", ["\\(bu", "2"]);
roff.text([roman(line)]); roff.text([roman(line)]);
} }
roff.control("RE", []); roff.control("RE", []);
} } else {
// without help for each possible value
else {
let possible_list = format_possible_values(&possibles);
let possible_value_text: Vec<Inline> = vec![ let possible_value_text: Vec<Inline> = vec![
Inline::LineBreak, Inline::LineBreak,
italic("[possible values: "), roman("["),
roman(possible_list.join(", ")), italic("possible values: "),
roman(possible_values_text.join(", ")),
roman("]"), roman("]"),
]; ];
roff.text(possible_value_text); roff.text(possible_value_text);
@ -181,8 +169,10 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
} }
let mut body = vec![]; let mut body = vec![];
let mut arg_help_written = false;
if let Some(help) = pos.get_long_help().or_else(|| pos.get_help()) { if let Some(help) = pos.get_long_help().or_else(|| pos.get_help()) {
body.push(roman(&help.to_string())); body.push(roman(&help.to_string()));
arg_help_written = true;
} }
roff.control("TP", []); roff.control("TP", []);
@ -194,6 +184,35 @@ pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
roff.text(env); roff.text(env);
roff.control("RE", []); 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<Inline> = vec![
Inline::LineBreak,
roman("["),
italic("possible values: "),
roman(possible_values_text.join(", ")),
roman("]"),
];
roff.text(possible_value_text);
}
}
} }
} }
@ -282,9 +301,21 @@ fn option_default_values(opt: &clap::Arg) -> Option<String> {
None None
} }
fn format_possible_values(possibles: &Vec<&clap::builder::PossibleValue>) -> Vec<String> { fn get_possible_values(arg: &clap::Arg) -> Option<(Vec<String>, bool)> {
let possibles = &arg.get_possible_values();
let possibles: Vec<&clap::builder::PossibleValue> =
possibles.iter().filter(|pos| !pos.is_hide_set()).collect();
if !(possibles.is_empty() || arg.is_hide_possible_values_set()) {
return Some(format_possible_values(&possibles));
}
None
}
fn format_possible_values(possibles: &Vec<&clap::builder::PossibleValue>) -> (Vec<String>, bool) {
let mut lines = vec![]; 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 { for value in possibles {
let val_name = value.get_name(); let val_name = value.get_name();
match value.get_help() { match value.get_help() {
@ -295,5 +326,5 @@ fn format_possible_values(possibles: &Vec<&clap::builder::PossibleValue>) -> Vec
} else { } else {
lines.append(&mut possibles.iter().map(|p| p.get_name().to_string()).collect()); lines.append(&mut possibles.iter().map(|p| p.get_name().to_string()).collect());
} }
lines (lines, with_help)
} }

View file

@ -281,7 +281,7 @@ pub fn assert_matches_path(expected_path: impl AsRef<std::path::Path>, cmd: clap
.matches_path(expected_path, buf); .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) clap::Command::new(name)
.trailing_var_arg(true) .trailing_var_arg(true)
.arg( .arg(
@ -292,12 +292,24 @@ pub fn possible_values_command(name: &'static str) -> clap::Command<'static> {
) )
.arg( .arg(
clap::Arg::new("method") clap::Arg::new("method")
.long("method") .long("method")
.action(clap::ArgAction::Set) .action(clap::ArgAction::Set)
.value_parser([ .value_parser([
PossibleValue::new("fast").help("use the Fast method"), PossibleValue::new("fast").help("use the Fast method"),
PossibleValue::new("slow").help("use the slow method"), PossibleValue::new("slow").help("use the slow method"),
PossibleValue::new("normal").help("use normal mode").hide(true) 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),
]),
) )
} }

View file

@ -23,6 +23,8 @@ some input file
.TP .TP
[/fIchoice/fR] [/fIchoice/fR]
.br
[/fIpossible values: /fRfirst, second]
.SH SUBCOMMANDS .SH SUBCOMMANDS
.TP .TP
my/-app/-test(1) my/-app/-test(1)

View file

@ -4,14 +4,14 @@
.SH NAME .SH NAME
my/-app my/-app
.SH SYNOPSIS .SH SYNOPSIS
/fBmy/-app/fR [/fB/-/-choice/fR] [/fB/-/-method/fR] [/fB/-h/fR|/fB/-/-help/fR] /fBmy/-app/fR [/fB/-/-choice/fR] [/fB/-/-method/fR] [/fB/-h/fR|/fB/-/-help/fR] [/fIpositional_choice/fR]
.SH DESCRIPTION .SH DESCRIPTION
.SH OPTIONS .SH OPTIONS
.TP .TP
/fB/-/-choice/fR /fB/-/-choice/fR
.br .br
/fI[possible values: /fRbash, fish, zsh] [/fIpossible values: /fRbash, fish, zsh]
.TP .TP
/fB/-/-method/fR /fB/-/-method/fR
@ -26,3 +26,16 @@ slow: use the slow method
.TP .TP
/fB/-h/fR, /fB/-/-help/fR /fB/-h/fR, /fB/-/-help/fR
Print help information Print help information
.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

View file

@ -23,6 +23,8 @@ some input file
.TP .TP
[/fIchoice/fR] [/fIchoice/fR]
.br
[/fIpossible values: /fRfirst, second]
.SH SUBCOMMANDS .SH SUBCOMMANDS
.TP .TP
my/-app/-test(1) my/-app/-test(1)

View file

@ -23,6 +23,8 @@ some input file
.TP .TP
[/fIchoice/fR] [/fIchoice/fR]
.br
[/fIpossible values: /fRfirst, second]
.SH SUBCOMMANDS .SH SUBCOMMANDS
.TP .TP
my/-app/-test(1) my/-app/-test(1)

View file

@ -11,7 +11,7 @@ my/-app
/fB/-/-choice/fR /fB/-/-choice/fR
.br .br
/fI[possible values: /fRbash, fish, zsh] [/fIpossible values: /fRbash, fish, zsh]
.TP .TP
/fB/-/-unknown/fR /fB/-/-unknown/fR