aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeicao-CatilGrass <1992414357@qq.com>2026-06-09 17:12:50 +0800
committerWeicao-CatilGrass <1992414357@qq.com>2026-06-09 17:14:08 +0800
commitf7ce99550595915efb3d3f7774095976cb3b763b (patch)
tree378bdacea64bb22d41844eb9298c6b67b260f8b5
parentbcdd642b269a3342a07d625139c647b0501fa7c7 (diff)
Add COMPLETION_SUBCOMMAND and is_completing method
-rw-r--r--CHANGELOG.md4
-rw-r--r--mingling_core/src/comp.rs11
-rw-r--r--mingling_core/src/comp/comp_ctx.rs19
-rw-r--r--mling/src/cli.rs10
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;