From 2582f054c40d55a770674694e0d05d48ce64c77a Mon Sep 17 00:00:00 2001 From: Brady Fomegne Date: Sat, 16 Sep 2023 00:20:24 +0100 Subject: [PATCH] fix(clafrica): conflict between translator and processor Before, it's was not really possible to use the translator and the processor simultaneously. --- clafrica/data/test.toml | 1 + clafrica/src/lib.rs | 39 ++++++++++++++------------ clafrica/src/processor.rs | 58 +++++++++++++++++++++------------------ 3 files changed, 54 insertions(+), 44 deletions(-) diff --git a/clafrica/data/test.toml b/clafrica/data/test.toml index 77a7c40..3da7d40 100644 --- a/clafrica/data/test.toml +++ b/clafrica/data/test.toml @@ -28,3 +28,4 @@ hi = "./scripts/hi.rhai" hello = "hi" heli = "helicopter" hea = "health" +vuue = "vʉe" diff --git a/clafrica/src/lib.rs b/clafrica/src/lib.rs index a00b1d4..85d3627 100644 --- a/clafrica/src/lib.rs +++ b/clafrica/src/lib.rs @@ -102,33 +102,31 @@ pub fn run( .expect("We couldn't cancel the special function key"); is_special_pressed = false; - if let Some(predicate) = frontend.get_selected_predicate() { - processor.commit(&predicate.0, &predicate.1, &predicate.2); + if let Some((_code, _remaining_code, text)) = frontend.get_selected_predicate() { + processor.commit(text); frontend.clear_predicates(); } } _ if is_special_pressed => (), _ => { - let (changed, committed) = processor.process(event); + let (changed, _committed) = processor.process(event); if changed { let input = processor.get_input(); frontend.clear_predicates(); - if !committed { - translator.translate(&input).iter().for_each( - |(code, remaining_code, texts, translated)| { - texts.iter().for_each(|text| { - if auto_commit && *translated { - processor.commit(code, remaining_code, text); - } else if !text.is_empty() { - frontend.add_predicate(code, remaining_code, text); - } - }); - }, - ); - }; + translator.translate(&input).iter().for_each( + |(code, remaining_code, texts, translated)| { + texts.iter().for_each(|text| { + if auto_commit && *translated { + processor.commit(text); + } else if !text.is_empty() { + frontend.add_predicate(code, remaining_code, text); + } + }); + }, + ); frontend.set_input(&input); frontend.display(); @@ -152,7 +150,6 @@ mod tests { $( thread::sleep($delay); rdev::simulate(&KeyPress($key)).unwrap(); - thread::sleep($delay); rdev::simulate(&KeyRelease($key)).unwrap(); )* ); @@ -209,7 +206,7 @@ mod tests { #[test] fn test_simple() { - let typing_speed_ms = Duration::from_millis(300); + let typing_speed_ms = Duration::from_millis(500); // To detect excessive backspace const LIMIT: &str = "bbb"; @@ -279,5 +276,11 @@ mod tests { input!(ControlRight, typing_speed_ms); rdev::simulate(&KeyRelease(ControlLeft)).unwrap(); output!(textfield, format!("{LIMIT}uuɑαⱭⱭɑɑhihellohi")); + input!(Escape, typing_speed_ms); + + // We verify that we don't have a conflict + // between the translator and the processor + input!(KeyV KeyU KeyU KeyE, typing_speed_ms); + output!(textfield, format!("{LIMIT}uuɑαⱭⱭɑɑhihellohivʉe")); } } diff --git a/clafrica/src/processor.rs b/clafrica/src/processor.rs index 2f8eab1..9722041 100644 --- a/clafrica/src/processor.rs +++ b/clafrica/src/processor.rs @@ -17,6 +17,27 @@ impl Processor { } } + fn rollback(&mut self) -> bool { + self.keyboard.key_up(Key::Backspace); + + if let Some(out) = self.cursor.undo() { + (1..out.chars().count()).for_each(|_| self.keyboard.key_click(Key::Backspace)); + + // Clear the remaining code + while let (None, 1.., ..) = self.cursor.state() { + self.cursor.undo(); + } + + if let (Some(_in), ..) = self.cursor.state() { + self.keyboard.key_sequence(&_in); + } + + true + } else { + false + } + } + pub fn process(&mut self, event: Event) -> (bool, bool) { let character = event.name.and_then(|s| s.chars().next()); let is_valid = character @@ -26,26 +47,10 @@ impl Processor { match event.event_type { EventType::KeyPress(E_Key::Backspace) => { - if let Some(out) = self.cursor.undo() { - self.pause(); - self.keyboard.key_up(Key::Backspace); - - (1..out.chars().count()).for_each(|_| self.keyboard.key_click(Key::Backspace)); - - // Clear the remaining code - while let (None, 1.., ..) = self.cursor.state() { - self.cursor.undo(); - } - - if let (Some(_in), ..) = self.cursor.state() { - self.keyboard.key_sequence(&_in); - } - - self.resume(); - committed = true; - } - + self.pause(); + committed = self.rollback(); changed = true; + self.resume(); } EventType::KeyPress( E_Key::Unknown(_) | E_Key::ShiftLeft | E_Key::ShiftRight | E_Key::CapsLock, @@ -57,11 +62,10 @@ impl Processor { changed = true; } EventType::KeyPress(_) => { + self.pause(); let character = character.unwrap(); if let Some(_in) = self.cursor.hit(character) { - self.pause(); - let mut prev_cursor = self.cursor.clone(); prev_cursor.undo(); self.keyboard.key_click(Key::Backspace); @@ -78,11 +82,11 @@ impl Processor { } self.keyboard.key_sequence(&_in); - self.resume(); committed = true; }; changed = true; + self.resume(); } _ => (), }; @@ -90,14 +94,16 @@ impl Processor { (changed, committed) } - pub fn commit(&mut self, code: &str, remaining_code: &str, text: &str) { + pub fn commit(&mut self, text: &str) { self.pause(); - (0..code.len() - remaining_code.len()) - .for_each(|_| self.keyboard.key_click(Key::Backspace)); + while !self.cursor.is_empty() { + self.keyboard.key_down(Key::Backspace); + self.rollback(); + } self.keyboard.key_sequence(text); - self.resume(); // We clear the buffer self.cursor.clear(); + self.resume(); } fn pause(&mut self) {