Skip to content

Commit 3f70e85

Browse files
committed
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 <mail@aparcar.org>
1 parent a216137 commit 3f70e85

File tree

3 files changed

+95
-14
lines changed

3 files changed

+95
-14
lines changed

clap_mangen/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,11 @@ impl Man {
258258
fn _render_subcommands_section(&self, roff: &mut Roff) {
259259
let heading = subcommand_heading(&self.cmd);
260260
roff.control("SH", [heading]);
261-
render::subcommands(roff, &self.cmd, &self.section);
261+
if self.cmd.is_flatten_help_set() {
262+
render::flat_subcommands(roff, &self.cmd);
263+
} else {
264+
render::subcommands(roff, &self.cmd, &self.section);
265+
}
262266
}
263267

264268
/// Render the EXTRA section into the writer.

clap_mangen/src/render.rs

+61-13
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ pub(crate) fn description(roff: &mut Roff, cmd: &clap::Command) {
2929
}
3030
}
3131

32-
pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
33-
let name = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name());
32+
pub(crate) fn command_with_args(cmd: &clap::Command, name: String) -> Vec<Inline> {
3433
let mut line = vec![bold(name), roman(" ")];
35-
3634
for opt in cmd.get_arguments().filter(|i| !i.is_hide_set()) {
3735
let (lhs, rhs) = option_markers(opt);
3836
match (opt.get_short(), opt.get_long()) {
@@ -74,18 +72,46 @@ pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
7472
line.push(roman(" "));
7573
}
7674

77-
if cmd.has_subcommands() {
78-
let (lhs, rhs) = subcommand_markers(cmd);
79-
line.push(roman(lhs));
80-
line.push(italic(
81-
cmd.get_subcommand_value_name()
82-
.unwrap_or_else(|| subcommand_heading(cmd))
83-
.to_lowercase(),
84-
));
85-
line.push(roman(rhs));
75+
line
76+
}
77+
78+
pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
79+
let name = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name());
80+
let flatten = cmd.is_flatten_help_set();
81+
82+
let mut ord_v = Vec::new();
83+
if flatten {
84+
for subcommand in cmd.get_subcommands() {
85+
ord_v.push((
86+
subcommand.get_display_order(),
87+
format!("{} {}", name, subcommand.get_name().to_owned()),
88+
subcommand,
89+
));
90+
}
91+
ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1)));
92+
} else {
93+
ord_v.push((cmd.get_display_order(), name.to_string(), cmd))
8694
}
8795

88-
roff.text(line);
96+
for (_, name, cmd) in ord_v {
97+
let mut line = command_with_args(cmd, name);
98+
99+
if cmd.has_subcommands() && !flatten {
100+
let (lhs, rhs) = subcommand_markers(cmd);
101+
line.push(roman(lhs));
102+
line.push(italic(
103+
cmd.get_subcommand_value_name()
104+
.unwrap_or_else(|| subcommand_heading(cmd))
105+
.to_lowercase(),
106+
));
107+
line.push(roman(rhs));
108+
}
109+
roff.text(line);
110+
111+
if flatten {
112+
roff.control("br", []);
113+
}
114+
}
89115
}
90116

91117
pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
@@ -220,6 +246,28 @@ pub(crate) fn subcommands(roff: &mut Roff, cmd: &clap::Command, section: &str) {
220246
}
221247
}
222248

249+
pub(crate) fn flat_subcommands(roff: &mut Roff, cmd: &clap::Command) {
250+
for sub in cmd.get_subcommands().filter(|s| !s.is_hide_set()) {
251+
roff.control("TP", []);
252+
253+
let name = sub.get_name().to_string();
254+
255+
let mut line = command_with_args(sub, name);
256+
257+
if let Some(about) = sub.get_long_about().or_else(|| sub.get_about()) {
258+
line.push(roman("\n"));
259+
line.push(roman(about.to_string()));
260+
}
261+
262+
if let Some(after_help) = sub.get_after_help() {
263+
line.push(roman("\n"));
264+
line.push(roman(after_help.to_string()));
265+
}
266+
267+
roff.text(line);
268+
}
269+
}
270+
223271
pub(crate) fn version(cmd: &clap::Command) -> String {
224272
format!(
225273
"v{}",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.ie \n(.g .ds Aq \(aq
2+
.el .ds Aq '
3+
.TH my-app 1 "my-app "
4+
.SH NAME
5+
my\-app
6+
.SH SYNOPSIS
7+
\fBmy\-app test\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
8+
.br
9+
\fBmy\-app help\fR
10+
.br
11+
.SH DESCRIPTION
12+
.SH OPTIONS
13+
.TP
14+
\fB\-c\fR
15+
16+
.TP
17+
\fB\-v\fR
18+
19+
.TP
20+
\fB\-h\fR, \fB\-\-help\fR
21+
Print help
22+
.SH SUBCOMMANDS
23+
.TP
24+
\fBtest\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
25+
Subcommand
26+
with a second line
27+
.TP
28+
\fBhelp\fR
29+
Print this message or the help of the given subcommand(s)

0 commit comments

Comments
 (0)