feature/readline-command-parsing
Manos Pitsidianakis 2022-12-03 16:44:33 +02:00
parent e079610b61
commit b4ede12ec5
2 changed files with 84 additions and 15 deletions

View File

@ -1224,15 +1224,23 @@ pub fn command_completion_suggestions(input: &str) -> Vec<String> {
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<Vec<Cow<'_, str>>, 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<Vec<Cow<'_, str>>, usize> {
}
}
#[derive(Debug)]
pub enum ParseResult {
Valid {
inner: Action,
},
Invalid {
position: usize,
reason: &'static str,
},
Incomplete {
suggestions: Vec<String>,
},
}
pub fn parser(input: &'_ str, context: &crate::Context) -> ParseResult {
use crate::melib::ShellExpandTrait;
let mut lex_output: Vec<Cow<'_, str>> = 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::<Vec<String>>(),
}
}
#[test]
fn test_lexer() {
assert_eq!(

View File

@ -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()) {