Skip to main content

strop_engine/editor/
keys.rs

1//! Streaming script-token decoding shared by Editor::feed_text and headless.
2//! Unknown tokens stay literal, and a lone '<' never fabricates a closing '>'.
3use 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];