diff options
| author | Teddy Wing | 2018-09-30 17:45:01 +0200 |
|---|---|---|
| committer | Teddy Wing | 2018-09-30 17:45:01 +0200 |
| commit | 29ea66e861420049f593cbaabace13c091db345a (patch) | |
| tree | ee1caef34a3f2d920e1bcafbf6b82e2467c15058 /src | |
| parent | 55432d2df2c3957b7bd022d163c9cec6b317376e (diff) | |
| download | dome-key-map-29ea66e861420049f593cbaabace13c091db345a.tar.bz2 | |
action_map(): Add backslash escaping
Escape '<' and '\' by prepending a backslash. Since special characters
are enclosed in '<' '>' brackets, in order to type a literal '<', we
need a way to escape it. Use backslash, like in Vim.
Diffstat (limited to 'src')
| -rw-r--r-- | src/parser.rs | 114 |
1 files changed, 113 insertions, 1 deletions
diff --git a/src/parser.rs b/src/parser.rs index d82cdaf..37d69df 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -219,7 +219,10 @@ where I: Stream<Item = char>, I::Error: ParseError<I::Item, I::Range, I::Position>, { - satisfy(|c| c != '<') + or( + satisfy(|c| c != '<' && c != '\\'), + action_escape() + ) .map(|c| KeyboardKeyWithModifiers::new( KeyboardKey::Character(Character::new(c)), @@ -228,6 +231,17 @@ where ) } +fn action_escape<I>() -> impl Parser<Input = I, Output = char> +where + I: Stream<Item = char>, + I::Error: ParseError<I::Item, I::Range, I::Position>, +{ + choice!( + try(string("\\\\")).map(|_| '\\'), + try(string("\\<")).map(|_| '<') + ) +} + fn special_key<I>() -> impl Parser<Input = I, Output = KeyboardKeyWithModifiers> where I: Stream<Item = char>, @@ -594,10 +608,108 @@ mod tests { #[test] fn action_parses_map_with_backslash_escape() { + let text = "type\\\\onebslash"; + + let expected = Action::Map(vec![ + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('t')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('y')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('p')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('e')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('\\')), + None, + ), + 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('b')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('s')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('l')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('a')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('s')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('h')), + None, + ), + ]); + let result = action_map().easy_parse(text).map(|t| t.0); + + assert_eq!(result, Ok(expected)); } #[test] fn action_parses_map_with_less_than_escape() { + let text = "type\\<lt"; + + let expected = Action::Map(vec![ + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('t')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('y')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('p')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('e')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('<')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('l')), + None, + ), + KeyboardKeyWithModifiers::new( + KeyboardKey::Character(Character::new('t')), + None, + ), + ]); + let result = action_map().easy_parse(text).map(|t| t.0); + + assert_eq!(result, Ok(expected)); } #[test] |
