aboutsummaryrefslogtreecommitdiff
path: root/mingling/src/comp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mingling/src/comp.rs')
-rw-r--r--mingling/src/comp.rs157
1 files changed, 157 insertions, 0 deletions
diff --git a/mingling/src/comp.rs b/mingling/src/comp.rs
new file mode 100644
index 0000000..7136ccc
--- /dev/null
+++ b/mingling/src/comp.rs
@@ -0,0 +1,157 @@
+use std::collections::HashSet;
+
+use mingling_core::{Flag, ShellContext, Suggest};
+
+pub struct ShellContextHelper {
+ ctx: ShellContext,
+}
+
+impl ShellContextHelper {
+ /// Checks if a flag appears exactly once in the command line arguments.
+ ///
+ /// This method is useful for determining whether a flag should be processed
+ /// when it should only be applied once, even if it appears multiple times
+ /// in the command line. It returns `true` if the flag is present and
+ /// appears exactly once among all words in the shell context.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use mingling_core::ShellContext;
+ /// # use mingling_macros::suggest;
+ /// # use mingling::comp_tools::ShellContextHelper;
+ ///
+ /// let ctx = ShellContext::default();
+ /// let helper = ShellContextHelper::from(ctx);
+ ///
+ /// // Check if either "--insert" or "-i" appears exactly once
+ /// if helper.filling_argument_first(["--insert", "-i"]) {
+ /// // Perform action that should only happen once, example:
+ /// // return suggest! {
+ /// // "A", "B", "C"
+ /// // }
+ /// }
+ /// ```
+ pub fn filling_argument_first(&self, flag: impl Into<Flag>) -> bool {
+ let flag = flag.into();
+ if self.filling_argument(&flag) {
+ let mut flag_appears = 0;
+ for w in self.ctx.all_words.iter() {
+ for f in flag.iter() {
+ if *f == w {
+ flag_appears += 1;
+ }
+ }
+ }
+ if flag_appears < 2 {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// Checks if the previous word in the command line arguments matches any of the given flags.
+ ///
+ /// This method determines whether a flag is currently being processed
+ /// by checking the word immediately before the cursor position. It returns
+ /// `true` if the previous word matches any of the provided flag strings.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use mingling_core::ShellContext;
+ /// # use mingling_macros::suggest;
+ /// # use mingling::comp_tools::ShellContextHelper;
+ ///
+ /// let ctx = ShellContext::default();
+ /// let helper = ShellContextHelper::from(ctx);
+ ///
+ /// // Check if the previous word is either "--file" or "-f"
+ /// if helper.filling_argument(["--file", "-f"]) {
+ /// // The user is likely expecting a file argument next, example:
+ /// // return suggest! {
+ /// // "src/main.rs", "Cargo.toml", "README.md"
+ /// // }
+ /// }
+ /// ```
+ pub fn filling_argument(&self, flag: impl Into<Flag>) -> bool {
+ for f in flag.into().iter() {
+ if self.ctx.previous_word == **f {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// Checks if the user is currently typing a flag argument.
+ ///
+ /// This method determines whether the current word being typed starts with
+ /// a dash (`-`), indicating that the user is likely in the process of
+ /// entering a command-line flag. It returns `true` if the current word
+ /// begins with a dash character.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use mingling_core::ShellContext;
+ /// # use mingling_macros::suggest;
+ /// # use mingling::comp_tools::ShellContextHelper;
+ ///
+ /// let ctx = ShellContext::default();
+ /// let helper = ShellContextHelper::from(ctx);
+ ///
+ /// // Check if the user is typing a flag
+ /// if helper.typing_argument() {
+ /// // The user is likely entering a flag, example:
+ /// // return suggest! {
+ /// // "--help", "--version", "--verbose"
+ /// // }
+ /// }
+ /// ```
+ pub fn typing_argument(&self) -> bool {
+ self.ctx.current_word.starts_with("-")
+ }
+
+ /// Filters out already typed flag arguments from suggestion results.
+ ///
+ /// This method removes any suggestions that match flag arguments already present
+ /// in the command line. It is useful for preventing duplicate flag suggestions
+ /// when the user has already typed certain flags. The method processes both
+ /// regular suggestion sets and file completion suggestions differently.
+ pub fn strip_typed_argument(&self, suggest: Suggest) -> Suggest {
+ let typed = Self::get_typed_arguments(&self);
+ match suggest {
+ Suggest::Suggest(mut set) => {
+ set.retain(|item| !typed.contains(item.suggest()));
+ Suggest::Suggest(set)
+ }
+ Suggest::FileCompletion => Suggest::FileCompletion,
+ }
+ }
+
+ /// Retrieves all flag arguments from the command line.
+ ///
+ /// This method collects all words in the shell context that start with a dash (`-`),
+ /// which typically represent command-line flags or options. It returns a vector
+ /// containing these flag strings, converted to owned `String` values.
+ pub fn get_typed_arguments(&self) -> HashSet<String> {
+ self.ctx
+ .all_words
+ .iter()
+ .filter(|word| word.starts_with("-"))
+ .map(|word| word.to_string())
+ .collect()
+ }
+}
+
+impl From<ShellContext> for ShellContextHelper {
+ fn from(ctx: ShellContext) -> Self {
+ Self { ctx }
+ }
+}
+
+impl From<ShellContextHelper> for ShellContext {
+ fn from(helper: ShellContextHelper) -> Self {
+ helper.ctx
+ }
+}