aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.rs
diff options
context:
space:
mode:
authorTeddy Wing2018-09-30 20:43:27 +0200
committerTeddy Wing2018-09-30 20:43:27 +0200
commitdc606d756ceecf5ae8a52e607fd4a68727fd2529 (patch)
tree12321df9e5df7462ae875193ea61ac8872a21a03 /src/parser.rs
parent7801f2561227526e7bacf9915bb4d7f63cf14449 (diff)
downloaddome-key-map-dc606d756ceecf5ae8a52e607fd4a68727fd2529.tar.bz2
special_key(): Handle modifier + character special keys
Previously we were able to parse modifier + KeyCode (`<C-Enter>`) special keys and plain KeyCode ones (`<Esc>`). This change adds parsing support for the final type of special key, modifier + character (e.g. `<C-l>`). action_character(): Move the `map` outside of this function and into `action_map()` to allow us to reuse the parsed `char` in `special_key()`. key_modifier(): * Move the `many()` parser and `Option` handling outside of this function and into `special_key()`. Doing so enables us to say: <C-l> // Character special keys _require_ a modifier (thus // `many1`) <[C-]Left> // KeyCode special keys may or may not have a modifier // (thus `many`) * Rename from `key_modifiers()` to singular now that it only parses a single modifier. special_key(): Parse both character and KeyCode special keys with modifiers. action_parses_map_with_modifier(): Change input string to include a KeyCode-style special key with a modifier since we didn't have one previously. This ensures we test both kinds of special keys.
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs101
1 files changed, 47 insertions, 54 deletions
diff --git a/src/parser.rs b/src/parser.rs
index 0ccb05d..0389cf5 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -207,14 +207,20 @@ where
(
many(
choice!(
- action_character(),
+ action_character()
+ .map(|c|
+ KeyboardKeyWithModifiers::new(
+ KeyboardKey::Character(Character::new(c)),
+ None,
+ )
+ ),
special_key()
)
),
).map(|(keys,)| Action::Map(keys))
}
-fn action_character<I>() -> impl Parser<Input = I, Output = KeyboardKeyWithModifiers>
+fn action_character<I>() -> impl Parser<Input = I, Output = char>
where
I: Stream<Item = char>,
I::Error: ParseError<I::Item, I::Range, I::Position>,
@@ -223,12 +229,6 @@ where
satisfy(|c| c != '<' && c != '\\'),
action_escape()
)
- .map(|c|
- KeyboardKeyWithModifiers::new(
- KeyboardKey::Character(Character::new(c)),
- None,
- )
- )
}
fn action_escape<I>() -> impl Parser<Input = I, Output = char>
@@ -247,40 +247,49 @@ where
I: Stream<Item = char>,
I::Error: ParseError<I::Item, I::Range, I::Position>,
{
- between(token('<'), token('>'), (
- key_modifiers(),
- key_code()
- ))
- .map(|(modifiers, code)|
- KeyboardKeyWithModifiers::new(
- KeyboardKey::KeyCode(code),
- modifiers,
- )
+ between(
+ token('<'),
+ token('>'),
+ or(
+ try((
+ many(key_modifier()),
+ key_code().map(|code| KeyboardKey::KeyCode(code)),
+ )),
+ try((
+ many1(key_modifier()),
+ action_character().map(|c|
+ KeyboardKey::Character(Character::new(c))
+ ),
+ ))
+ )
+ ).map(|(modifiers, key): (Vec<Flag>, KeyboardKey)| {
+ let modifiers = if modifiers.is_empty() {
+ None
+ } else {
+ Some(modifiers)
+ };
+
+ KeyboardKeyWithModifiers::new(
+ key,
+ modifiers,
)
+ })
}
-fn key_modifiers<I>() -> impl Parser<Input = I, Output = Option<Vec<Flag>>>
+fn key_modifier<I>() -> impl Parser<Input = I, Output = 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)
- }
+ choice!(
+ try(string_case_insensitive("D-"))
+ .map(|_| Flag::Meta),
+ try(string_case_insensitive("A-"))
+ .map(|_| Flag::Alt),
+ try(string_case_insensitive("C-"))
+ .map(|_| Flag::Control),
+ try(string_case_insensitive("S-"))
+ .map(|_| Flag::Shift)
)
}
@@ -576,7 +585,7 @@ mod tests {
#[test]
fn action_parses_map_with_modifier() {
- let text = "one<C-l>two<D-s>three";
+ let text = "one<C-l>two<D-s><A-Left>";
let expected = Action::Map(vec![
KeyboardKeyWithModifiers::new(
@@ -612,24 +621,8 @@ mod tests {
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,
+ KeyboardKey::KeyCode(KeyCode::new(autopilot::key::KeyCode::LeftArrow)),
+ Some(vec![Flag::Alt]),
),
]);
let result = action_map().easy_parse(text).map(|t| t.0);