Skip to content

Commit

Permalink
feat(mangen): Support flatten_help
Browse files Browse the repository at this point in the history
The `flatten_help` argument combines all subcommands on a single page.
Until now this wasn't supported for `mangen`. With this command the
sections `SYNOPSIS` as well as `SUBCOMMANDS` are changed to imitate the
style of `git stash --help`.

Differences between flattened `--help` and the flattened man:
* `--help` prints the description at the very beginning while Man uses a
  section called DESCRIPTION below the USAGE.
* `--help` prints placeholder `[OPTIONS]` while Man prints all options
* `--help` prints positional options (aka arguments) in its own section
  called arguments while Man prints them at the end of OPTIONS.
* `--help` prints subcommands as their own section after the options
  section while Man uses an extra section called SUBCOMMANDS
* `--help` prints `after_long_help` at the very end while Man uses the
  section EXTRA which comes before the sections VERSION and AUTHORS

Signed-off-by: Paul Spooren <[email protected]>
  • Loading branch information
aparcar committed Oct 23, 2024
1 parent cec57c8 commit e19c5b5
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 21 deletions.
6 changes: 5 additions & 1 deletion clap_mangen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,11 @@ impl Man {
fn _render_subcommands_section(&self, roff: &mut Roff) {
let heading = subcommand_heading(&self.cmd);
roff.control("SH", [heading]);
render::subcommands(roff, &self.cmd, &self.section);
if self.cmd.is_flatten_help_set() {
render::flat_subcommands(roff, &self.cmd);
} else {
render::subcommands(roff, &self.cmd, &self.section);
}
}

/// Render the EXTRA section into the writer.
Expand Down
68 changes: 54 additions & 14 deletions clap_mangen/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,41 @@ pub(crate) fn description(roff: &mut Roff, cmd: &clap::Command) {
}

pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
let name = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name());
let mut line = vec![bold(name), roman(" ")];
let mut line = usage(cmd, name);

if cmd.has_subcommands() && !flatten {
let (lhs, rhs) = subcommand_markers(cmd);
line.push(roman(lhs));
line.push(italic(
cmd.get_subcommand_value_name()
.unwrap_or_else(|| subcommand_heading(cmd))
.to_lowercase(),
));
line.push(roman(rhs));
let flatten = cmd.is_flatten_help_set();
let mut first = true;
if !cmd.is_subcommand_required_set() || cmd.is_args_conflicts_with_subcommands_set() {
let mut line = usage(cmd, cmd.get_bin_name().unwrap_or_else(|| cmd.get_name()));
if cmd.has_subcommands() && !flatten {
let (lhs, rhs) = subcommand_markers(cmd);
line.push(roman(lhs));
line.push(italic(
cmd.get_subcommand_value_name()
.unwrap_or_else(|| subcommand_heading(cmd))
.to_lowercase(),
));
line.push(roman(rhs));
}
roff.text(line);
first = false;
}
roff.text(line);
if flatten {
let mut ord_v = Vec::new();
for subcommand in cmd.get_subcommands() {
ord_v.push((
subcommand.get_display_order(),
subcommand.get_bin_name().unwrap_or_else(|| cmd.get_name()),
subcommand,
));
}
ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1)));
for (_, name, cmd) in ord_v {
if !first {
roff.control("br", []);
} else {
first = false;
}
roff.text(usage(cmd, name));
}
}
}

Expand Down Expand Up @@ -226,6 +246,26 @@ pub(crate) fn subcommands(roff: &mut Roff, cmd: &clap::Command, section: &str) {
}
}

pub(crate) fn flat_subcommands(roff: &mut Roff, cmd: &clap::Command) {
for sub in cmd.get_subcommands().filter(|s| !s.is_hide_set()) {
roff.control("TP", []);

let mut line = usage(sub, sub.get_name());

if let Some(about) = sub.get_long_about().or_else(|| sub.get_about()) {
line.push(roman("\n"));
line.push(roman(about.to_string()));
}

if let Some(after_help) = sub.get_after_help() {
line.push(roman("\n"));
line.push(roman(after_help.to_string()));
}

roff.text(line);
}
}

pub(crate) fn version(cmd: &clap::Command) -> String {
format!(
"v{}",
Expand Down
10 changes: 7 additions & 3 deletions clap_mangen/tests/snapshots/flatten_help.roff
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
.SH NAME
my\-app
.SH SYNOPSIS
\fBmy\-app\fR [\fB\-c \fR] [\fB\-v \fR] [\fB\-h\fR|\fB\-\-help\fR] [\fIsubcommands\fR]
\fBmy\-app\fR [\fB\-c \fR] [\fB\-v \fR] [\fB\-h\fR|\fB\-\-help\fR]
.br
\fBmy\-app test\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
.br
\fBmy\-app help\fR
.SH DESCRIPTION
.SH OPTIONS
.TP
Expand All @@ -18,9 +22,9 @@ my\-app
Print help
.SH SUBCOMMANDS
.TP
my\-app\-test(1)
\fBtest\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
Subcommand
with a second line
.TP
my\-app\-help(1)
\fBhelp\fR
Print this message or the help of the given subcommand(s)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
.SH NAME
my\-app
.SH SYNOPSIS
\fBmy\-app\fR [\fB\-c \fR] [\fB\-v \fR] [\fB\-h\fR|\fB\-\-help\fR] <\fIsubcommands\fR>
\fBmy\-app test\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
.br
\fBmy\-app help\fR
.SH DESCRIPTION
.SH OPTIONS
.TP
Expand All @@ -18,9 +20,9 @@ my\-app
Print help
.SH SUBCOMMANDS
.TP
my\-app\-test(1)
\fBtest\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
Subcommand
with a second line
.TP
my\-app\-help(1)
\fBhelp\fR
Print this message or the help of the given subcommand(s)

0 comments on commit e19c5b5

Please sign in to comment.