aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros/src/lib.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-04-10 16:47:40 +0800
committer魏曹先生 <1992414357@qq.com>2026-04-10 16:47:40 +0800
commitb18749170b6006e53976dbb6df9f59a3b9c34127 (patch)
treea0f9288fdc9082e26daab218167da1f54521d32b /mingling_macros/src/lib.rs
parent3bb5afcbe01ad16293a66084dc1ad35f3378a833 (diff)
Add completion macro infrastructure without logic
Diffstat (limited to 'mingling_macros/src/lib.rs')
-rw-r--r--mingling_macros/src/lib.rs67
1 files changed, 66 insertions, 1 deletions
diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs
index d324ddc..7291f0e 100644
--- a/mingling_macros/src/lib.rs
+++ b/mingling_macros/src/lib.rs
@@ -24,10 +24,13 @@ mod suggest;
use once_cell::sync::Lazy;
use std::sync::Mutex;
-// Global variable declarations for storing chain and renderer mappings
+// Global variables
#[cfg(feature = "general_renderer")]
pub(crate) static GENERAL_RENDERERS: Lazy<Mutex<Vec<String>>> =
Lazy::new(|| Mutex::new(Vec::new()));
+#[cfg(feature = "comp")]
+pub(crate) static COMPLETIONS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new()));
+
pub(crate) static PACKED_TYPES: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new()));
pub(crate) static CHAINS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new()));
pub(crate) static RENDERERS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new()));
@@ -107,6 +110,13 @@ pub fn gen_program(input: TokenStream) -> TokenStream {
let mut packed_types = PACKED_TYPES.lock().unwrap().clone();
packed_types.push("DispatcherNotFound".to_string());
packed_types.push("RendererNotFound".to_string());
+
+ #[cfg(feature = "comp")]
+ {
+ packed_types.push("CompletionContext".to_string());
+ packed_types.push("CompletionSuggest".to_string());
+ }
+
packed_types.sort();
packed_types.dedup();
let renderers = RENDERERS.lock().unwrap().clone();
@@ -117,6 +127,9 @@ pub fn gen_program(input: TokenStream) -> TokenStream {
#[cfg(feature = "general_renderer")]
let general_renderers = GENERAL_RENDERERS.lock().unwrap().clone();
+ #[cfg(feature = "comp")]
+ let completions = COMPLETIONS.lock().unwrap().clone();
+
let packed_types: Vec<proc_macro2::TokenStream> = packed_types
.iter()
.map(|s| syn::parse_str::<proc_macro2::TokenStream>(s).unwrap())
@@ -164,6 +177,55 @@ pub fn gen_program(input: TokenStream) -> TokenStream {
#[cfg(not(feature = "general_renderer"))]
let general_render = quote! {};
+ #[cfg(feature = "comp")]
+ let comp_dispatcher = quote! {
+ ::mingling::macros::dispatcher!(#name, "__comp", CompletionDispatcher => CompletionContext);
+ ::mingling::macros::pack!(
+ #name,
+ CompletionSuggest = (::mingling::ShellContext, ::mingling::Suggest)
+ );
+
+ #[::mingling::macros::chain]
+ async fn __completion(prev: CompletionContext) -> NextProcess {
+ let read_ctx = ::mingling::ShellContext::try_from(prev.inner);
+ match read_ctx {
+ Ok(ctx) => {
+ let suggest = ::mingling::CompletionHelper::exec_completion::<#name>(&ctx);
+ CompletionSuggest::new((ctx, suggest)).to_render()
+ }
+ Err(_) => std::process::exit(1),
+ }
+ }
+
+ #[::mingling::macros::renderer]
+ fn __render_completion(prev: CompletionSuggest) {
+ let (ctx, suggest) = prev.inner;
+ ::mingling::CompletionHelper::render_suggest::<#name>(ctx, suggest);
+ }
+ };
+
+ #[cfg(not(feature = "comp"))]
+ let comp_dispatcher = quote! {};
+
+ #[cfg(feature = "comp")]
+ let completion_tokens: Vec<proc_macro2::TokenStream> = completions
+ .iter()
+ .map(|s| syn::parse_str::<proc_macro2::TokenStream>(s).unwrap())
+ .collect();
+
+ #[cfg(feature = "comp")]
+ let comp = quote! {
+ fn do_comp(any: &::mingling::AnyOutput<Self::Enum>, ctx: &::mingling::ShellContext) -> ::mingling::Suggest {
+ match any.member_id {
+ #(#completion_tokens)*
+ _ => ::mingling::Suggest::FileCompletion,
+ }
+ }
+ };
+
+ #[cfg(not(feature = "comp"))]
+ let comp = quote! {};
+
let expanded = quote! {
::mingling::macros::pack!(#name, RendererNotFound = String);
::mingling::macros::pack!(#name, DispatcherNotFound = Vec<String>);
@@ -176,6 +238,8 @@ pub fn gen_program(input: TokenStream) -> TokenStream {
#(#packed_types),*
}
+ #comp_dispatcher
+
impl ::std::fmt::Display for #name {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match self {
@@ -212,6 +276,7 @@ pub fn gen_program(input: TokenStream) -> TokenStream {
}
}
#general_render
+ #comp
}
impl #name {