espanso/src/matcher/scrolling.rs

59 lines
1.8 KiB
Rust
Raw Normal View History

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 15:20:52 +00:00
pub struct ScrollingMatcher<'a, R> where R: MatchReceiver{
matches: Vec<Match>,
receiver: R,
current_set: RefCell<Vec<MatchEntry<'a>>>
2019-08-31 15:00:23 +00:00
}
struct MatchEntry<'a> {
remaining: &'a str,
_match: &'a Match
}
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) {
let mut current_set = self.current_set.borrow_mut();
let new_matches: Vec<MatchEntry> = self.matches.iter()
2019-08-31 15:00:23 +00:00
.filter(|&x| x.trigger.chars().nth(0).unwrap() == c)
.map(|x | MatchEntry{remaining: &x.trigger[1..], _match: &x})
.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-08-31 15:00:23 +00:00
.filter(|&x| x.remaining.chars().nth(0).unwrap() == c)
.map(|x | MatchEntry{remaining: &x.remaining[1..], _match: &x._match})
.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-08-31 15:00:23 +00:00
if entry.remaining.len() == 0 {
2019-09-01 18:46:46 +00:00
found_match = Some(entry._match);
2019-08-31 15:00:23 +00:00
break;
}
}
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-09-05 17:18:55 +00:00
fn handle_modifier(&'a self, m: KeyModifier) {
}
}
2019-09-05 15:20:52 +00:00
impl <'a, R> ScrollingMatcher<'a, R> where R: MatchReceiver {
pub fn new(matches:Vec<Match>, receiver: R) -> ScrollingMatcher<'a, R> {
let current_set = RefCell::new(Vec::new());
2019-08-31 15:00:23 +00:00
ScrollingMatcher{ matches, receiver, current_set }
}
}