mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-08 12:46:44 +01:00
90 lines
3.3 KiB
Rust
90 lines
3.3 KiB
Rust
use crate::*;
|
|
|
|
pub struct KeyMatcher {
|
|
valid: bool,
|
|
key: Option<KeyCode>,
|
|
mods: KeyModifiers,
|
|
}
|
|
|
|
impl KeyMatcher {
|
|
pub fn new (token: impl AsRef<str>) -> Self {
|
|
let token = token.as_ref();
|
|
if token.len() < 2 {
|
|
Self { valid: false, key: None, mods: KeyModifiers::NONE }
|
|
} else if token.chars().next() != Some('@') {
|
|
Self { valid: false, key: None, mods: KeyModifiers::NONE }
|
|
} else {
|
|
Self { valid: true, key: None, mods: KeyModifiers::NONE }.next(&token[1..])
|
|
}
|
|
}
|
|
pub fn build (self) -> Option<Event> {
|
|
if self.valid && self.key.is_some() {
|
|
Some(Event::Key(KeyEvent::new(self.key.unwrap(), self.mods)))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
fn next (mut self, token: &str) -> Self {
|
|
let mut tokens = token.split('-').peekable();
|
|
while let Some(token) = tokens.next() {
|
|
if tokens.peek().is_some() {
|
|
match token {
|
|
"ctrl" | "Ctrl" | "c" | "C" => self.mods |= KeyModifiers::CONTROL,
|
|
"alt" | "Alt" | "m" | "M" => self.mods |= KeyModifiers::ALT,
|
|
"shift" | "Shift" | "s" | "S" => {
|
|
self.mods |= KeyModifiers::SHIFT;
|
|
// + TODO normalize character case, BackTab, etc.
|
|
},
|
|
_ => panic!("unknown modifier {token}"),
|
|
}
|
|
} else {
|
|
self.key = if token.len() == 1 {
|
|
Some(KeyCode::Char(token.chars().next().unwrap()))
|
|
} else {
|
|
Some(Self::named_key(token).unwrap_or_else(||panic!("unknown character {token}")))
|
|
}
|
|
}
|
|
}
|
|
self
|
|
}
|
|
fn named_key (token: &str) -> Option<KeyCode> {
|
|
use KeyCode::*;
|
|
Some(match token {
|
|
"up" => Up,
|
|
"down" => Down,
|
|
"left" => Left,
|
|
"right" => Right,
|
|
"esc" | "escape" => Esc,
|
|
"enter" | "return" => Enter,
|
|
"delete" | "del" => Delete,
|
|
"tab" => Tab,
|
|
"space" => Char(' '),
|
|
"comma" => Char(','),
|
|
"period" => Char('.'),
|
|
"plus" => Char('+'),
|
|
"minus" | "dash" => Char('-'),
|
|
"equal" | "equals" => Char('='),
|
|
"underscore" => Char('_'),
|
|
"backtick" => Char('`'),
|
|
"lt" => Char('<'),
|
|
"gt" => Char('>'),
|
|
"openbracket" => Char('['),
|
|
"closebracket" => Char(']'),
|
|
"pgup" | "pageup" => PageUp,
|
|
"pgdn" | "pagedown" => PageDown,
|
|
"f1" => F(1),
|
|
"f2" => F(2),
|
|
"f3" => F(3),
|
|
"f4" => F(4),
|
|
"f5" => F(5),
|
|
"f6" => F(6),
|
|
"f7" => F(7),
|
|
"f8" => F(8),
|
|
"f9" => F(9),
|
|
"f10" => F(10),
|
|
"f11" => F(11),
|
|
"f12" => F(12),
|
|
_ => return None,
|
|
})
|
|
}
|
|
}
|