aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.rs
diff options
context:
space:
mode:
authorTeddy Wing2018-09-30 18:58:40 +0200
committerTeddy Wing2018-09-30 18:58:40 +0200
commit7801f2561227526e7bacf9915bb4d7f63cf14449 (patch)
treee3563a6d3ef5162c77f89bc6a2ea35d6f5804145 /src/parser.rs
parent29ea66e861420049f593cbaabace13c091db345a (diff)
downloaddome-key-map-7801f2561227526e7bacf9915bb4d7f63cf14449.tar.bz2
Try to parse modifier keys (WIP)
Add some parsing code for modifier keys inside special keys (`<`- `>`-wrapped keys). Currently only works for special keys defined in `special_key()`. Needs to be extended to work for modified character keys (e.g. <C-l>), thus the test in this commit doesn't pass.
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs94
1 files changed, 90 insertions, 4 deletions
diff --git a/src/parser.rs b/src/parser.rs
index 37d69df..0ccb05d 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -247,15 +247,43 @@ where
I: Stream<Item = char>,
I::Error: ParseError<I::Item, I::Range, I::Position>,
{
- between(token('<'), token('>'), key_code())
- .map(|code|
+ between(token('<'), token('>'), (
+ key_modifiers(),
+ key_code()
+ ))
+ .map(|(modifiers, code)|
KeyboardKeyWithModifiers::new(
KeyboardKey::KeyCode(code),
- None,
+ modifiers,
)
)
}
+fn key_modifiers<I>() -> impl Parser<Input = I, Output = Option<Vec<Flag>>>
+where
+ I: Stream<Item = char>,
+ I::Error: ParseError<I::Item, I::Range, I::Position>,
+{
+ many(
+ choice!(
+ try(string_case_insensitive("D-"))
+ .map(|_| Flag::Control),
+ try(string_case_insensitive("A-"))
+ .map(|_| Flag::Alt),
+ try(string_case_insensitive("C-"))
+ .map(|_| Flag::Meta),
+ try(string_case_insensitive("S-"))
+ .map(|_| Flag::Shift)
+ )
+ ).map(|modifiers: Vec<Flag>|
+ if modifiers.is_empty() {
+ None
+ } else {
+ Some(modifiers)
+ }
+ )
+}
+
fn key_code<I>() -> impl Parser<Input = I, Output = KeyCode>
where
I: Stream<Item = char>,
@@ -548,7 +576,65 @@ mod tests {
#[test]
fn action_parses_map_with_modifier() {
- // "one<C-l>two<D-s>three"
+ let text = "one<C-l>two<D-s>three";
+
+ let expected = Action::Map(vec![
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('o')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('n')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('e')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('l')),
+ Some(vec![Flag::Control]),
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('t')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('w')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('o')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('s')),
+ Some(vec![Flag::Meta]),
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('t')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('h')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('r')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('e')),
+ None,
+ ),
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new('e')),
+ None,
+ ),
+ ]);
+ let result = action_map().easy_parse(text).map(|t| t.0);
+
+ assert_eq!(result, Ok(expected));
}
#[test]
fn action_parses_map_with_multiple_modifiers() {