Improve repl autocorrect and error handling
* Combine comparison algorithims for autocorrect
* clear zephyr functions
* remove redundant comments because co-pilot is stupid and i probably will never try to use it again
* implement basic tab completion
* fix unused items
* Make workflow check code quality
* split code quality into its own file
* make action fail on bad formatting
* change workflow to nightly
* f it, code quality is considered breaking
* fix forgetting to set toolchain back to nightly when rewriting workflow (😔)
* Add condition for too little arguments
* run cargo fmt
* remove unneeded feature directive
This commit is contained in:
parent
b4f31785d4
commit
3aba3aea1c
8 changed files with 170 additions and 42 deletions
|
@ -9,9 +9,9 @@ use log::debug;
|
|||
use parking_lot::Mutex;
|
||||
use regex::Regex;
|
||||
use rustyline::{
|
||||
error::ReadlineError, highlight::Highlighter, hint::HistoryHinter, history::DefaultHistory,
|
||||
Cmd, Completer, ConditionalEventHandler, Editor, Event, EventContext, EventHandler, Helper,
|
||||
Hinter, KeyEvent, RepeatCount, Validator,
|
||||
completion::Completer, error::ReadlineError, highlight::Highlighter, hint::HistoryHinter,
|
||||
history::DefaultHistory, Cmd, Completer, ConditionalEventHandler, Editor, Event, EventContext,
|
||||
EventHandler, Helper, Hinter, KeyEvent, RepeatCount, Validator,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -19,8 +19,44 @@ use crate::{
|
|||
utils::logger::LOGGER,
|
||||
};
|
||||
|
||||
struct CommandCompleter;
|
||||
impl CommandCompleter {
|
||||
fn new() -> Self {
|
||||
CommandCompleter {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Completer for CommandCompleter {
|
||||
type Candidate = String;
|
||||
|
||||
fn complete(
|
||||
&self,
|
||||
line: &str,
|
||||
pos: usize,
|
||||
_ctx: &rustyline::Context<'_>,
|
||||
) -> rustyline::Result<(usize, Vec<Self::Candidate>)> {
|
||||
let binding = COMMAND_LIST.commands.read();
|
||||
let filtered_commands: Vec<_> = binding
|
||||
.iter()
|
||||
.filter(|command| command.name.starts_with(line))
|
||||
.collect();
|
||||
|
||||
let completions: Vec<String> = filtered_commands
|
||||
.iter()
|
||||
.filter(|command| command.name.starts_with(&line[..pos]))
|
||||
.map(|command| command.name[pos..].to_string())
|
||||
.collect();
|
||||
Ok((pos, completions))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Completer, Helper, Hinter, Validator)]
|
||||
struct MyHelper(#[rustyline(Hinter)] HistoryHinter);
|
||||
struct MyHelper {
|
||||
#[rustyline(Hinter)]
|
||||
hinter: HistoryHinter,
|
||||
#[rustyline(Completer)]
|
||||
completer: CommandCompleter,
|
||||
}
|
||||
|
||||
impl Highlighter for MyHelper {
|
||||
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
|
||||
|
@ -142,6 +178,11 @@ fn tokenize(command: &str) -> Vec<String> {
|
|||
tokens
|
||||
}
|
||||
|
||||
pub fn parse_command(input: &str) -> anyhow::Result<Vec<String>> {
|
||||
let pattern = Regex::new(r"[;|\n]").unwrap();
|
||||
let commands: Vec<String> = pattern.split(input).map(|s| String::from(s)).collect();
|
||||
Ok(commands)
|
||||
}
|
||||
pub fn evaluate_command(input: &str) -> anyhow::Result<()> {
|
||||
if input.trim().is_empty() {
|
||||
println!("Empty command, skipping. type 'help' for a list of commands.");
|
||||
|
@ -176,7 +217,10 @@ pub fn evaluate_command(input: &str) -> anyhow::Result<()> {
|
|||
|
||||
pub async fn handle_repl() -> anyhow::Result<()> {
|
||||
let mut rl = Editor::<MyHelper, DefaultHistory>::new()?;
|
||||
rl.set_helper(Some(MyHelper(HistoryHinter::new())));
|
||||
rl.set_helper(Some(MyHelper {
|
||||
hinter: HistoryHinter::new(),
|
||||
completer: CommandCompleter::new(),
|
||||
}));
|
||||
|
||||
rl.bind_sequence(
|
||||
KeyEvent::from('`'),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue