You've already forked uutils-args
mirror of
https://github.com/uutils/uutils-args.git
synced 2026-06-10 16:13:08 -07:00
value hints in completions
This commit is contained in:
@@ -30,6 +30,7 @@ fn render_value_hint(value: &ValueHint) -> String {
|
||||
let joined = s.join(", ");
|
||||
format!(" -a {{ {joined} }}")
|
||||
}
|
||||
ValueHint::Unknown => String::new(),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::{
|
||||
|
||||
pub struct Argument {
|
||||
pub ident: Ident,
|
||||
pub field: Option<syn::Type>,
|
||||
pub name: String,
|
||||
pub arg_type: ArgType,
|
||||
pub help: String,
|
||||
@@ -105,6 +106,7 @@ pub fn parse_argument(v: Variant) -> Vec<Argument> {
|
||||
};
|
||||
Argument {
|
||||
ident: ident.clone(),
|
||||
field: field.clone(),
|
||||
name: name.clone(),
|
||||
arg_type,
|
||||
help: arg_help,
|
||||
|
||||
+16
-2
@@ -11,7 +11,13 @@ use quote::quote;
|
||||
pub fn complete(args: &[Argument]) -> TokenStream {
|
||||
let mut arg_specs = Vec::new();
|
||||
|
||||
for Argument { help, arg_type, .. } in args {
|
||||
for Argument {
|
||||
help,
|
||||
field,
|
||||
arg_type,
|
||||
..
|
||||
} in args
|
||||
{
|
||||
let ArgType::Option {
|
||||
flags,
|
||||
hidden: false,
|
||||
@@ -25,21 +31,29 @@ pub fn complete(args: &[Argument]) -> TokenStream {
|
||||
if short.is_empty() && long.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let short: Vec<_> = short
|
||||
.iter()
|
||||
.map(|Flag { flag, .. }| quote!(String::from(#flag)))
|
||||
.collect();
|
||||
|
||||
let long: Vec<_> = long
|
||||
.iter()
|
||||
.map(|Flag { flag, .. }| quote!(String::from(#flag)))
|
||||
.collect();
|
||||
|
||||
let hint = if let Some(ty) = field {
|
||||
quote!(Some(<#ty>::value_hint()))
|
||||
} else {
|
||||
quote!(None)
|
||||
};
|
||||
|
||||
arg_specs.push(quote!(
|
||||
Arg {
|
||||
short: vec![#(#short),*],
|
||||
long: vec![#(#long),*],
|
||||
help: String::from(#help),
|
||||
value: None,
|
||||
value: #hint,
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ pub struct Flags {
|
||||
pub dd_style: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum Value {
|
||||
No,
|
||||
Optional(String),
|
||||
|
||||
@@ -109,6 +109,7 @@ pub fn arguments(input: TokenStream) -> TokenStream {
|
||||
#[cfg(feature = "complete")]
|
||||
fn complete() -> ::uutils_args_complete::Command {
|
||||
use ::uutils_args_complete::{Command, Arg, ValueHint};
|
||||
use ::uutils_args::Value;
|
||||
#completion
|
||||
}
|
||||
}
|
||||
@@ -131,6 +132,7 @@ pub fn value(input: TokenStream) -> TokenStream {
|
||||
let mut options = Vec::new();
|
||||
|
||||
let mut match_arms = vec![];
|
||||
let mut all_keys = Vec::new();
|
||||
for variant in data.variants {
|
||||
let variant_name = variant.ident.to_string();
|
||||
let attrs = variant.attrs.clone();
|
||||
@@ -147,6 +149,7 @@ pub fn value(input: TokenStream) -> TokenStream {
|
||||
keys
|
||||
};
|
||||
|
||||
all_keys.extend(keys.clone());
|
||||
options.push(quote!(&[#(#keys),*]));
|
||||
|
||||
let stmt = if let Some(v) = value {
|
||||
@@ -195,6 +198,16 @@ pub fn value(input: TokenStream) -> TokenStream {
|
||||
_ => unreachable!("Should be caught by (None, []) case above.")
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "complete")]
|
||||
fn value_hint() -> ::uutils_args_complete::ValueHint {
|
||||
::uutils_args_complete::ValueHint::Strings(
|
||||
[#(#all_keys),*]
|
||||
.into_iter()
|
||||
.map(ToString::to_string)
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
use uutils_args::{Arguments, Options, Value};
|
||||
|
||||
#[derive(Arguments)]
|
||||
#[arguments(file = "examples/hello_world_help.md")]
|
||||
enum Arg {
|
||||
/// Color!
|
||||
#[arg("-c NAME", "--color=NAME")]
|
||||
Color(Color),
|
||||
}
|
||||
|
||||
#[derive(Value, Debug, Default)]
|
||||
enum Color {
|
||||
#[value("never")]
|
||||
Never,
|
||||
#[default]
|
||||
#[value("auto")]
|
||||
Auto,
|
||||
#[value("always")]
|
||||
Always,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Settings {
|
||||
color: Color,
|
||||
}
|
||||
|
||||
impl Options<Arg> for Settings {
|
||||
fn apply(&mut self, arg: Arg) {
|
||||
match arg {
|
||||
Arg::Color(c) => self.color = c,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let color = Settings::default().parse(std::env::args_os()).color;
|
||||
println!("{:?}", color);
|
||||
}
|
||||
Reference in New Issue
Block a user