From 5094ea2547269847a2bea94e0ffd434da6db78fe Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Thu, 17 Oct 2024 14:58:06 +0200 Subject: [PATCH] feat(mangen): Support flatten_help 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 --- clap_mangen/src/lib.rs | 6 +- clap_mangen/src/render.rs | 71 +++++++++++++++---- clap_mangen/tests/snapshots/flatten_help.roff | 8 ++- 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/clap_mangen/src/lib.rs b/clap_mangen/src/lib.rs index 7b8d8af79004..b9fbdb76d1ad 100644 --- a/clap_mangen/src/lib.rs +++ b/clap_mangen/src/lib.rs @@ -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. diff --git a/clap_mangen/src/render.rs b/clap_mangen/src/render.rs index 009750a7ff03..4b0dda74558a 100644 --- a/clap_mangen/src/render.rs +++ b/clap_mangen/src/render.rs @@ -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); } } @@ -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{}", diff --git a/clap_mangen/tests/snapshots/flatten_help.roff b/clap_mangen/tests/snapshots/flatten_help.roff index e9ab64a9d6fc..e2dd9cc9a9f1 100644 --- a/clap_mangen/tests/snapshots/flatten_help.roff +++ b/clap_mangen/tests/snapshots/flatten_help.roff @@ -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 @@ -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)