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 | |
| 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.
| -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] | 
