Early draft of RollingMatcher

This commit is contained in:
Federico Terzi 2021-03-09 21:43:07 +01:00
parent e8881d0faf
commit 1103278ccd
10 changed files with 377 additions and 0 deletions

28
Cargo.lock generated
View File

@ -227,6 +227,7 @@ dependencies = [
"espanso-config", "espanso-config",
"espanso-detect", "espanso-detect",
"espanso-inject", "espanso-inject",
"espanso-match",
"espanso-ui", "espanso-ui",
"maplit", "maplit",
"simplelog", "simplelog",
@ -295,6 +296,18 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "espanso-match"
version = "0.1.0"
dependencies = [
"anyhow",
"lazy_static",
"log",
"regex",
"thiserror",
"unicase",
]
[[package]] [[package]]
name = "espanso-ui" name = "espanso-ui"
version = "0.1.0" version = "0.1.0"
@ -810,6 +823,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.7.1" version = "1.7.1"
@ -828,6 +850,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.9.0+wasi-snapshot-preview1" version = "0.9.0+wasi-snapshot-preview1"

View File

@ -7,4 +7,5 @@ members = [
"espanso-inject", "espanso-inject",
"espanso-ipc", "espanso-ipc",
"espanso-config", "espanso-config",
"espanso-match",
] ]

13
espanso-match/Cargo.toml Normal file
View File

@ -0,0 +1,13 @@
[package]
name = "espanso-match"
version = "0.1.0"
authors = ["Federico Terzi <federico-terzi@users.noreply.github.com>"]
edition = "2018"
[dependencies]
log = "0.4.14"
anyhow = "1.0.38"
thiserror = "1.0.23"
regex = "1.4.3"
lazy_static = "1.4.0"
unicase = "2.6.0"

View File

@ -0,0 +1,84 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
#[derive(Debug, PartialEq)]
pub enum Event {
Key {
key: Key,
char: Option<String>
},
VirtualSeparator,
}
#[derive(Debug, PartialEq)]
pub enum Key {
// Modifiers
Alt,
CapsLock,
Control,
Meta,
NumLock,
Shift,
// Whitespace
Enter,
Tab,
Space,
// Navigation
ArrowDown,
ArrowLeft,
ArrowRight,
ArrowUp,
End,
Home,
PageDown,
PageUp,
// UI
Escape,
// Editing keys
Backspace,
// Function keys
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
// Others
Other,
}

31
espanso-match/src/lib.rs Normal file
View File

@ -0,0 +1,31 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
use std::any::Any;
#[macro_use]
extern crate lazy_static;
pub mod event;
pub mod rolling;
pub trait Matcher {
// TODO: create suitable event type
fn process(&self, prev_state: Option<&dyn Any>, event: Option<bool>) -> (Box<dyn Any>, Vec<i32>);
}

View File

@ -0,0 +1,28 @@
use crate::event::Key;
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
pub enum RollingItem {
WordSeparator,
Key(Key),
Char(String),
CharInsensitive(String),
}

View File

@ -0,0 +1,110 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
use unicase::UniCase;
use crate::event::{Event, Key};
use super::tree::{MatcherTreeNode, MatcherTreeRef};
pub struct RollingMatcher {
char_word_separators: Vec<String>,
key_word_separators: Vec<Key>,
root: MatcherTreeNode,
}
// impl Matcher for RollingMatcher {
// fn process(
// &self,
// prev_state: &dyn std::any::Any,
// event: Option<bool>,
// ) -> (Box<dyn std::any::Any>, Vec<i32>) {
// todo!()
// }
// }
impl RollingMatcher {
// TODO: to find the matches, we first call the `find_refs` to get the list of matching nodes
// then we scan them and if any of those references is of variant `Matches`, then we return those
// match ids, otherwise None
// TODO: test
fn find_refs<'a>(&'a self, node: &'a MatcherTreeNode, event: &Event) -> Vec<&'a MatcherTreeRef> {
let mut refs = Vec::new();
if let Event::Key { key, char } = event {
// Key matching
if let Some((_, node_ref)) = node.keys.iter().find(|(_key, _)| _key == key) {
refs.push(node_ref);
}
if let Some(char) = char {
// Char matching
if let Some((_, node_ref)) = node.chars.iter().find(|(_char, _)| _char == char) {
refs.push(node_ref);
}
// Char case-insensitive
let insensitive_char = UniCase::new(char);
if let Some((_, node_ref)) = node
.chars_insensitive
.iter()
.find(|(_char, _)| *_char == insensitive_char)
{
refs.push(node_ref);
}
}
}
if self.is_word_separator(event) {
if let Some(node_ref) = node.word_separators.as_ref() {
refs.push(node_ref)
}
}
refs
}
fn is_word_separator(&self, event: &Event) -> bool {
match event {
Event::Key { key, char } => {
if self.key_word_separators.contains(&key) {
true
} else if let Some(char) = char {
self.char_word_separators.contains(&char)
} else {
false
}
}
Event::VirtualSeparator => true,
_ => false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
use self::item::RollingItem;
mod item;
mod tree;
mod matcher;
pub struct RollingMatch {
id: i32,
items: Vec<RollingItem>,
}
impl RollingMatch {
pub fn new(id: i32, items: Vec<RollingItem>) -> Self {
Self { id, items }
}
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
use unicase::UniCase;
use crate::event::Key;
use super::item::RollingItem;
#[derive(Debug)]
pub(crate) enum MatcherTreeRef {
Matches(Vec<i32>),
Node(Box<MatcherTreeNode>),
}
#[derive(Debug)]
pub(crate) struct MatcherTreeNode {
pub word_separators: Option<MatcherTreeRef>,
pub keys: Vec<(Key, MatcherTreeRef)>,
pub chars: Vec<(String, MatcherTreeRef)>,
pub chars_insensitive: Vec<(UniCase<String>, MatcherTreeRef)>,
}
impl MatcherTreeNode {
// TODO: test
pub fn from_items(items: &[RollingItem]) -> MatcherTreeNode {
todo!()
}
}

View File

@ -18,5 +18,6 @@ espanso-detect = { path = "../espanso-detect" }
espanso-ui = { path = "../espanso-ui" } espanso-ui = { path = "../espanso-ui" }
espanso-inject = { path = "../espanso-inject" } espanso-inject = { path = "../espanso-inject" }
espanso-config = { path = "../espanso-config" } espanso-config = { path = "../espanso-config" }
espanso-match = { path = "../espanso-match" }
maplit = "1.0.2" maplit = "1.0.2"
simplelog = "0.9.0" simplelog = "0.9.0"