Add trigger for toggle

This commit is contained in:
Federico Terzi 2019-09-05 20:54:19 +02:00
parent 2d9af53e74
commit 5d51b856b3
5 changed files with 56 additions and 28 deletions

View File

@ -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<Match>
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<Match>
}
impl Configs {

View File

@ -1,13 +1,15 @@
use crate::matcher::{Match, MatchReceiver};
use crate::keyboard::KeyboardSender;
use crate::config::Configs;
pub struct Engine<S> where S: KeyboardSender {
sender: S
sender: S,
configs: Configs,
}
impl <S> Engine<S> where S: KeyboardSender{
pub fn new(sender: S) -> Engine<S> where S: KeyboardSender {
Engine{sender}
pub fn new(sender: S, configs: Configs) -> Engine<S> where S: KeyboardSender {
Engine{sender, configs }
}
}

View File

@ -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),

View File

@ -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);
});

View File

@ -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<Match>,
configs: Configs,
receiver: R,
current_set: RefCell<Vec<MatchEntry<'a>>>
current_set: RefCell<Vec<MatchEntry<'a>>>,
toggle_press_time: RefCell<SystemTime>
}
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<MatchEntry> = self.matches.iter()
let new_matches: Vec<MatchEntry> = 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<MatchEntry> = (*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<Match>, 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 }
}
}