Skip to content

Commit 911cb8c

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 `(SUB)COMMANDS` are changed to imitate the style of `git stash --help`. Signed-off-by: Paul Spooren <[email protected]>
1 parent 61ebe72 commit 911cb8c

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

clap_mangen/src/lib.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,14 @@ impl Man {
221221

222222
fn _render_synopsis_section(&self, roff: &mut Roff) {
223223
roff.control("SH", ["SYNOPSIS"]);
224-
render::synopsis(roff, &self.cmd);
224+
if self.cmd.is_flatten_help_set() {
225+
for sc in self.cmd.get_subcommands() {
226+
render::synopsis(roff, sc);
227+
roff.control("br", []);
228+
}
229+
} else {
230+
render::synopsis(roff, &self.cmd);
231+
}
225232
}
226233

227234
/// Render the DESCRIPTION section into the writer.
@@ -251,7 +258,11 @@ impl Man {
251258
/// Render the SUBCOMMANDS section into the writer.
252259
pub fn render_subcommands_section(&self, w: &mut dyn Write) -> Result<(), std::io::Error> {
253260
let mut roff = Roff::default();
254-
self._render_subcommands_section(&mut roff);
261+
if self.cmd.is_flatten_help_set() {
262+
self._render_flat_subcommands_section(&mut roff);
263+
} else {
264+
self._render_subcommands_section(&mut roff);
265+
}
255266
roff.to_writer(w)
256267
}
257268

@@ -261,6 +272,11 @@ impl Man {
261272
render::subcommands(roff, &self.cmd, &self.section);
262273
}
263274

275+
fn _render_flat_subcommands_section(&self, roff: &mut Roff) {
276+
roff.control("SH", ["COMMANDS"]);
277+
render::flat_subcommands(roff, &self.cmd, &self.section);
278+
}
279+
264280
/// Render the EXTRA section into the writer.
265281
pub fn render_extra_section(&self, w: &mut dyn Write) -> Result<(), std::io::Error> {
266282
let mut roff = Roff::default();

clap_mangen/src/render.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
7474
line.push(roman(" "));
7575
}
7676

77-
if cmd.has_subcommands() {
77+
if cmd.has_subcommands() && !cmd.is_flatten_help_set() {
7878
let (lhs, rhs) = subcommand_markers(cmd);
7979
line.push(roman(lhs));
8080
line.push(italic(
@@ -220,6 +220,71 @@ pub(crate) fn subcommands(roff: &mut Roff, cmd: &clap::Command, section: &str) {
220220
}
221221
}
222222

223+
pub(crate) fn flat_subcommands(roff: &mut Roff, cmd: &clap::Command, section: &str) {
224+
for sub in cmd.get_subcommands().filter(|s| !s.is_hide_set()) {
225+
roff.control("TP", []);
226+
227+
let name = sub.get_name();
228+
let mut line = vec![bold(name), roman(" ")];
229+
230+
for opt in sub.get_arguments().filter(|i| !i.is_hide_set()) {
231+
if opt.get_short() == Some('h') || opt.get_long() == Some("help") {
232+
continue;
233+
}
234+
let (lhs, rhs) = option_markers(opt);
235+
match (opt.get_short(), opt.get_long()) {
236+
(Some(short), Some(long)) => {
237+
line.push(roman(lhs));
238+
line.push(bold(format!("-{short}")));
239+
line.push(roman("|"));
240+
line.push(bold(format!("--{long}",)));
241+
line.push(roman(rhs));
242+
}
243+
(Some(short), None) => {
244+
line.push(roman(lhs));
245+
line.push(bold(format!("-{short} ")));
246+
line.push(roman(rhs));
247+
}
248+
(None, Some(long)) => {
249+
line.push(roman(lhs));
250+
line.push(bold(format!("--{long}")));
251+
line.push(roman(rhs));
252+
}
253+
(None, None) => continue,
254+
};
255+
256+
if matches!(opt.get_action(), ArgAction::Count) {
257+
line.push(roman("..."));
258+
}
259+
line.push(roman(" "));
260+
}
261+
262+
for arg in sub.get_positionals() {
263+
let (lhs, rhs) = option_markers(arg);
264+
line.push(roman(lhs));
265+
if let Some(value) = arg.get_value_names() {
266+
line.push(italic(value.join(" ")));
267+
} else {
268+
line.push(italic(arg.get_id().as_str()));
269+
}
270+
line.push(roman(rhs));
271+
line.push(roman(" "));
272+
}
273+
274+
if let Some(about) = sub.get_long_about().or_else(|| sub.get_about()) {
275+
line.push(roman("\n"));
276+
line.push(roman(about.to_string()));
277+
}
278+
279+
if let Some(after_help) = sub.get_after_help() {
280+
line.push(roman("\n"));
281+
line.push(roman(after_help.to_string()));
282+
}
283+
284+
roff.text(line);
285+
}
286+
}
287+
223288
pub(crate) fn version(cmd: &clap::Command) -> String {
224289
format!(
225290
"v{}",

0 commit comments

Comments
 (0)