summaryrefslogtreecommitdiff
path: root/macros/comp_system_macros/src/lib.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-03-26 15:55:10 +0800
committer魏曹先生 <1992414357@qq.com>2026-03-26 15:55:10 +0800
commitfb2ffa849a2cf9251cc274ebea5daa9898579787 (patch)
tree53b87ee60ba7c6ee7b001221855a6f3bff7e8526 /macros/comp_system_macros/src/lib.rs
parent4cb7c2e91d7dbde32de31e6ab48683d60212ec1d (diff)
Add shell completion system with descriptions and i18n support
Diffstat (limited to 'macros/comp_system_macros/src/lib.rs')
-rw-r--r--macros/comp_system_macros/src/lib.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/macros/comp_system_macros/src/lib.rs b/macros/comp_system_macros/src/lib.rs
new file mode 100644
index 0000000..dd1fb01
--- /dev/null
+++ b/macros/comp_system_macros/src/lib.rs
@@ -0,0 +1,73 @@
+use proc_macro::TokenStream;
+use proc_macro2::TokenStream as TokenStream2;
+use quote::quote;
+use syn::parse::{Parse, ParseStream};
+use syn::punctuated::Punctuated;
+use syn::{Expr, LitStr, Token, parse_macro_input};
+
+struct SuggestInput {
+ items: Punctuated<SuggestItem, Token![,]>,
+}
+
+enum SuggestItem {
+ WithDesc(Box<(LitStr, Expr)>), // "-i" = "Insert something"
+ Simple(LitStr), // "-I"
+}
+
+impl Parse for SuggestInput {
+ fn parse(input: ParseStream) -> syn::Result<Self> {
+ let items = Punctuated::parse_terminated(input)?;
+ Ok(SuggestInput { items })
+ }
+}
+
+impl Parse for SuggestItem {
+ fn parse(input: ParseStream) -> syn::Result<Self> {
+ let key: LitStr = input.parse()?;
+
+ if input.peek(Token![=]) {
+ let _eq: Token![=] = input.parse()?;
+ let value: Expr = input.parse()?;
+ Ok(SuggestItem::WithDesc(Box::new((key, value))))
+ } else {
+ Ok(SuggestItem::Simple(key))
+ }
+ }
+}
+
+#[proc_macro]
+pub fn suggest(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as SuggestInput);
+
+ let mut tokens = TokenStream2::new();
+
+ tokens.extend(quote! {
+ CompletionResult::empty_comp()
+ });
+
+ for item in input.items {
+ match item {
+ SuggestItem::WithDesc(boxed) => {
+ let (key, value) = *boxed;
+ tokens.extend(quote! {
+ .with_suggest_desc(#key, #value)
+ });
+ }
+ SuggestItem::Simple(key) => {
+ tokens.extend(quote! {
+ .with_suggest(#key)
+ });
+ }
+ }
+ }
+
+ tokens.into()
+}
+
+#[proc_macro]
+pub fn file_suggest(_input: TokenStream) -> TokenStream {
+ quote! {
+ CompletionResult::file_comp()
+ }
+ .into()
+}