strop_engine/editor/
keys.rs1use super::Key;
4
5pub fn parse(text: &str) -> Keys<'_> {
6 Keys {
7 remaining: text,
8 literal_bytes: 0,
9 }
10}
11pub struct Keys<'a> {
12 remaining: &'a str,
13 literal_bytes: usize,
14}
15impl Iterator for Keys<'_> {
16 type Item = Key;
17 fn next(&mut self) -> Option<Key> {
18 let character = self.remaining.chars().next()?;
19 if self.literal_bytes > 0 {
20 self.remaining = &self.remaining[character.len_utf8()..];
21 self.literal_bytes -= character.len_utf8();
22 return Some(Key::Char(character));
23 }
24 if character == '<' {
25 if let Some(end) = self.remaining.find('>') {
26 let token = &self.remaining[1..end];
27 if let Some((_, key)) = TOKENS
28 .iter()
29 .find(|(name, _)| token.eq_ignore_ascii_case(name))
30 {
31 self.remaining = &self.remaining[end + 1..];
32 return Some(*key);
33 }
34 self.literal_bytes = end;
35 }
36 }
37 self.remaining = &self.remaining[character.len_utf8()..];
38 Some(match character {
39 '\x1b' => Key::Esc,
40 '\r' | '\n' => Key::Enter,
41 '\x7f' => Key::Backspace,
42 character => Key::Char(character),
43 })
44 }
45}
46const TOKENS: &[(&str, Key)] = &[
47 ("esc", Key::Esc),
48 ("cr", Key::Enter),
49 ("enter", Key::Enter),
50 ("bs", Key::Backspace),
51 ("space", Key::Char(' ')),
52 ("lt", Key::Char('<')),
53 ("gt", Key::Char('>')),
54 ("up", Key::Up),
55 ("down", Key::Down),
56 ("left", Key::Left),
57 ("right", Key::Right),
58 ("tab", Key::Tab),
59 ("s-tab", Key::Backtab),
60 ("c-r", Key::CtrlR),
61 ("c-x", Key::CtrlX),
62 ("c-d", Key::CtrlD),
63 ("c-u", Key::CtrlU),
64 ("c-f", Key::CtrlF),
65 ("c-b", Key::CtrlB),
66 ("c-^", Key::CtrlCaret),
67 ("c-v", Key::CtrlV),
68 ("c-w", Key::CtrlW),
69 ("c-o", Key::CtrlO),
70 ("c-l", Key::CtrlL),
71 ("c-space", Key::CtrlSpace),
72];