diff options
Diffstat (limited to 'mingling_core/src/comp')
| -rw-r--r-- | mingling_core/src/comp/shell_ctx.rs | 50 | ||||
| -rw-r--r-- | mingling_core/src/comp/suggest.rs | 36 |
2 files changed, 52 insertions, 34 deletions
diff --git a/mingling_core/src/comp/shell_ctx.rs b/mingling_core/src/comp/shell_ctx.rs index 1fca325..734b5d2 100644 --- a/mingling_core/src/comp/shell_ctx.rs +++ b/mingling_core/src/comp/shell_ctx.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; -use crate::{Flag, ShellFlag, Suggest}; +use crate::{Flag, ShellFlag, Suggest, special_argument}; /// Context passed from the shell to the completion system, /// providing information about the current command line state @@ -38,44 +38,26 @@ pub struct ShellContext { impl TryFrom<Vec<String>> for ShellContext { type Error = String; - fn try_from(args: Vec<String>) -> Result<Self, Self::Error> { - use std::collections::HashMap; - - // Parse arguments into a map for easy lookup - let mut arg_map = HashMap::new(); - let mut i = 0; - while i < args.len() { - if args[i].starts_with('-') { - let key = args[i].clone(); - if i + 1 < args.len() && !args[i + 1].starts_with('-') { - arg_map.insert(key, args[i + 1].clone()); - i += 2; - } else { - arg_map.insert(key, String::new()); - i += 1; - } - } else { - i += 1; - } - } - + fn try_from(mut args: Vec<String>) -> Result<Self, Self::Error> { // Extract values with defaults - let command_line = arg_map.get("-f").cloned().unwrap_or_default(); - let cursor_position = arg_map - .get("-C") + let command_line = special_argument!(args, "-f").unwrap_or_default(); + let cursor_position = special_argument!(args, "-C") .and_then(|s| s.parse().ok()) .unwrap_or_default(); - let current_word = arg_map.get("-w").cloned().unwrap_or_default(); - let previous_word = arg_map.get("-p").cloned().unwrap_or_default(); - let command_name = arg_map.get("-c").cloned().unwrap_or_default(); - let word_index = arg_map - .get("-i") + let current_word = special_argument!(args, "-w").unwrap_or_default(); + let previous_word = special_argument!(args, "-p").unwrap_or_default(); + let command_name = special_argument!(args, "-c").unwrap_or_default(); + let word_index = special_argument!(args, "-i") .and_then(|s| s.parse().ok()) .unwrap_or_default(); - let shell_flag = arg_map - .get("-F") - .cloned() - .map_or(ShellFlag::Other("unknown".to_string()), ShellFlag::from); + // Distinguish "-F absent" (unknown shell) from "-F present without a value" (empty shell) + let has_shell_flag = args.iter().any(|arg| arg == "-F"); + let shell_flag = if has_shell_flag { + special_argument!(args, "-F") + .map_or_else(|| ShellFlag::Other(String::new()), ShellFlag::from) + } else { + ShellFlag::Other("unknown".to_string()) + }; let all_words = command_line .split_whitespace() diff --git a/mingling_core/src/comp/suggest.rs b/mingling_core/src/comp/suggest.rs index 88fa5fc..dda5026 100644 --- a/mingling_core/src/comp/suggest.rs +++ b/mingling_core/src/comp/suggest.rs @@ -56,6 +56,42 @@ impl Suggest { (suggest, _) => suggest, } } + + /// Adds multiple simple suggestions (without descriptions) to the `Suggest` set. + /// + /// Each item produced by the iterator is wrapped in a [`SuggestItem::Simple`] + /// variant and inserted into the underlying `BTreeSet`. + /// + /// # Arguments + /// + /// * `items` — A collection of suggestion strings to add. + pub fn add_suggest(&mut self, items: impl Into<Vec<String>>) { + for item in items.into() { + self.insert(SuggestItem::Simple(item)); + } + } + + /// Adds multiple suggestions with a shared description to the `Suggest` set. + /// + /// Each item produced by the iterator is wrapped in a + /// [`SuggestItem::WithDescription`] variant using the provided description, + /// and inserted into the underlying `BTreeSet`. + /// + /// # Arguments + /// + /// * `items` — A collection of suggestion strings to add. + /// * `desc` — The description to attach to each suggestion. Must implement + /// `Into<String>`. + pub fn add_suggest_with_description( + &mut self, + items: impl Into<Vec<String>>, + desc: impl Into<String>, + ) { + let desc_str = desc.into(); + for item in items.into() { + self.insert(SuggestItem::WithDescription(item, desc_str.clone())); + } + } } impl<T> From<T> for Suggest |
