Add backspace corrections
This commit is contained in:
		
							parent
							
								
									189da97f0d
								
							
						
					
					
						commit
						778375c574
					
				| 
						 | 
					@ -7,7 +7,6 @@ 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;
 | 
				
			||||||
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");
 | 
				
			||||||
| 
						 | 
					@ -18,6 +17,10 @@ fn default_toggle_interval() -> u32 {
 | 
				
			||||||
    230
 | 
					    230
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn default_backspace_limit() -> i32 {
 | 
				
			||||||
 | 
					    3
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
 | 
					#[derive(Clone, Debug, Serialize, Deserialize)]
 | 
				
			||||||
pub struct Configs {
 | 
					pub struct Configs {
 | 
				
			||||||
    #[serde(default)]
 | 
					    #[serde(default)]
 | 
				
			||||||
| 
						 | 
					@ -26,6 +29,9 @@ pub struct Configs {
 | 
				
			||||||
    #[serde(default = "default_toggle_interval")]
 | 
					    #[serde(default = "default_toggle_interval")]
 | 
				
			||||||
    pub toggle_interval: u32,
 | 
					    pub toggle_interval: u32,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[serde(default = "default_backspace_limit")]
 | 
				
			||||||
 | 
					    pub backspace_limit: i32,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub matches: Vec<Match>
 | 
					    pub matches: Vec<Match>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,3 @@
 | 
				
			||||||
use std::thread;
 | 
					 | 
				
			||||||
use std::sync::mpsc;
 | 
					use std::sync::mpsc;
 | 
				
			||||||
use widestring::{U16CString};
 | 
					use widestring::{U16CString};
 | 
				
			||||||
use crate::keyboard::{KeyEvent, KeyModifier};
 | 
					use crate::keyboard::{KeyEvent, KeyModifier};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,11 +4,12 @@ use crate::keyboard::KeyModifier;
 | 
				
			||||||
use crate::config::Configs;
 | 
					use crate::config::Configs;
 | 
				
			||||||
use crate::keyboard::KeyModifier::BACKSPACE;
 | 
					use crate::keyboard::KeyModifier::BACKSPACE;
 | 
				
			||||||
use std::time::SystemTime;
 | 
					use std::time::SystemTime;
 | 
				
			||||||
 | 
					use std::collections::VecDeque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct ScrollingMatcher<'a, R> where R: MatchReceiver{
 | 
					pub struct ScrollingMatcher<'a, R> where R: MatchReceiver{
 | 
				
			||||||
    configs: Configs,
 | 
					    configs: Configs,
 | 
				
			||||||
    receiver: R,
 | 
					    receiver: R,
 | 
				
			||||||
    current_set: RefCell<Vec<MatchEntry<'a>>>,
 | 
					    current_set_queue: RefCell<VecDeque<Vec<MatchEntry<'a>>>>,
 | 
				
			||||||
    toggle_press_time: RefCell<SystemTime>,
 | 
					    toggle_press_time: RefCell<SystemTime>,
 | 
				
			||||||
    is_enabled: RefCell<bool>,
 | 
					    is_enabled: RefCell<bool>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -25,7 +26,7 @@ impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiv
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut current_set = self.current_set.borrow_mut();
 | 
					        let mut current_set_queue = self.current_set_queue.borrow_mut();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let new_matches: Vec<MatchEntry> = self.configs.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)
 | 
				
			||||||
| 
						 | 
					@ -33,27 +34,40 @@ impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiv
 | 
				
			||||||
            .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 combined_matches: Vec<MatchEntry> = match current_set_queue.back() {
 | 
				
			||||||
 | 
					            Some(last_matches) => {
 | 
				
			||||||
 | 
					                let mut updated: Vec<MatchEntry> = last_matches.iter()
 | 
				
			||||||
                    .filter(|&x| {
 | 
					                    .filter(|&x| {
 | 
				
			||||||
                        x._match.trigger[x.start..].chars().nth(0).unwrap() == c
 | 
					                        x._match.trigger[x.start..].chars().nth(0).unwrap() == c
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    .map(|x | MatchEntry{start: x.start+1, _match: &x._match})
 | 
					                    .map(|x | MatchEntry{start: x.start+1, _match: &x._match})
 | 
				
			||||||
                    .collect();
 | 
					                    .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        (*current_set) = old_matches;
 | 
					                updated.extend(new_matches);
 | 
				
			||||||
        (*current_set).extend(new_matches);
 | 
					                updated
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            None => {new_matches},
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut found_match = None;
 | 
					        let mut found_match = None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for entry in (*current_set).iter() {
 | 
					        for entry in combined_matches.iter() {
 | 
				
			||||||
            if entry.start == entry._match.trigger.len() {
 | 
					            if entry.start == entry._match.trigger.len() {
 | 
				
			||||||
                found_match = Some(entry._match);
 | 
					                found_match = Some(entry._match);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_set_queue.push_back(combined_matches);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if current_set_queue.len() as i32 > (self.configs.backspace_limit + 1) {
 | 
				
			||||||
 | 
					            current_set_queue.pop_front();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if let Some(_match) = found_match {
 | 
					        if let Some(_match) = found_match {
 | 
				
			||||||
            (*current_set).clear();
 | 
					            if let Some(last) = current_set_queue.back_mut() {
 | 
				
			||||||
 | 
					                last.clear();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            self.receiver.on_match(_match);
 | 
					            self.receiver.on_match(_match);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -67,7 +81,7 @@ impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiv
 | 
				
			||||||
                    *is_enabled = !(*is_enabled);
 | 
					                    *is_enabled = !(*is_enabled);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if !*is_enabled {
 | 
					                    if !*is_enabled {
 | 
				
			||||||
                        self.current_set.borrow_mut().clear();
 | 
					                        self.current_set_queue.borrow_mut().clear();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    println!("Enabled {}", *is_enabled);
 | 
					                    println!("Enabled {}", *is_enabled);
 | 
				
			||||||
| 
						 | 
					@ -76,18 +90,23 @@ impl <'a, R> super::Matcher<'a> for ScrollingMatcher<'a, R> where R: MatchReceiv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            (*toggle_press_time) = SystemTime::now();
 | 
					            (*toggle_press_time) = SystemTime::now();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Backspace handling, basically "rewinding history"
 | 
				
			||||||
 | 
					        if m == BACKSPACE {
 | 
				
			||||||
 | 
					            let mut current_set_queue = self.current_set_queue.borrow_mut();
 | 
				
			||||||
 | 
					            current_set_queue.pop_back();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
impl <'a, R> ScrollingMatcher<'a, R> where R: MatchReceiver {
 | 
					impl <'a, R> ScrollingMatcher<'a, R> where R: MatchReceiver {
 | 
				
			||||||
    pub fn new(configs: Configs, 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_queue = RefCell::new(VecDeque::new());
 | 
				
			||||||
        let toggle_press_time = RefCell::new(SystemTime::now());
 | 
					        let toggle_press_time = RefCell::new(SystemTime::now());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ScrollingMatcher{
 | 
					        ScrollingMatcher{
 | 
				
			||||||
            configs,
 | 
					            configs,
 | 
				
			||||||
            receiver,
 | 
					            receiver,
 | 
				
			||||||
            current_set,
 | 
					            current_set_queue,
 | 
				
			||||||
            toggle_press_time,
 | 
					            toggle_press_time,
 | 
				
			||||||
            is_enabled: RefCell::new(true)
 | 
					            is_enabled: RefCell::new(true)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user