From b138dff3517e8cb793d431af6ad4a577491e21b0 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 14 Aug 2026 03:26:54 +0800 Subject: docs(comp): improve documentation for completion module Add detailed doc comments, examples, and usage notes across the completion module including ShellContext, Suggest, and related traits. --- mingling_core/src/comp/shell_ctx.rs | 132 ++++++++++++++++++++++++++++++++---- 1 file changed, 118 insertions(+), 14 deletions(-) (limited to 'mingling_core/src/comp/shell_ctx.rs') diff --git a/mingling_core/src/comp/shell_ctx.rs b/mingling_core/src/comp/shell_ctx.rs index 78ccb87..552e514 100644 --- a/mingling_core/src/comp/shell_ctx.rs +++ b/mingling_core/src/comp/shell_ctx.rs @@ -1,38 +1,142 @@ -// Doc Not Optimize #![allow(deprecated)] -use std::collections::HashSet; - use crate::{Flag, ShellFlag, Suggest, special_argument}; +use std::collections::HashSet; -/// Context passed from the shell to the completion system, -/// providing information about the current command line state -/// to guide how completions should be generated. +/// The shell context description for the current user. +/// +/// It records the state of the command line input when the user is using the +/// completion feature, allowing smart completion suggestions to be provided +/// to the user based on this state. +/// +/// # Note on `^` and `-` characters +/// +/// The completion scripts auto-generated by `mingling` replace any `-` +/// characters in the user's input with `^` when passing arguments to the +/// completion engine. This is an intentional tradeoff to avoid parsing +/// conflicts: since `-` is used both as a flag prefix (e.g., `-f`, `--help`) +/// and as a value separator in the command-line arguments consumed by +/// [`TryFrom`](std::convert::TryFrom), differentiating between them would +/// otherwise be ambiguous. By substituting `-` with `^`, the completion +/// engine can cleanly parse user-input values without confusing them for +/// flags. +/// +/// When reading fields like [`command_line`](ShellContext::command_line), +/// [`current_word`](ShellContext::current_word), +/// [`previous_word`](ShellContext::previous_word), or +/// [`command_name`](ShellContext::command_name), the `^` characters are +/// converted back to `-` so that the resulting context faithfully represents +/// what the user originally typed. +/// +/// # Behavior under `structural_renderer` feature +/// +/// When the `structural_renderer` feature is enabled, this struct derives +/// [`serde::Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html). +/// This allows the shell context to be serialized and transmitted over +/// serialization boundaries (e.g., JSON, YAML) as a structured representation +/// of the current shell input state. Each public field is serialized under +/// its own key, enabling consumers to reconstruct the exact command-line +/// state for rendering purposes. +/// +/// # Usage +/// +/// A [`ShellContext`] can be constructed from a vector of command-line +/// argument strings using [`TryFrom`](std::convert::TryFrom): +/// +/// ``` +/// # #[cfg(feature = "comp")] { +/// # use mingling_core::ShellContext; +/// let args = vec![ +/// "-f".to_string(), // --command-line +/// "git commit ^m 'test'".to_string(), +/// "-C".to_string(), // --cursor-position +/// "12".to_string(), +/// "-w".to_string(), // --current-word +/// "commit".to_string(), +/// "-p".to_string(), // --previous-word +/// "git".to_string(), +/// "-c".to_string(), // --command-name +/// "git".to_string(), +/// "-i".to_string(), // --word-index +/// "1".to_string(), +/// "-F".to_string(), // --shell-flag +/// "bash".to_string(), +/// ]; +/// +/// let context = ShellContext::try_from(args).unwrap(); +/// assert_eq!(context.command_line, "git commit -m 'test'"); +/// assert_eq!(context.cursor_position, 12); +/// assert_eq!(context.current_word, "commit"); +/// assert_eq!(context.previous_word, "git"); +/// assert_eq!(context.command_name, "git"); +/// assert_eq!(context.word_index, 1); +/// assert_eq!(context.all_words, vec!["git", "commit", "-m", "'test'"]); +/// # } +/// ``` +/// +/// When only partial information is available, the remaining fields default +/// to empty values: +/// +/// ``` +/// # #[cfg(feature = "comp")] { +/// # use mingling_core::ShellContext; +/// let args = vec![ +/// "-f".to_string(), +/// "ls ^la".to_string(), +/// "-C".to_string(), +/// "5".to_string(), +/// ]; +/// +/// let context = ShellContext::try_from(args).unwrap(); +/// assert_eq!(context.command_line, "ls -la"); +/// assert_eq!(context.cursor_position, 5); +/// # } +/// ``` +/// +/// If the `-F` flag is present without a value, `shell_flag` becomes +/// `ShellFlag::Other(String::new())`. If `-F` is absent, it defaults to +/// `ShellFlag::Other("unknown".to_string())`. #[derive(Default, Debug)] #[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] pub struct ShellContext { - /// The full command line (-f / --command-line) + /// The full command line + /// + /// Flag: [`-f`, `--command-line`] pub command_line: String, - /// Cursor position (-C / --cursor-position) + /// Cursor position + /// + /// Flag: [`-C`, `--cursor-position`] pub cursor_position: usize, - /// Current word (-w / --current-word) + /// Current word + /// + /// Flag: [`-w`, `--current-word`] pub current_word: String, - /// Previous word (-p / --previous-word) + /// Previous word + /// + /// Flag: [`-p`, `--previous-word`] pub previous_word: String, - /// Command name (-c / --command-name) + /// Command name + /// + /// Flag: [`-c`, `--command-name`] pub command_name: String, - /// Word index (-i / --word-index) + /// Word index + /// + /// Flag: [`-i`, `--word-index`] pub word_index: usize, - /// All words (-a / --all-words) + /// All words + /// + /// Flag: [`-a`, `--all-words`] pub all_words: Vec, - /// Flag to indicate completion context (-F / --shell-flag) + /// Flag to indicate completion context + /// + /// Flag: [`-F`, `--shell-flag`] pub shell_flag: ShellFlag, } -- cgit