Add trigger for toggle
This commit is contained in:
parent
2d9af53e74
commit
5d51b856b3
|
@ -6,25 +6,27 @@ use crate::matcher::Match;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
use crate::keyboard::KeyModifier;
|
||||||
|
use crate::keyboard::KeyModifier::*;
|
||||||
|
|
||||||
// TODO: add documentation link
|
// TODO: add documentation link
|
||||||
const DEFAULT_CONFIG_FILE_CONTENT : &str = include_str!("res/config.yaml");
|
const DEFAULT_CONFIG_FILE_CONTENT : &str = include_str!("res/config.yaml");
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
// Default values for primitives
|
||||||
pub struct Configs {
|
|
||||||
#[serde(default)]
|
|
||||||
pub backspace_enabled: bool,
|
|
||||||
|
|
||||||
pub matches: Vec<Match>
|
fn default_toggle_interval() -> u32 {
|
||||||
|
230
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Configs {
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
fn default() -> Self {
|
pub struct Configs {
|
||||||
Configs {
|
#[serde(default)]
|
||||||
backspace_enabled: false,
|
pub toggle_key: KeyModifier,
|
||||||
matches: Vec::new()
|
|
||||||
}
|
#[serde(default = "default_toggle_interval")]
|
||||||
}
|
pub toggle_interval: u32,
|
||||||
|
|
||||||
|
pub matches: Vec<Match>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Configs {
|
impl Configs {
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
use crate::matcher::{Match, MatchReceiver};
|
use crate::matcher::{Match, MatchReceiver};
|
||||||
use crate::keyboard::KeyboardSender;
|
use crate::keyboard::KeyboardSender;
|
||||||
|
use crate::config::Configs;
|
||||||
|
|
||||||
pub struct Engine<S> where S: KeyboardSender {
|
pub struct Engine<S> where S: KeyboardSender {
|
||||||
sender: S
|
sender: S,
|
||||||
|
configs: Configs,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <S> Engine<S> where S: KeyboardSender{
|
impl <S> Engine<S> where S: KeyboardSender{
|
||||||
pub fn new(sender: S) -> Engine<S> where S: KeyboardSender {
|
pub fn new(sender: S, configs: Configs) -> Engine<S> where S: KeyboardSender {
|
||||||
Engine{sender}
|
Engine{sender, configs }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,14 @@ mod linux;
|
||||||
mod macos;
|
mod macos;
|
||||||
|
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
pub trait KeyboardInterceptor {
|
pub trait KeyboardInterceptor {
|
||||||
fn initialize(&self);
|
fn initialize(&self);
|
||||||
fn start(&self);
|
fn start(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum KeyModifier {
|
pub enum KeyModifier {
|
||||||
CTRL,
|
CTRL,
|
||||||
SHIFT,
|
SHIFT,
|
||||||
|
@ -23,6 +24,12 @@ pub enum KeyModifier {
|
||||||
BACKSPACE,
|
BACKSPACE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for KeyModifier {
|
||||||
|
fn default() -> Self {
|
||||||
|
KeyModifier::ALT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum KeyEvent {
|
pub enum KeyEvent {
|
||||||
Char(char),
|
Char(char),
|
||||||
|
|
|
@ -13,15 +13,16 @@ mod config;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let configs = Configs::load_default();
|
let configs = Configs::load_default();
|
||||||
|
println!("{:#?}", configs);
|
||||||
|
|
||||||
let (txc, rxc) = mpsc::channel();
|
let (txc, rxc) = mpsc::channel();
|
||||||
|
|
||||||
let sender = keyboard::get_sender();
|
let sender = keyboard::get_sender();
|
||||||
|
|
||||||
let engine = Engine::new(sender);
|
let engine = Engine::new(sender, configs.clone());
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let matcher = ScrollingMatcher::new(configs.matches.to_vec(), engine);
|
let matcher = ScrollingMatcher::new(configs.clone(), engine);
|
||||||
matcher.watch(rxc);
|
matcher.watch(rxc);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
use crate::matcher::{Match, MatchReceiver};
|
use crate::matcher::{Match, MatchReceiver};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use crate::keyboard::KeyModifier;
|
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{
|
pub struct ScrollingMatcher<'a, R> where R: MatchReceiver{
|
||||||
matches: Vec<Match>,
|
configs: Configs,
|
||||||
receiver: R,
|
receiver: R,
|
||||||
current_set: RefCell<Vec<MatchEntry<'a>>>
|
current_set: RefCell<Vec<MatchEntry<'a>>>,
|
||||||
|
toggle_press_time: RefCell<SystemTime>
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MatchEntry<'a> {
|
struct MatchEntry<'a> {
|
||||||
remaining: &'a str,
|
start: usize,
|
||||||
_match: &'a Match
|
_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) {
|
fn handle_char(&'a self, c: char) {
|
||||||
let mut current_set = self.current_set.borrow_mut();
|
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)
|
.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();
|
.collect();
|
||||||
// TODO: use an associative structure to improve the efficiency of this first "new_matches" lookup.
|
// TODO: use an associative structure to improve the efficiency of this first "new_matches" lookup.
|
||||||
|
|
||||||
let old_matches: Vec<MatchEntry> = (*current_set).iter()
|
let old_matches: Vec<MatchEntry> = (*current_set).iter()
|
||||||
.filter(|&x| x.remaining.chars().nth(0).unwrap() == c)
|
.filter(|&x| {
|
||||||
.map(|x | MatchEntry{remaining: &x.remaining[1..], _match: &x._match})
|
x._match.trigger[x.start..].chars().nth(0).unwrap() == c
|
||||||
|
})
|
||||||
|
.map(|x | MatchEntry{start: x.start+1, _match: &x._match})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
(*current_set) = old_matches;
|
(*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;
|
let mut found_match = None;
|
||||||
|
|
||||||
for entry in (*current_set).iter() {
|
for entry in (*current_set).iter() {
|
||||||
if entry.remaining.len() == 0 {
|
if entry.start == entry._match.trigger.len() {
|
||||||
found_match = Some(entry._match);
|
found_match = Some(entry._match);
|
||||||
break;
|
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) {
|
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 {
|
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());
|
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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user