From 5d51b856b3a7a940457d78ccad8ee2eeed4a4326 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Thu, 5 Sep 2019 20:54:19 +0200 Subject: [PATCH] Add trigger for toggle --- src/config.rs | 26 ++++++++++++++------------ src/engine.rs | 8 +++++--- src/keyboard/mod.rs | 9 ++++++++- src/main.rs | 5 +++-- src/matcher/scrolling.rs | 36 ++++++++++++++++++++++++++---------- 5 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/config.rs b/src/config.rs index 97d5e45..a7c3095 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,25 +6,27 @@ use crate::matcher::Match; use std::fs::File; use std::io::Read; use serde::{Serialize, Deserialize}; +use crate::keyboard::KeyModifier; +use crate::keyboard::KeyModifier::*; // TODO: add documentation link const DEFAULT_CONFIG_FILE_CONTENT : &str = include_str!("res/config.yaml"); -#[derive(Debug, Serialize, Deserialize)] -pub struct Configs { - #[serde(default)] - pub backspace_enabled: bool, +// Default values for primitives - pub matches: Vec +fn default_toggle_interval() -> u32 { + 230 } -impl Default for Configs { - fn default() -> Self { - Configs { - backspace_enabled: false, - matches: Vec::new() - } - } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Configs { + #[serde(default)] + pub toggle_key: KeyModifier, + + #[serde(default = "default_toggle_interval")] + pub toggle_interval: u32, + + pub matches: Vec } impl Configs { diff --git a/src/engine.rs b/src/engine.rs index 824b34f..688cc04 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,13 +1,15 @@ use crate::matcher::{Match, MatchReceiver}; use crate::keyboard::KeyboardSender; +use crate::config::Configs; pub struct Engine where S: KeyboardSender { - sender: S + sender: S, + configs: Configs, } impl Engine where S: KeyboardSender{ - pub fn new(sender: S) -> Engine where S: KeyboardSender { - Engine{sender} + pub fn new(sender: S, configs: Configs) -> Engine where S: KeyboardSender { + Engine{sender, configs } } } diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index 0f949e6..1c38cd5 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -8,13 +8,14 @@ mod linux; mod macos; use std::sync::mpsc; +use serde::{Serialize, Deserialize}; pub trait KeyboardInterceptor { fn initialize(&self); fn start(&self); } -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum KeyModifier { CTRL, SHIFT, @@ -23,6 +24,12 @@ pub enum KeyModifier { BACKSPACE, } +impl Default for KeyModifier { + fn default() -> Self { + KeyModifier::ALT + } +} + #[derive(Debug)] pub enum KeyEvent { Char(char), diff --git a/src/main.rs b/src/main.rs index 0b876b2..fe719da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,15 +13,16 @@ mod config; fn main() { let configs = Configs::load_default(); + println!("{:#?}", configs); let (txc, rxc) = mpsc::channel(); let sender = keyboard::get_sender(); - let engine = Engine::new(sender); + let engine = Engine::new(sender, configs.clone()); thread::spawn(move || { - let matcher = ScrollingMatcher::new(configs.matches.to_vec(), engine); + let matcher = ScrollingMatcher::new(configs.clone(), engine); matcher.watch(rxc); }); diff --git a/src/matcher/scrolling.rs b/src/matcher/scrolling.rs index 1c7a445..4d48192 100644 --- a/src/matcher/scrolling.rs +++ b/src/matcher/scrolling.rs @@ -1,15 +1,19 @@ use crate::matcher::{Match, MatchReceiver}; use std::cell::RefCell; use crate::keyboard::KeyModifier; +use crate::config::Configs; +use crate::keyboard::KeyModifier::BACKSPACE; +use std::time::SystemTime; pub struct ScrollingMatcher<'a, R> where R: MatchReceiver{ - matches: Vec, + configs: Configs, receiver: R, - current_set: RefCell>> + current_set: RefCell>>, + toggle_press_time: RefCell } struct MatchEntry<'a> { - remaining: &'a str, + start: usize, _match: &'a Match } @@ -17,15 +21,17 @@ impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiv fn handle_char(&'a self, c: char) { let mut current_set = self.current_set.borrow_mut(); - let new_matches: Vec = self.matches.iter() + let new_matches: Vec = self.configs.matches.iter() .filter(|&x| x.trigger.chars().nth(0).unwrap() == c) - .map(|x | MatchEntry{remaining: &x.trigger[1..], _match: &x}) + .map(|x | MatchEntry{start: 1, _match: &x}) .collect(); // TODO: use an associative structure to improve the efficiency of this first "new_matches" lookup. let old_matches: Vec = (*current_set).iter() - .filter(|&x| x.remaining.chars().nth(0).unwrap() == c) - .map(|x | MatchEntry{remaining: &x.remaining[1..], _match: &x._match}) + .filter(|&x| { + x._match.trigger[x.start..].chars().nth(0).unwrap() == c + }) + .map(|x | MatchEntry{start: x.start+1, _match: &x._match}) .collect(); (*current_set) = old_matches; @@ -34,7 +40,7 @@ impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiv let mut found_match = None; for entry in (*current_set).iter() { - if entry.remaining.len() == 0 { + if entry.start == entry._match.trigger.len() { found_match = Some(entry._match); break; } @@ -47,13 +53,23 @@ impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiv } fn handle_modifier(&'a self, m: KeyModifier) { + if m == self.configs.toggle_key { + let mut toggle_press_time = self.toggle_press_time.borrow_mut(); + if let Ok(elapsed) = toggle_press_time.elapsed() { + if elapsed.as_millis() < self.configs.toggle_interval as u128 { + println!("Disable! {}", elapsed.as_millis()); + } + } + (*toggle_press_time) = SystemTime::now(); + } } } impl <'a, R> ScrollingMatcher<'a, R> where R: MatchReceiver { - pub fn new(matches:Vec, receiver: R) -> ScrollingMatcher<'a, R> { + pub fn new(configs: Configs, receiver: R) -> ScrollingMatcher<'a, R> { let current_set = RefCell::new(Vec::new()); - ScrollingMatcher{ matches, receiver, current_set } + let toggle_press_time = RefCell::new(SystemTime::now()); + ScrollingMatcher{ configs, receiver, current_set, toggle_press_time } } } \ No newline at end of file