From b4ede12ec5974226d378e7b165e460163762165c Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 3 Dec 2022 16:44:33 +0200 Subject: [PATCH] WIP2 --- src/command.rs | 75 +++++++++++++++++++++++++++++++++++-- src/components/utilities.rs | 24 ++++++------ 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/src/command.rs b/src/command.rs index 26a7b5cfd..454ba0626 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1224,15 +1224,23 @@ pub fn command_completion_suggestions(input: &str) -> Vec { use std::borrow::Cow; pub enum LexerToken<'a> { - Complete { input: Cow<'a, str>, token: Token }, - Incomplete { input: &'a str, token: Token }, - Invalid { input: &'a str }, + Complete { + input: Cow<'a, str>, + token: Token, + }, + Incomplete { + input: Cow<'a, str>, + token: Token, + }, + Invalid { + input: Cow<'a, str>, + reason: &'static str, + }, } pub fn lexer(input: &'_ str) -> Result>, usize> { #[inline(always)] fn unescape(input: &str) -> Cow<'_, str> { - println!("`{}`", &input); if input.is_empty() { return input.into(); } @@ -1337,6 +1345,65 @@ pub fn lexer(input: &'_ str) -> Result>, usize> { } } +#[derive(Debug)] +pub enum ParseResult { + Valid { + inner: Action, + }, + Invalid { + position: usize, + reason: &'static str, + }, + Incomplete { + suggestions: Vec, + }, +} + +pub fn parser(input: &'_ str, context: &crate::Context) -> ParseResult { + use crate::melib::ShellExpandTrait; + let mut lex_output: Vec> = match lexer(input) { + Ok(v) => v, + Err(err) => { + return ParseResult::Invalid { + position: err, + reason: "", + } + } + }; + let mut sugg = HashSet::default(); + for Command { + tags: _, + desc: _, + tokens, + } in COMMANDS.iter() + { + let m = tokens.matches_tokens(&lex_output, &mut sugg); + let m = match m { + Err(i) => { + //println!("error at `{}`", lex_output[i]); + continue; + } + Ok(m) => { + if !m.is_empty() { + //print!("{:?} ", desc); + //println!(" result = {:#?}\n\n", m); + } + m + } + }; + if let Some((s, ExistingFilepath)) = m.last() { + let p = std::path::Path::new(s); + sugg.extend(p.complete(true).into_iter()); + } + } + ParseResult::Incomplete { + suggestions: sugg + .into_iter() + .map(|s| format!("{}{}", input, s.as_str())) + .collect::>(), + } +} + #[test] fn test_lexer() { assert_eq!( diff --git a/src/components/utilities.rs b/src/components/utilities.rs index 848770edf..8732ff950 100644 --- a/src/components/utilities.rs +++ b/src/components/utilities.rs @@ -318,17 +318,19 @@ impl Component for StatusBar { } }) .collect(); - let command_completion_suggestions = - crate::command::command_completion_suggestions(self.ex_buffer.as_str()); - - suggestions.extend(command_completion_suggestions.iter().filter_map(|e| { - if !unique_suggestions.contains(e.as_str()) { - unique_suggestions.insert(e.as_str()); - Some(e.clone().into()) - } else { - None - } - })); + if let ParseResult::Incomplete { + suggestions: command_completion_suggestions, + } = crate::command::parser(self.ex_buffer.as_str(), &context) + { + suggestions.extend(command_completion_suggestions.iter().filter_map(|e| { + if !unique_suggestions.contains(e.as_str()) { + unique_suggestions.insert(e.as_str()); + Some(e.clone().into()) + } else { + None + } + })); + } /* suggestions.extend(crate::command::COMMAND_COMPLETION.iter().filter_map(|e| { if e.0.starts_with(self.ex_buffer.as_str()) {