1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
use {
super::{builtin::builtin_verbs, Verb},
crate::conf::Conf,
crossterm::event::KeyEvent,
std::convert::TryFrom,
};
/// Provide access to the verbs:
/// - the built-in ones
/// - the user defined ones
/// A user defined verb can replace a built-in.
/// When the user types some keys, we select a verb
/// - if the input exactly matches a shortcut or the name
/// - if only one verb name starts with the input
pub struct VerbStore {
pub verbs: Vec<Verb>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum PrefixSearchResult<'v, T> {
NoMatch,
Match(T),
TooManyMatches(Vec<&'v str>),
}
impl VerbStore {
pub fn new() -> VerbStore {
VerbStore { verbs: Vec::new() }
}
pub fn init(&mut self, conf: &Conf) {
// we first add the verbs coming from configuration, as
// we'll search in order. This way, a user can overload a
// standard verb.
for verb_conf in &conf.verbs {
match Verb::try_from(verb_conf) {
Ok(v) => {
self.verbs.push(v);
}
Err(e) => {
eprintln!("Verb error: {:?}", e);
}
}
}
self.verbs.extend(builtin_verbs());
}
pub fn search<'v>(&'v self, prefix: &str) -> PrefixSearchResult<'v, &Verb> {
let mut found_index = 0;
let mut nb_found = 0;
let mut completions: Vec<&str> = Vec::new();
for (index, verb) in self.verbs.iter().enumerate() {
for name in &verb.names {
if name.starts_with(prefix) {
if name == prefix {
return PrefixSearchResult::Match(&verb);
}
found_index = index;
nb_found += 1;
completions.push(name);
continue;
}
}
}
match nb_found {
0 => PrefixSearchResult::NoMatch,
1 => PrefixSearchResult::Match(&self.verbs[found_index]),
_ => PrefixSearchResult::TooManyMatches(completions),
}
}
/// return the index of the verb which is triggered by the given keyboard key, if any
pub fn index_of_key(&self, key: KeyEvent) -> Option<usize> {
for i in 0..self.verbs.len() {
for verb_key in &self.verbs[i].keys {
if *verb_key == key {
return Some(i);
}
}
}
None
}
}
|