Skip to content

Commit

Permalink
fix(derive): Allow 'long_help' to force populating from doc comment
Browse files Browse the repository at this point in the history
Fixes #4441
  • Loading branch information
epage committed Nov 7, 2022
1 parent 8751152 commit c37ab6c
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 11 deletions.
4 changes: 4 additions & 0 deletions clap_derive/src/attr.rs
Expand Up @@ -105,6 +105,8 @@ impl Parse for ClapAttr {
"external_subcommand" => Some(MagicAttrName::ExternalSubcommand),
"verbatim_doc_comment" => Some(MagicAttrName::VerbatimDocComment),
"about" => Some(MagicAttrName::About),
"long_about" => Some(MagicAttrName::LongAbout),
"long_help" => Some(MagicAttrName::LongHelp),
"author" => Some(MagicAttrName::Author),
"version" => Some(MagicAttrName::Version),
_ => None,
Expand Down Expand Up @@ -160,6 +162,8 @@ pub enum MagicAttrName {
VerbatimDocComment,
ExternalSubcommand,
About,
LongAbout,
LongHelp,
Author,
Version,
RenameAllEnv,
Expand Down
19 changes: 18 additions & 1 deletion clap_derive/src/item.rs
Expand Up @@ -43,6 +43,7 @@ pub struct Item {
value_parser: Option<ValueParser>,
action: Option<Action>,
verbatim_doc_comment: bool,
force_long_help: bool,
next_display_order: Option<Method>,
next_help_heading: Option<Method>,
is_enum: bool,
Expand Down Expand Up @@ -266,6 +267,7 @@ impl Item {
value_parser: None,
action: None,
verbatim_doc_comment: false,
force_long_help: false,
next_display_order: None,
next_help_heading: None,
is_enum: false,
Expand Down Expand Up @@ -504,6 +506,18 @@ impl Item {
}
}

Some(MagicAttrName::LongAbout) if attr.value.is_none() => {
assert_attr_kind(attr, &[AttrKind::Command]);

self.force_long_help = true;
}

Some(MagicAttrName::LongHelp) if attr.value.is_none() => {
assert_attr_kind(attr, &[AttrKind::Arg]);

self.force_long_help = true;
}

Some(MagicAttrName::Author) if attr.value.is_none() => {
assert_attr_kind(attr, &[AttrKind::Command]);

Expand Down Expand Up @@ -820,6 +834,8 @@ impl Item {
| Some(MagicAttrName::Long)
| Some(MagicAttrName::Env)
| Some(MagicAttrName::About)
| Some(MagicAttrName::LongAbout)
| Some(MagicAttrName::LongHelp)
| Some(MagicAttrName::Author)
| Some(MagicAttrName::Version)
=> {
Expand Down Expand Up @@ -873,7 +889,8 @@ impl Item {
let lines = extract_doc_comment(attrs);

if !lines.is_empty() {
let (short_help, long_help) = format_doc_comment(&lines, !self.verbatim_doc_comment);
let (short_help, long_help) =
format_doc_comment(&lines, !self.verbatim_doc_comment, self.force_long_help);
let short_name = format_ident!("{}", short_name);
let short = Method::new(
short_name,
Expand Down
20 changes: 14 additions & 6 deletions clap_derive/src/utils/doc_comments.rs
Expand Up @@ -47,7 +47,11 @@ pub fn extract_doc_comment(attrs: &[syn::Attribute]) -> Vec<String> {
lines
}

pub fn format_doc_comment(lines: &[String], preprocess: bool) -> (Option<String>, Option<String>) {
pub fn format_doc_comment(
lines: &[String],
preprocess: bool,
force_long: bool,
) -> (Option<String>, Option<String>) {
if let Some(first_blank) = lines.iter().position(|s| is_blank(s)) {
let (short, long) = if preprocess {
let paragraphs = split_paragraphs(lines);
Expand All @@ -62,14 +66,18 @@ pub fn format_doc_comment(lines: &[String], preprocess: bool) -> (Option<String>

(Some(short), Some(long))
} else {
let short = if preprocess {
let s = merge_lines(lines);
remove_period(s)
let (short, long) = if preprocess {
let short = merge_lines(lines);
let long = force_long.then(|| short.clone());
let short = remove_period(short);
(short, long)
} else {
lines.join("\n")
let short = lines.join("\n");
let long = force_long.then(|| short.clone());
(short, long)
};

(Some(short), None)
(Some(short), long)
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/_derive/mod.rs
Expand Up @@ -154,8 +154,9 @@
//! - **TIP:** When a doc comment is also present, you most likely want to add
//! `#[arg(long_about = None)]` to clear the doc comment so only [`about`][crate::Command::about]
//! gets shown with both `-h` and `--help`.
//! - `long_about = <expr>`: [`Command::long_about`][crate::Command::long_about]
//! - `long_about[ = <expr>]`: [`Command::long_about`][crate::Command::long_about]
//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
//! - When present without a value: [Doc comment](#doc-comments)
//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`about`][crate::Command::about] / [`long_about`][crate::Command::long_about]
//! - `next_display_order`: [`Command::next_display_order`][crate::Command::next_display_order]
//! - `next_help_heading`: [`Command::next_help_heading`][crate::Command::next_help_heading]
Expand Down Expand Up @@ -200,8 +201,9 @@
//! - When not present: will auto-select an action based on the field type
//! - `help = <expr>`: [`Arg::help`][crate::Arg::help]
//! - When not present: [Doc comment summary](#doc-comments)
//! - `long_help = <expr>`: [`Arg::long_help`][crate::Arg::long_help]
//! - `long_help[ = <expr>]`: [`Arg::long_help`][crate::Arg::long_help]
//! - When not present: [Doc comment](#doc-comments) if there is a blank line, else nothing
//! - When present without a value: [Doc comment](#doc-comments)
//! - `verbatim_doc_comment`: Minimizes pre-processing when converting doc comments to [`help`][crate::Arg::help] / [`long_help`][crate::Arg::long_help]
//! - `short [= <char>]`: [`Arg::short`][crate::Arg::short]
//! - When not present: no short set
Expand Down
4 changes: 2 additions & 2 deletions tests/derive/doc_comments_help.rs
Expand Up @@ -296,10 +296,10 @@ fn force_long_help() {
struct LoremIpsum {
/// Fooify a bar
/// and a baz.
#[arg(short, long)]
#[arg(short, long, long_help)]
foo: bool,
}

let help = utils::get_long_help::<LoremIpsum>();
assert!(help.contains("Fooify a bar and a baz"));
assert!(help.contains("Fooify a bar and a baz."));
}

0 comments on commit c37ab6c

Please sign in to comment.