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`.

Signed-off-by: Paul Spooren <[email protected]>
  • Loading branch information
aparcar committed Oct 17, 2024
1 parent d70ef84 commit 5094ea2
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 17 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
71 changes: 58 additions & 13 deletions clap_mangen/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,46 @@ 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(),
let flatten = cmd.is_flatten_help_set();

let mut ord_v = Vec::new();
if flatten {
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)));
} else {
ord_v.push((
cmd.get_display_order(),
cmd.get_bin_name().unwrap_or_else(|| cmd.get_name()),
cmd,
));
line.push(roman(rhs));
}
roff.text(line);

let mut first = true;
for (_, name, cmd) in ord_v {
if !first && flatten {
roff.control("br", []);
} else {
first = false;
}
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));
}
roff.text(line);
}
}

Expand Down Expand Up @@ -226,6 +251,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
8 changes: 5 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,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 5094ea2

Please sign in to comment.