use crate::shell::Toolbox;
use rustyline::completion::Completer;
use rustyline::highlight::Highlighter;
use rustyline::hint::Hinter;
use rustyline::{self, Context};
use std::borrow::Cow::{self, Borrowed};
use std::sync::{Arc, Mutex};
pub struct CmdCompleter(Arc<Mutex<Toolbox>>);
impl CmdCompleter {
#[inline]
pub fn new(toolbox: Arc<Mutex<Toolbox>>) -> CmdCompleter {
CmdCompleter(toolbox)
}
#[inline]
fn commands(&self) -> Vec<String> {
self.0.lock().unwrap().keys()
}
}
impl Completer for CmdCompleter {
type Candidate = String;
#[inline]
fn complete(
&self,
line: &str,
pos: usize,
_ctx: &Context<'_>,
) -> rustyline::Result<(usize, Vec<String>)> {
if line.contains(' ') || line.len() != pos {
return Ok((0, vec![]));
}
let results: Vec<String> = self
.commands()
.iter()
.filter(|x| x.starts_with(line))
.map(|x| x.clone() + " ")
.collect();
Ok((0, results))
}
}
impl Hinter for CmdCompleter {
type Hint = String;
#[inline]
fn hint(&self, _line: &str, _pos: usize, _ctx: &Context<'_>) -> Option<String> {
None
}
}
impl Highlighter for CmdCompleter {
#[inline]
fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
Borrowed(hint)
}
}
impl rustyline::validate::Validator for CmdCompleter {}
impl rustyline::Helper for CmdCompleter {}