2019-08-31 14:07:45 +00:00
|
|
|
use crate::matcher::{Match, MatchReceiver};
|
2019-09-05 15:20:52 +00:00
|
|
|
use std::cell::RefCell;
|
2019-09-05 17:18:55 +00:00
|
|
|
use crate::keyboard::KeyModifier;
|
2019-09-05 18:54:19 +00:00
|
|
|
use crate::config::Configs;
|
|
|
|
use crate::keyboard::KeyModifier::BACKSPACE;
|
|
|
|
use std::time::SystemTime;
|
2019-08-31 14:07:45 +00:00
|
|
|
|
2019-09-05 15:20:52 +00:00
|
|
|
pub struct ScrollingMatcher<'a, R> where R: MatchReceiver{
|
2019-09-05 18:54:19 +00:00
|
|
|
configs: Configs,
|
2019-09-05 15:20:52 +00:00
|
|
|
receiver: R,
|
2019-09-05 18:54:19 +00:00
|
|
|
current_set: RefCell<Vec<MatchEntry<'a>>>,
|
2019-09-05 17:51:16 +00:00
|
|
|
toggle_press_time: RefCell<SystemTime>,
|
|
|
|
is_enabled: RefCell<bool>,
|
2019-08-31 15:00:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct MatchEntry<'a> {
|
2019-09-05 18:54:19 +00:00
|
|
|
start: usize,
|
2019-08-31 15:00:23 +00:00
|
|
|
_match: &'a Match
|
2019-08-31 14:07:45 +00:00
|
|
|
}
|
|
|
|
|
2019-09-05 15:20:52 +00:00
|
|
|
impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiver+Send{
|
|
|
|
fn handle_char(&'a self, c: char) {
|
2019-09-05 17:51:16 +00:00
|
|
|
// if not enabled, avoid any processing
|
|
|
|
if !*(self.is_enabled.borrow()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-05 15:20:52 +00:00
|
|
|
let mut current_set = self.current_set.borrow_mut();
|
|
|
|
|
2019-09-05 18:54:19 +00:00
|
|
|
let new_matches: Vec<MatchEntry> = self.configs.matches.iter()
|
2019-08-31 15:00:23 +00:00
|
|
|
.filter(|&x| x.trigger.chars().nth(0).unwrap() == c)
|
2019-09-05 18:54:19 +00:00
|
|
|
.map(|x | MatchEntry{start: 1, _match: &x})
|
2019-08-31 15:00:23 +00:00
|
|
|
.collect();
|
|
|
|
// TODO: use an associative structure to improve the efficiency of this first "new_matches" lookup.
|
|
|
|
|
2019-09-05 15:20:52 +00:00
|
|
|
let old_matches: Vec<MatchEntry> = (*current_set).iter()
|
2019-09-05 18:54:19 +00:00
|
|
|
.filter(|&x| {
|
|
|
|
x._match.trigger[x.start..].chars().nth(0).unwrap() == c
|
|
|
|
})
|
|
|
|
.map(|x | MatchEntry{start: x.start+1, _match: &x._match})
|
2019-08-31 15:00:23 +00:00
|
|
|
.collect();
|
2019-09-05 15:20:52 +00:00
|
|
|
|
|
|
|
(*current_set) = old_matches;
|
|
|
|
(*current_set).extend(new_matches);
|
2019-08-31 15:00:23 +00:00
|
|
|
|
2019-09-01 18:46:46 +00:00
|
|
|
let mut found_match = None;
|
2019-08-31 15:00:23 +00:00
|
|
|
|
2019-09-05 15:20:52 +00:00
|
|
|
for entry in (*current_set).iter() {
|
2019-09-05 18:54:19 +00:00
|
|
|
if entry.start == entry._match.trigger.len() {
|
2019-09-01 18:46:46 +00:00
|
|
|
found_match = Some(entry._match);
|
2019-08-31 15:00:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-08-31 14:07:45 +00:00
|
|
|
|
2019-09-01 18:46:46 +00:00
|
|
|
if let Some(_match) = found_match {
|
2019-09-05 15:20:52 +00:00
|
|
|
(*current_set).clear();
|
2019-08-31 15:00:23 +00:00
|
|
|
self.receiver.on_match(_match);
|
2019-08-31 14:07:45 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-05 17:18:55 +00:00
|
|
|
|
|
|
|
fn handle_modifier(&'a self, m: KeyModifier) {
|
2019-09-05 18:54:19 +00:00
|
|
|
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 {
|
2019-09-05 17:51:16 +00:00
|
|
|
let mut is_enabled = self.is_enabled.borrow_mut();
|
|
|
|
*is_enabled = !(*is_enabled);
|
|
|
|
|
|
|
|
if !*is_enabled {
|
|
|
|
self.current_set.borrow_mut().clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
println!("Enabled {}", *is_enabled);
|
2019-09-05 18:54:19 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-05 17:18:55 +00:00
|
|
|
|
2019-09-05 18:54:19 +00:00
|
|
|
(*toggle_press_time) = SystemTime::now();
|
|
|
|
}
|
2019-09-05 17:18:55 +00:00
|
|
|
}
|
2019-08-31 14:07:45 +00:00
|
|
|
}
|
|
|
|
|
2019-09-05 15:20:52 +00:00
|
|
|
impl <'a, R> ScrollingMatcher<'a, R> where R: MatchReceiver {
|
2019-09-05 18:54:19 +00:00
|
|
|
pub fn new(configs: Configs, receiver: R) -> ScrollingMatcher<'a, R> {
|
2019-09-05 15:20:52 +00:00
|
|
|
let current_set = RefCell::new(Vec::new());
|
2019-09-05 18:54:19 +00:00
|
|
|
let toggle_press_time = RefCell::new(SystemTime::now());
|
2019-09-05 17:51:16 +00:00
|
|
|
|
|
|
|
ScrollingMatcher{
|
|
|
|
configs,
|
|
|
|
receiver,
|
|
|
|
current_set,
|
|
|
|
toggle_press_time,
|
|
|
|
is_enabled: RefCell::new(true)
|
|
|
|
}
|
2019-08-31 14:07:45 +00:00
|
|
|
}
|
|
|
|
}
|