boxxy/
completer.rs

1use crate::shell::Toolbox;
2use rustyline::completion::Completer;
3use rustyline::highlight::Highlighter;
4use rustyline::hint::Hinter;
5use rustyline::{self, Context};
6use std::borrow::Cow::{self, Borrowed};
7use std::sync::{Arc, Mutex};
8
9pub struct CmdCompleter(Arc<Mutex<Toolbox>>);
10
11impl CmdCompleter {
12    #[inline]
13    pub fn new(toolbox: Arc<Mutex<Toolbox>>) -> CmdCompleter {
14        CmdCompleter(toolbox)
15    }
16
17    #[inline]
18    fn commands(&self) -> Vec<String> {
19        self.0.lock().unwrap().keys()
20    }
21}
22
23impl Completer for CmdCompleter {
24    type Candidate = String;
25
26    #[inline]
27    fn complete(
28        &self,
29        line: &str,
30        pos: usize,
31        _ctx: &Context<'_>,
32    ) -> rustyline::Result<(usize, Vec<String>)> {
33        if line.contains(' ') || line.len() != pos {
34            return Ok((0, vec![]));
35        }
36
37        let results: Vec<String> = self
38            .commands()
39            .iter()
40            .filter(|x| x.starts_with(line))
41            .map(|x| x.clone() + " ")
42            .collect();
43
44        Ok((0, results))
45    }
46}
47
48impl Hinter for CmdCompleter {
49    type Hint = String;
50
51    #[inline]
52    fn hint(&self, _line: &str, _pos: usize, _ctx: &Context<'_>) -> Option<String> {
53        None
54    }
55}
56
57impl Highlighter for CmdCompleter {
58    #[inline]
59    fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
60        Borrowed(hint)
61    }
62}
63
64impl rustyline::validate::Validator for CmdCompleter {}
65
66impl rustyline::Helper for CmdCompleter {}