feat(core): wire up regex matcher

This commit is contained in:
Federico Terzi 2021-05-06 21:22:03 +02:00
parent 745c329580
commit 248b62a6a2
6 changed files with 181 additions and 83 deletions

View File

@ -24,7 +24,10 @@ use espanso_config::{
MatchCause, MatchCause,
}, },
}; };
use espanso_match::rolling::{RollingMatch, StringMatchOptions}; use espanso_match::{
regex::RegexMatch,
rolling::{RollingMatch, StringMatchOptions},
};
use std::iter::FromIterator; use std::iter::FromIterator;
pub struct MatchConverter<'a> { pub struct MatchConverter<'a> {
@ -64,6 +67,23 @@ impl<'a> MatchConverter<'a> {
matches matches
} }
// TODO: test (might need to move the conversion logic into a separate function)
pub fn get_regex_matches(&self) -> Vec<RegexMatch<i32>> {
let match_set = self.global_match_set();
let mut matches = Vec::new();
for m in match_set.matches {
if let MatchCause::Regex(cause) = &m.cause {
matches.push(RegexMatch::new(
m.id,
&cause.regex,
))
}
}
matches
}
fn global_match_set(&self) -> MatchSet { fn global_match_set(&self) -> MatchSet {
let paths = self.config_store.get_all_match_paths(); let paths = self.config_store.get_all_match_paths();
self.match_store.query(&Vec::from_iter(paths.into_iter())) self.match_store.query(&Vec::from_iter(paths.into_iter()))

View File

@ -1,5 +1,3 @@
use espanso_match::rolling::matcher::RollingMatcherState;
/* /*
* This file is part of espanso. * This file is part of espanso.
* *
@ -19,13 +17,92 @@ use espanso_match::rolling::matcher::RollingMatcherState;
* along with espanso. If not, see <https://www.gnu.org/licenses/>. * along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/ */
use espanso_match::rolling::matcher::RollingMatcherState;
use espanso_match::regex::RegexMatcherState;
use crate::engine::{
event::input::Key,
process::{MatchResult, MatcherEvent},
};
use enum_as_inner::EnumAsInner; use enum_as_inner::EnumAsInner;
pub mod rolling; pub mod rolling;
pub mod regex;
pub mod convert; pub mod convert;
#[derive(Clone, EnumAsInner)] #[derive(Clone, EnumAsInner)]
pub enum MatcherState<'a> { pub enum MatcherState<'a> {
Rolling(RollingMatcherState<'a, i32>), Rolling(RollingMatcherState<'a, i32>),
// TODO: regex Regex(RegexMatcherState),
}
impl From<&MatcherEvent> for espanso_match::event::Event {
fn from(event: &MatcherEvent) -> Self {
match event {
MatcherEvent::Key { key, chars } => espanso_match::event::Event::Key {
key: key.clone().into(),
chars: chars.to_owned(),
},
MatcherEvent::VirtualSeparator => espanso_match::event::Event::VirtualSeparator,
}
}
}
impl From<espanso_match::MatchResult<i32>> for MatchResult {
fn from(result: espanso_match::MatchResult<i32>) -> Self {
Self {
id: result.id,
trigger: result.trigger,
left_separator: result.left_separator,
right_separator: result.right_separator,
args: result.vars,
}
}
}
impl From<Key> for espanso_match::event::Key {
fn from(key: Key) -> Self {
match key {
Key::Alt => espanso_match::event::Key::Alt,
Key::CapsLock => espanso_match::event::Key::CapsLock,
Key::Control => espanso_match::event::Key::Control,
Key::Meta => espanso_match::event::Key::Meta,
Key::NumLock => espanso_match::event::Key::NumLock,
Key::Shift => espanso_match::event::Key::Shift,
Key::Enter => espanso_match::event::Key::Enter,
Key::Tab => espanso_match::event::Key::Tab,
Key::Space => espanso_match::event::Key::Space,
Key::ArrowDown => espanso_match::event::Key::ArrowDown,
Key::ArrowLeft => espanso_match::event::Key::ArrowLeft,
Key::ArrowRight => espanso_match::event::Key::ArrowRight,
Key::ArrowUp => espanso_match::event::Key::ArrowUp,
Key::End => espanso_match::event::Key::End,
Key::Home => espanso_match::event::Key::Home,
Key::PageDown => espanso_match::event::Key::PageDown,
Key::PageUp => espanso_match::event::Key::PageUp,
Key::Escape => espanso_match::event::Key::Escape,
Key::Backspace => espanso_match::event::Key::Backspace,
Key::F1 => espanso_match::event::Key::F1,
Key::F2 => espanso_match::event::Key::F2,
Key::F3 => espanso_match::event::Key::F3,
Key::F4 => espanso_match::event::Key::F4,
Key::F5 => espanso_match::event::Key::F5,
Key::F6 => espanso_match::event::Key::F6,
Key::F7 => espanso_match::event::Key::F7,
Key::F8 => espanso_match::event::Key::F8,
Key::F9 => espanso_match::event::Key::F9,
Key::F10 => espanso_match::event::Key::F10,
Key::F11 => espanso_match::event::Key::F11,
Key::F12 => espanso_match::event::Key::F12,
Key::F13 => espanso_match::event::Key::F13,
Key::F14 => espanso_match::event::Key::F14,
Key::F15 => espanso_match::event::Key::F15,
Key::F16 => espanso_match::event::Key::F16,
Key::F17 => espanso_match::event::Key::F17,
Key::F18 => espanso_match::event::Key::F18,
Key::F19 => espanso_match::event::Key::F19,
Key::F20 => espanso_match::event::Key::F20,
Key::Other(_) => espanso_match::event::Key::Other,
}
}
} }

View File

@ -0,0 +1,67 @@
/*
* 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 crate::engine::process::{MatchResult, Matcher, MatcherEvent};
use espanso_match::regex::{RegexMatch, RegexMatcher, RegexMatcherOptions};
use super::MatcherState;
pub struct RegexMatcherAdapterOptions {
pub max_buffer_size: usize,
}
pub struct RegexMatcherAdapter {
matcher: RegexMatcher<i32>,
}
impl RegexMatcherAdapter {
pub fn new(matches: &[RegexMatch<i32>], options: &RegexMatcherAdapterOptions) -> Self {
let matcher = RegexMatcher::new(matches, RegexMatcherOptions {
max_buffer_size: options.max_buffer_size,
});
Self { matcher }
}
}
impl<'a> Matcher<'a, MatcherState<'a>> for RegexMatcherAdapter {
fn process(
&'a self,
prev_state: Option<&MatcherState<'a>>,
event: &MatcherEvent,
) -> (MatcherState<'a>, Vec<MatchResult>) {
use espanso_match::Matcher;
let prev_state = prev_state.map(|state| {
if let Some(state) = state.as_regex() {
state
} else {
panic!("invalid state type received in RegexMatcherAdapter")
}
});
let event = event.into();
let (state, results) = self.matcher.process(prev_state, event);
let enum_state = MatcherState::Regex(state);
let results: Vec<MatchResult> = results.into_iter().map(|result| result.into()).collect();
(enum_state, results)
}
}

View File

@ -23,7 +23,6 @@ use espanso_match::rolling::{
}; };
use crate::engine::{ use crate::engine::{
event::input::Key,
process::{MatchResult, Matcher, MatcherEvent}, process::{MatchResult, Matcher, MatcherEvent},
}; };
@ -83,74 +82,3 @@ impl<'a> Matcher<'a, MatcherState<'a>> for RollingMatcherAdapter {
(enum_state, results) (enum_state, results)
} }
} }
impl From<&MatcherEvent> for espanso_match::event::Event {
fn from(event: &MatcherEvent) -> Self {
match event {
MatcherEvent::Key { key, chars } => espanso_match::event::Event::Key {
key: key.clone().into(),
chars: chars.to_owned(),
},
MatcherEvent::VirtualSeparator => espanso_match::event::Event::VirtualSeparator,
}
}
}
impl From<espanso_match::MatchResult<i32>> for MatchResult {
fn from(result: espanso_match::MatchResult<i32>) -> Self {
Self {
id: result.id,
trigger: result.trigger,
left_separator: result.left_separator,
right_separator: result.right_separator,
args: result.vars,
}
}
}
impl From<Key> for espanso_match::event::Key {
fn from(key: Key) -> Self {
match key {
Key::Alt => espanso_match::event::Key::Alt,
Key::CapsLock => espanso_match::event::Key::CapsLock,
Key::Control => espanso_match::event::Key::Control,
Key::Meta => espanso_match::event::Key::Meta,
Key::NumLock => espanso_match::event::Key::NumLock,
Key::Shift => espanso_match::event::Key::Shift,
Key::Enter => espanso_match::event::Key::Enter,
Key::Tab => espanso_match::event::Key::Tab,
Key::Space => espanso_match::event::Key::Space,
Key::ArrowDown => espanso_match::event::Key::ArrowDown,
Key::ArrowLeft => espanso_match::event::Key::ArrowLeft,
Key::ArrowRight => espanso_match::event::Key::ArrowRight,
Key::ArrowUp => espanso_match::event::Key::ArrowUp,
Key::End => espanso_match::event::Key::End,
Key::Home => espanso_match::event::Key::Home,
Key::PageDown => espanso_match::event::Key::PageDown,
Key::PageUp => espanso_match::event::Key::PageUp,
Key::Escape => espanso_match::event::Key::Escape,
Key::Backspace => espanso_match::event::Key::Backspace,
Key::F1 => espanso_match::event::Key::F1,
Key::F2 => espanso_match::event::Key::F2,
Key::F3 => espanso_match::event::Key::F3,
Key::F4 => espanso_match::event::Key::F4,
Key::F5 => espanso_match::event::Key::F5,
Key::F6 => espanso_match::event::Key::F6,
Key::F7 => espanso_match::event::Key::F7,
Key::F8 => espanso_match::event::Key::F8,
Key::F9 => espanso_match::event::Key::F9,
Key::F10 => espanso_match::event::Key::F10,
Key::F11 => espanso_match::event::Key::F11,
Key::F12 => espanso_match::event::Key::F12,
Key::F13 => espanso_match::event::Key::F13,
Key::F14 => espanso_match::event::Key::F14,
Key::F15 => espanso_match::event::Key::F15,
Key::F16 => espanso_match::event::Key::F16,
Key::F17 => espanso_match::event::Key::F17,
Key::F18 => espanso_match::event::Key::F18,
Key::F19 => espanso_match::event::Key::F19,
Key::F20 => espanso_match::event::Key::F20,
Key::Other(_) => espanso_match::event::Key::Other,
}
}
}

View File

@ -22,7 +22,7 @@ use espanso_config::{config::ConfigStore, matches::store::MatchStore};
use espanso_path::Paths; use espanso_path::Paths;
use ui::selector::MatchSelectorAdapter; use ui::selector::MatchSelectorAdapter;
use crate::cli::worker::engine::path::PathProviderAdapter; use crate::cli::worker::engine::{matcher::regex::RegexMatcherAdapterOptions, path::PathProviderAdapter};
use super::ui::icon::IconPaths; use super::ui::icon::IconPaths;
@ -61,12 +61,18 @@ pub fn initialize_and_spawn(
let sources: Vec<&dyn crate::engine::funnel::Source> = vec![&detect_source]; let sources: Vec<&dyn crate::engine::funnel::Source> = vec![&detect_source];
let funnel = crate::engine::funnel::default(&sources); let funnel = crate::engine::funnel::default(&sources);
let matcher = super::engine::matcher::rolling::RollingMatcherAdapter::new( let rolling_matcher = super::engine::matcher::rolling::RollingMatcherAdapter::new(
&match_converter.get_rolling_matches(), &match_converter.get_rolling_matches(),
); );
let regex_matcher = super::engine::matcher::regex::RegexMatcherAdapter::new(
&match_converter.get_regex_matches(),
&RegexMatcherAdapterOptions {
max_buffer_size: 30, // TODO: load from configs
}
);
let matchers: Vec< let matchers: Vec<
&dyn crate::engine::process::Matcher<super::engine::matcher::MatcherState>, &dyn crate::engine::process::Matcher<super::engine::matcher::MatcherState>,
> = vec![&matcher]; > = vec![&rolling_matcher, &regex_matcher];
let selector = MatchSelectorAdapter::new(); let selector = MatchSelectorAdapter::new();
let multiplexer = super::engine::multiplex::MultiplexAdapter::new(&match_cache); let multiplexer = super::engine::multiplex::MultiplexAdapter::new(&match_cache);

View File

@ -218,7 +218,7 @@ impl<'a> Renderer<'a> for RendererAdapter<'a> {
for (name, value) in trigger_vars { for (name, value) in trigger_vars {
let mut params = espanso_render::Params::new(); let mut params = espanso_render::Params::new();
params.insert("echo".to_string(), Value::String(value)); params.insert("echo".to_string(), Value::String(value));
augmented.vars.push(Variable { augmented.vars.insert(0, Variable {
name, name,
var_type: "echo".to_string(), var_type: "echo".to_string(),
params, params,