diff options
| author | Weicao-CatilGrass <1992414357@qq.com> | 2026-06-09 17:12:50 +0800 |
|---|---|---|
| committer | Weicao-CatilGrass <1992414357@qq.com> | 2026-06-09 17:14:08 +0800 |
| commit | f7ce99550595915efb3d3f7774095976cb3b763b (patch) | |
| tree | 378bdacea64bb22d41844eb9298c6b67b260f8b5 | |
| parent | bcdd642b269a3342a07d625139c647b0501fa7c7 (diff) | |
Add COMPLETION_SUBCOMMAND and is_completing method
| -rw-r--r-- | CHANGELOG.md | 4 | ||||
| -rw-r--r-- | mingling_core/src/comp.rs | 11 | ||||
| -rw-r--r-- | mingling_core/src/comp/comp_ctx.rs | 19 | ||||
| -rw-r--r-- | mling/src/cli.rs | 10 |
4 files changed, 38 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 957952d..b8e7cf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,10 @@ fn render_entry_show(_args: EntryShow, res: &mut LazyRes<ResLargeData>) { 5. **\[core\]** Added `Program::get_args(&self)` method to expose the program's command-line arguments as a `&[String]` slice, providing public read access to the internal `args` field. +6. **\[core:comp\]** Added `COMPLETION_SUBCOMMAND` constant to `mingling_core::comp` with the value `"__comp"`, providing a single canonical reference for the completion subcommand name used internally. This replaces hardcoded string literals across the codebase. + +7. **\[core:comp\]** Added `Program::is_completing()` method to check whether the program is currently running in completion mode. This provides a convenient way to conditionally skip certain logic during completion generation, where those operations may be unnecessary or undesirable. + #### **BREAKING CHANGES** (API CHANGES): 1. **\[core\]** Changed the signature of `ProgramSetup::setup` from `fn setup(&mut self, program: &mut Program<C>) -> S` to `fn setup(self, program: &mut Program<C>)`, consuming `self` instead of taking a mutable reference. Correspondingly, `Program::with_setup` now accepts `S` by value (`&mut self, setup: S`) instead of by mutable reference (`&mut self, setup: &mut S`). diff --git a/mingling_core/src/comp.rs b/mingling_core/src/comp.rs index 1769a5c..bf7ab13 100644 --- a/mingling_core/src/comp.rs +++ b/mingling_core/src/comp.rs @@ -1,3 +1,4 @@ +mod comp_ctx; mod flags; mod shell_ctx; mod suggest; @@ -5,6 +6,16 @@ mod suggest; use std::collections::BTreeSet; use std::fmt::Display; +/// Constant defining the name of the completion subcommand. +/// +/// When a user invokes this subcommand (e.g., `your_program __comp`), the +/// program enters completion mode and generates shell completions based on +/// the current shell context. +/// +/// This value is used internally by the completion system to intercept the +/// command-line input and redirect to the completion handler. +pub const COMPLETION_SUBCOMMAND: &str = "__comp"; + #[doc(hidden)] pub use flags::*; #[doc(hidden)] diff --git a/mingling_core/src/comp/comp_ctx.rs b/mingling_core/src/comp/comp_ctx.rs new file mode 100644 index 0000000..02e79c5 --- /dev/null +++ b/mingling_core/src/comp/comp_ctx.rs @@ -0,0 +1,19 @@ +use crate::{COMPLETION_SUBCOMMAND, Program, ProgramCollect}; + +impl<C> Program<C> +where + C: ProgramCollect<Enum = C>, +{ + /// Checks whether the program is currently in a completion mode. + /// + /// This is determined by checking if the special completion subcommand + /// (defined by [`COMPLETION_SUBCOMMAND`]) appears among the parsed arguments. + /// When `true`, the program should generate shell completions instead of + /// running its normal execution path. + pub fn is_completing(&self) -> bool { + // Check if the first argument (args[1]) is the completion subcommand + self.args + .get(1) + .is_some_and(|arg| arg == COMPLETION_SUBCOMMAND) + } +} diff --git a/mling/src/cli.rs b/mling/src/cli.rs index 6a4c7d8..6dc7b9e 100644 --- a/mling/src/cli.rs +++ b/mling/src/cli.rs @@ -75,16 +75,14 @@ pub fn run() { }); // Manifest Path Check - program.with_hook(ProgramHook::empty().on_post_dispatch(|c| match c { - // Skip completion (bypass completion) - ThisProgram::CompletionContext => {} - _ => { + if !program.is_completing() { + program.with_hook(ProgramHook::empty().on_post_dispatch(|_| { let p = ThisProgram::this(); p.modify_res(|manifest_path: &mut ResManifestPath| { manifest_path.resolved = Some(resolve_manifest_path(manifest_path.raw.clone())); }); - } - })); + })); + } // Execute let quiet = program.stdout_setting.quiet; |
