Convert matching system to unicode strings instead of chars. Fix #78
This commit is contained in:
parent
ebc4cacd27
commit
a19b90e50a
|
@ -18,12 +18,13 @@
|
|||
*/
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::os::raw::c_void;
|
||||
use std::os::raw::{c_void, c_char};
|
||||
use crate::event::*;
|
||||
use crate::event::KeyModifier::*;
|
||||
use crate::bridge::linux::*;
|
||||
use std::process::exit;
|
||||
use log::error;
|
||||
use std::ffi::CStr;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct LinuxContext {
|
||||
|
@ -74,14 +75,19 @@ extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const u8, len: i32,
|
|||
let _self = _self as *mut LinuxContext;
|
||||
|
||||
if is_modifier == 0 { // Char event
|
||||
// Convert the received buffer to a character
|
||||
let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
|
||||
let r = String::from_utf8_lossy(buffer).chars().nth(0);
|
||||
// Convert the received buffer to a string
|
||||
let c_str = CStr::from_ptr(raw_buffer as (*const c_char));
|
||||
let char_str = c_str.to_str();
|
||||
|
||||
// Send the char through the channel
|
||||
if let Some(c) = r {
|
||||
let event = Event::Key(KeyEvent::Char(c));
|
||||
(*_self).send_channel.send(event).unwrap();
|
||||
match char_str {
|
||||
Ok(char_str) => {
|
||||
let event = Event::Key(KeyEvent::Char(char_str.to_owned()));
|
||||
(*_self).send_channel.send(event).unwrap();
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Unable to receive char: {}",e);
|
||||
},
|
||||
}
|
||||
}else{ // Modifier event
|
||||
let modifier: Option<KeyModifier> = match key_code {
|
||||
|
|
|
@ -110,7 +110,7 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa
|
|||
return;
|
||||
}
|
||||
|
||||
self.keyboard_manager.delete_string(m.trigger.len() as i32);
|
||||
self.keyboard_manager.delete_string(m.trigger.chars().count() as i32);
|
||||
|
||||
let target_string = if m._has_vars {
|
||||
let mut output_map = HashMap::new();
|
||||
|
|
|
@ -52,7 +52,7 @@ impl From<i32> for ActionType {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum KeyEvent {
|
||||
Char(char),
|
||||
Char(String),
|
||||
Modifier(KeyModifier)
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ pub trait MatchReceiver {
|
|||
}
|
||||
|
||||
pub trait Matcher : KeyEventReceiver {
|
||||
fn handle_char(&self, c: char);
|
||||
fn handle_char(&self, c: &str);
|
||||
fn handle_modifier(&self, m: KeyModifier);
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ impl <M: Matcher> KeyEventReceiver for M {
|
|||
fn on_key_event(&self, e: KeyEvent) {
|
||||
match e {
|
||||
KeyEvent::Char(c) => {
|
||||
self.handle_char(c);
|
||||
self.handle_char(&c);
|
||||
},
|
||||
KeyEvent::Modifier(m) => {
|
||||
self.handle_modifier(m);
|
||||
|
|
|
@ -35,6 +35,7 @@ pub struct ScrollingMatcher<'a, R: MatchReceiver, M: ConfigManager<'a>> {
|
|||
|
||||
struct MatchEntry<'a> {
|
||||
start: usize,
|
||||
count: usize,
|
||||
_match: &'a Match
|
||||
}
|
||||
|
||||
|
@ -68,7 +69,7 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ScrollingMatcher<'a, R, M> {
|
|||
}
|
||||
|
||||
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMatcher<'a, R, M> {
|
||||
fn handle_char(&self, c: char) {
|
||||
fn handle_char(&self, c: &str) {
|
||||
// if not enabled, avoid any processing
|
||||
if !*(self.is_enabled.borrow()) {
|
||||
return;
|
||||
|
@ -77,8 +78,12 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa
|
|||
let mut current_set_queue = self.current_set_queue.borrow_mut();
|
||||
|
||||
let new_matches: Vec<MatchEntry> = self.config_manager.matches().iter()
|
||||
.filter(|&x| x.trigger.chars().nth(0).unwrap() == c)
|
||||
.map(|x | MatchEntry{start: 1, _match: &x})
|
||||
.filter(|&x| x.trigger.starts_with(c))
|
||||
.map(|x | MatchEntry{
|
||||
start: 1,
|
||||
count: x.trigger.chars().count(),
|
||||
_match: &x
|
||||
})
|
||||
.collect();
|
||||
// TODO: use an associative structure to improve the efficiency of this first "new_matches" lookup.
|
||||
|
||||
|
@ -86,9 +91,18 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa
|
|||
Some(last_matches) => {
|
||||
let mut updated: Vec<MatchEntry> = last_matches.iter()
|
||||
.filter(|&x| {
|
||||
x._match.trigger[x.start..].chars().nth(0).unwrap() == c
|
||||
let nchar = x._match.trigger.chars().nth(x.start);
|
||||
if let Some(nchar) = nchar {
|
||||
c.starts_with(nchar)
|
||||
}else{
|
||||
false
|
||||
}
|
||||
})
|
||||
.map(|x | MatchEntry{
|
||||
start: x.start+1,
|
||||
count: x.count,
|
||||
_match: &x._match
|
||||
})
|
||||
.map(|x | MatchEntry{start: x.start+1, _match: &x._match})
|
||||
.collect();
|
||||
|
||||
updated.extend(new_matches);
|
||||
|
@ -100,7 +114,7 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa
|
|||
let mut found_match = None;
|
||||
|
||||
for entry in combined_matches.iter() {
|
||||
if entry.start == entry._match.trigger.len() {
|
||||
if entry.start == entry.count {
|
||||
found_match = Some(entry._match);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user