diff --git a/complete/src/fish.rs b/complete/src/fish.rs index d6f0f66..e2a49f2 100644 --- a/complete/src/fish.rs +++ b/complete/src/fish.rs @@ -108,6 +108,7 @@ mod test { value: Value::No, }], long: vec![], + dd_style: vec![], help: "some flag", value: Some(hint), }], diff --git a/complete/src/lib.rs b/complete/src/lib.rs index 5d8649c..ab2a4eb 100644 --- a/complete/src/lib.rs +++ b/complete/src/lib.rs @@ -41,6 +41,7 @@ pub struct Command<'a> { pub struct Arg<'a> { pub short: Vec>, pub long: Vec>, + pub dd_style: Vec<(&'a str, &'a str)>, pub help: &'a str, pub value: Option, } diff --git a/complete/src/man.rs b/complete/src/man.rs index 046cf08..d381c59 100644 --- a/complete/src/man.rs +++ b/complete/src/man.rs @@ -54,6 +54,14 @@ pub fn render(c: &Command) -> String { Value::No => {} } } + for (flag, value) in &arg.dd_style { + if !flags.is_empty() { + flags.push(roman(", ")); + } + flags.push(bold(*flag)); + flags.push(roman("=")); + flags.push(italic(*value)); + } page.text(flags); page.text([roman(arg.help)]); } diff --git a/complete/src/md.rs b/complete/src/md.rs index 1c2fa1b..fcc80a3 100644 --- a/complete/src/md.rs +++ b/complete/src/md.rs @@ -58,6 +58,10 @@ fn options(c: &Command) -> String { flags.push(format!("-{flag}{value_str}")); } + for (flag, value) in &arg.dd_style { + flags.push(format!("{flag}={value}")); + } + out.push_str(&flags.join(", ")); out.push_str("\n"); out.push_str(&format!("
\n\n{}\n\n
\n", arg.help)); diff --git a/derive/src/complete.rs b/derive/src/complete.rs index 10b9691..6d00b9e 100644 --- a/derive/src/complete.rs +++ b/derive/src/complete.rs @@ -33,16 +33,21 @@ pub fn complete(args: &[Argument], file: &Option) -> TokenStream { continue; }; - let Flags { short, long, .. } = flags; - if short.is_empty() && long.is_empty() { + let Flags { + short, + long, + dd_style, + } = flags; + if short.is_empty() && long.is_empty() && dd_style.is_empty() { continue; } // If none of the flags take an argument, we won't need ValueHint // based on that type. So we should not attempt to call `value_hint` // on it. - let any_flag_takes_argument = - short.iter().any(|f| f.value != Value::No) && long.iter().any(|f| f.value != Value::No); + let any_flag_takes_argument = !dd_style.is_empty() + && short.iter().any(|f| f.value != Value::No) + && long.iter().any(|f| f.value != Value::No); let short: Vec<_> = short .iter() @@ -75,6 +80,11 @@ pub fn complete(args: &[Argument], file: &Option) -> TokenStream { }) .collect(); + let dd_style: Vec<_> = dd_style + .iter() + .map(|(flag, value)| quote!((#flag, #value))) + .collect(); + let hint = match (field, any_flag_takes_argument) { (Some(ty), true) => quote!(Some(<#ty>::value_hint())), _ => quote!(None), @@ -84,6 +94,7 @@ pub fn complete(args: &[Argument], file: &Option) -> TokenStream { ::uutils_args_complete::Arg { short: vec![#(#short),*], long: vec![#(#long),*], + dd_style: vec![#(#dd_style),*], help: #help, value: #hint, } diff --git a/examples/completion.rs b/examples/completion.rs index 112cc60..45cf783 100644 --- a/examples/completion.rs +++ b/examples/completion.rs @@ -27,6 +27,10 @@ enum Arg { /// Give it a path! #[arg("-p P", "--path=P")] Path(PathBuf), + + /// A dd_style argument! + #[arg("if=file")] + File(PathBuf), } struct Settings;