aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.rs
diff options
context:
space:
mode:
authorTeddy Wing2018-09-30 17:45:01 +0200
committerTeddy Wing2018-09-30 17:45:01 +0200
commit29ea66e861420049f593cbaabace13c091db345a (patch)
treeee1caef34a3f2d920e1bcafbf6b82e2467c15058 /src/parser.rs
parent55432d2df2c3957b7bd022d163c9cec6b317376e (diff)
downloaddome-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/parser.rs')
-rw-r--r--src/parser.rs114
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]