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 {}