diff --git a/espanso/src/cli/worker/engine/matcher/convert.rs b/espanso/src/cli/worker/engine/matcher/convert.rs index 3422ff2..61039b2 100644 --- a/espanso/src/cli/worker/engine/matcher/convert.rs +++ b/espanso/src/cli/worker/engine/matcher/convert.rs @@ -24,7 +24,10 @@ use espanso_config::{ MatchCause, }, }; -use espanso_match::rolling::{RollingMatch, StringMatchOptions}; +use espanso_match::{ + regex::RegexMatch, + rolling::{RollingMatch, StringMatchOptions}, +}; use std::iter::FromIterator; pub struct MatchConverter<'a> { @@ -52,9 +55,9 @@ impl<'a> MatchConverter<'a> { m.id, &trigger, &StringMatchOptions { - case_insensitive: cause.propagate_case, + case_insensitive: cause.propagate_case, left_word: cause.left_word, - right_word: cause.right_word, + right_word: cause.right_word, }, )) } @@ -64,6 +67,23 @@ impl<'a> MatchConverter<'a> { matches } + // TODO: test (might need to move the conversion logic into a separate function) + pub fn get_regex_matches(&self) -> Vec> { + 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 { let paths = self.config_store.get_all_match_paths(); self.match_store.query(&Vec::from_iter(paths.into_iter())) diff --git a/espanso/src/cli/worker/engine/matcher/mod.rs b/espanso/src/cli/worker/engine/matcher/mod.rs index ac109b6..bc38fae 100644 --- a/espanso/src/cli/worker/engine/matcher/mod.rs +++ b/espanso/src/cli/worker/engine/matcher/mod.rs @@ -1,5 +1,3 @@ -use espanso_match::rolling::matcher::RollingMatcherState; - /* * This file is part of espanso. * @@ -19,13 +17,92 @@ use espanso_match::rolling::matcher::RollingMatcherState; * along with espanso. If not, see . */ +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; pub mod rolling; +pub mod regex; pub mod convert; #[derive(Clone, EnumAsInner)] pub enum MatcherState<'a> { Rolling(RollingMatcherState<'a, i32>), - // TODO: regex -} \ No newline at end of file + 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> for MatchResult { + fn from(result: espanso_match::MatchResult) -> Self { + Self { + id: result.id, + trigger: result.trigger, + left_separator: result.left_separator, + right_separator: result.right_separator, + args: result.vars, + } + } +} + +impl From 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, + } + } +} diff --git a/espanso/src/cli/worker/engine/matcher/regex.rs b/espanso/src/cli/worker/engine/matcher/regex.rs new file mode 100644 index 0000000..15263c7 --- /dev/null +++ b/espanso/src/cli/worker/engine/matcher/regex.rs @@ -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 . + */ + +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, +} + +impl RegexMatcherAdapter { + pub fn new(matches: &[RegexMatch], 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) { + 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 = results.into_iter().map(|result| result.into()).collect(); + + (enum_state, results) + } +} diff --git a/espanso/src/cli/worker/engine/matcher/rolling.rs b/espanso/src/cli/worker/engine/matcher/rolling.rs index 3dca1b2..af6404e 100644 --- a/espanso/src/cli/worker/engine/matcher/rolling.rs +++ b/espanso/src/cli/worker/engine/matcher/rolling.rs @@ -23,7 +23,6 @@ use espanso_match::rolling::{ }; use crate::engine::{ - event::input::Key, process::{MatchResult, Matcher, MatcherEvent}, }; @@ -83,74 +82,3 @@ impl<'a> Matcher<'a, MatcherState<'a>> for RollingMatcherAdapter { (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> for MatchResult { - fn from(result: espanso_match::MatchResult) -> Self { - Self { - id: result.id, - trigger: result.trigger, - left_separator: result.left_separator, - right_separator: result.right_separator, - args: result.vars, - } - } -} - -impl From 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, - } - } -} diff --git a/espanso/src/cli/worker/engine/mod.rs b/espanso/src/cli/worker/engine/mod.rs index 2c59bd7..edf0cef 100644 --- a/espanso/src/cli/worker/engine/mod.rs +++ b/espanso/src/cli/worker/engine/mod.rs @@ -22,7 +22,7 @@ use espanso_config::{config::ConfigStore, matches::store::MatchStore}; use espanso_path::Paths; 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; @@ -61,12 +61,18 @@ pub fn initialize_and_spawn( let sources: Vec<&dyn crate::engine::funnel::Source> = vec![&detect_source]; 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(), ); + 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< &dyn crate::engine::process::Matcher, - > = vec![&matcher]; + > = vec![&rolling_matcher, ®ex_matcher]; let selector = MatchSelectorAdapter::new(); let multiplexer = super::engine::multiplex::MultiplexAdapter::new(&match_cache); diff --git a/espanso/src/cli/worker/engine/render/mod.rs b/espanso/src/cli/worker/engine/render/mod.rs index f2a48a5..86b8b03 100644 --- a/espanso/src/cli/worker/engine/render/mod.rs +++ b/espanso/src/cli/worker/engine/render/mod.rs @@ -218,7 +218,7 @@ impl<'a> Renderer<'a> for RendererAdapter<'a> { for (name, value) in trigger_vars { let mut params = espanso_render::Params::new(); params.insert("echo".to_string(), Value::String(value)); - augmented.vars.push(Variable { + augmented.vars.insert(0, Variable { name, var_type: "echo".to_string(), params,