diff --git a/Cargo.lock b/Cargo.lock index 33aec5e..fb1f94f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -522,6 +522,7 @@ dependencies = [ "espanso-clipboard", "espanso-config", "espanso-detect", + "espanso-engine", "espanso-info", "espanso-inject", "espanso-ipc", @@ -535,13 +536,11 @@ dependencies = [ "espanso-ui", "fs2", "fs_extra", - "html2text", "lazy_static", "libc", "log", "log-panics", "maplit", - "markdown", "named_pipe", "notify", "opener", @@ -611,6 +610,19 @@ dependencies = [ "widestring", ] +[[package]] +name = "espanso-engine" +version = "0.1.0" +dependencies = [ + "anyhow", + "crossbeam", + "html2text", + "log", + "markdown", + "tempdir", + "thiserror", +] + [[package]] name = "espanso-info" version = "0.1.0" @@ -1873,9 +1885,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" +checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" [[package]] name = "slab" diff --git a/Cargo.toml b/Cargo.toml index 426c234..2aa228b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,5 @@ members = [ "espanso-migrate", "espanso-mac-utils", "espanso-kvs", + "espanso-engine", ] \ No newline at end of file diff --git a/espanso/Cargo.toml b/espanso/Cargo.toml index 993cbe3..361a332 100644 --- a/espanso/Cargo.toml +++ b/espanso/Cargo.toml @@ -33,6 +33,7 @@ espanso-ipc = { path = "../espanso-ipc" } espanso-modulo = { path = "../espanso-modulo", optional = true } espanso-migrate = { path = "../espanso-migrate" } espanso-kvs = { path = "../espanso-kvs" } +espanso-engine = { path = "../espanso-engine" } maplit = "1.0.2" simplelog = "0.9.0" log = "0.4.14" @@ -45,8 +46,6 @@ enum-as-inner = "0.3.3" dirs = "3.0.1" serde = { version = "1.0.123", features = ["derive"] } serde_json = "1.0.62" -markdown = "0.3.0" -html2text = "0.2.1" log-panics = "2.0.0" fs2 = "0.4.3" serde_yaml = "0.8.17" diff --git a/espanso/src/cli/worker/builtin/debug.rs b/espanso/src/cli/worker/builtin/debug.rs index 4d43e65..6ab41df 100644 --- a/espanso/src/cli/worker/builtin/debug.rs +++ b/espanso/src/cli/worker/builtin/debug.rs @@ -17,10 +17,9 @@ * along with espanso. If not, see . */ -use crate::{ - cli::worker::builtin::generate_next_builtin_id, - engine::event::{effect::TextInjectRequest, EventType}, -}; +use espanso_engine::event::{effect::TextInjectRequest, EventType}; + +use crate::cli::worker::builtin::generate_next_builtin_id; use super::BuiltInMatch; diff --git a/espanso/src/cli/worker/builtin/mod.rs b/espanso/src/cli/worker/builtin/mod.rs index a27b457..7723a3b 100644 --- a/espanso/src/cli/worker/builtin/mod.rs +++ b/espanso/src/cli/worker/builtin/mod.rs @@ -21,7 +21,7 @@ use std::cell::Cell; use espanso_config::config::Config; -use crate::engine::event::EventType; +use espanso_engine::event::EventType; use super::context::Context; diff --git a/espanso/src/cli/worker/builtin/search.rs b/espanso/src/cli/worker/builtin/search.rs index 8443bce..d482101 100644 --- a/espanso/src/cli/worker/builtin/search.rs +++ b/espanso/src/cli/worker/builtin/search.rs @@ -17,19 +17,22 @@ * along with espanso. If not, see . */ -use crate::{cli::worker::builtin::generate_next_builtin_id, engine::event::{EventType}}; +use espanso_engine::event::EventType; + +use crate::cli::worker::builtin::generate_next_builtin_id; use super::BuiltInMatch; -pub fn create_match_trigger_search_bar(trigger: Option, hotkey: Option) -> BuiltInMatch { +pub fn create_match_trigger_search_bar( + trigger: Option, + hotkey: Option, +) -> BuiltInMatch { BuiltInMatch { id: generate_next_builtin_id(), label: "Open search bar", triggers: trigger.map(|trigger| vec![trigger]).unwrap_or_default(), hotkey, - action: |_| { - EventType::ShowSearchBar - }, + action: |_| EventType::ShowSearchBar, ..Default::default() } } diff --git a/espanso/src/cli/worker/config.rs b/espanso/src/cli/worker/config.rs index e9ea90d..c2cd4f9 100644 --- a/espanso/src/cli/worker/config.rs +++ b/espanso/src/cli/worker/config.rs @@ -73,7 +73,7 @@ fn to_app_properties(info: &AppInfo) -> AppProperties { } } -impl<'a> crate::engine::process::MatchFilter for ConfigManager<'a> { +impl<'a> espanso_engine::process::MatchFilter for ConfigManager<'a> { fn filter_active(&self, matches_ids: &[i32]) -> Vec { let ids_set: HashSet = HashSet::from_iter(matches_ids.iter().copied()); let (_, match_set) = self.active_context(); @@ -115,13 +115,13 @@ impl<'a> super::engine::process::middleware::render::ConfigProvider<'a> for Conf } } -impl<'a> crate::engine::dispatch::ModeProvider for ConfigManager<'a> { - fn active_mode(&self) -> crate::engine::dispatch::Mode { +impl<'a> espanso_engine::dispatch::ModeProvider for ConfigManager<'a> { + fn active_mode(&self) -> espanso_engine::dispatch::Mode { let config = self.active(); match config.backend() { - espanso_config::config::Backend::Inject => crate::engine::dispatch::Mode::Event, - espanso_config::config::Backend::Clipboard => crate::engine::dispatch::Mode::Clipboard, - espanso_config::config::Backend::Auto => crate::engine::dispatch::Mode::Auto { + espanso_config::config::Backend::Inject => espanso_engine::dispatch::Mode::Event, + espanso_config::config::Backend::Clipboard => espanso_engine::dispatch::Mode::Clipboard, + espanso_config::config::Backend::Auto => espanso_engine::dispatch::Mode::Auto { clipboard_threshold: config.clipboard_threshold(), }, } @@ -155,7 +155,7 @@ impl<'a> super::engine::dispatch::executor::InjectParamsProvider for ConfigManag } } -impl<'a> crate::engine::process::MatcherMiddlewareConfigProvider for ConfigManager<'a> { +impl<'a> espanso_engine::process::MatcherMiddlewareConfigProvider for ConfigManager<'a> { fn max_history_size(&self) -> usize { self.default().backspace_limit() } diff --git a/espanso/src/cli/worker/daemon_monitor.rs b/espanso/src/cli/worker/daemon_monitor.rs index 8e1d4a3..8302874 100644 --- a/espanso/src/cli/worker/daemon_monitor.rs +++ b/espanso/src/cli/worker/daemon_monitor.rs @@ -17,13 +17,14 @@ * along with espanso. If not, see . */ -use std::{path::Path}; +use std::path::Path; use anyhow::Result; use crossbeam::channel::Sender; +use espanso_engine::event::ExitMode; use log::{error, info, warn}; -use crate::{engine::event::ExitMode, lock::acquire_daemon_lock}; +use crate::lock::acquire_daemon_lock; const DAEMON_STATUS_CHECK_INTERVAL: u64 = 1000; @@ -40,7 +41,7 @@ pub fn initialize_and_spawn(runtime_dir: &Path, exit_notify: Sender) - fn daemon_monitor_main(runtime_dir: &Path, exit_notify: Sender) { info!("monitoring the status of the daemon process"); - + loop { let is_daemon_lock_free = { let lock = acquire_daemon_lock(runtime_dir); @@ -55,6 +56,8 @@ fn daemon_monitor_main(runtime_dir: &Path, exit_notify: Sender) { break; } - std::thread::sleep(std::time::Duration::from_millis(DAEMON_STATUS_CHECK_INTERVAL)); + std::thread::sleep(std::time::Duration::from_millis( + DAEMON_STATUS_CHECK_INTERVAL, + )); } } diff --git a/espanso/src/cli/worker/engine/dispatch/executor/clipboard_injector.rs b/espanso/src/cli/worker/engine/dispatch/executor/clipboard_injector.rs index 3237d13..d226cdd 100644 --- a/espanso/src/cli/worker/engine/dispatch/executor/clipboard_injector.rs +++ b/espanso/src/cli/worker/engine/dispatch/executor/clipboard_injector.rs @@ -23,7 +23,7 @@ use espanso_clipboard::Clipboard; use espanso_inject::{keys::Key, InjectionOptions, Injector}; use log::error; -use crate::engine::{ +use espanso_engine::{ dispatch::HtmlInjector, dispatch::{ImageInjector, TextInjector}, }; diff --git a/espanso/src/cli/worker/engine/dispatch/executor/context_menu.rs b/espanso/src/cli/worker/engine/dispatch/executor/context_menu.rs index 55822b8..ba71ce8 100644 --- a/espanso/src/cli/worker/engine/dispatch/executor/context_menu.rs +++ b/espanso/src/cli/worker/engine/dispatch/executor/context_menu.rs @@ -19,7 +19,7 @@ use espanso_ui::UIRemote; -use crate::engine::dispatch::ContextMenuHandler; +use espanso_engine::dispatch::ContextMenuHandler; pub struct ContextMenuHandlerAdapter<'a> { remote: &'a dyn UIRemote, @@ -32,7 +32,7 @@ impl<'a> ContextMenuHandlerAdapter<'a> { } impl<'a> ContextMenuHandler for ContextMenuHandlerAdapter<'a> { - fn show_context_menu(&self, items: &[crate::engine::event::ui::MenuItem]) -> anyhow::Result<()> { + fn show_context_menu(&self, items: &[espanso_engine::event::ui::MenuItem]) -> anyhow::Result<()> { let ui_menu_items: Vec = items.iter().map(convert_to_ui_menu_item).collect(); let ui_menu = espanso_ui::menu::Menu { @@ -46,16 +46,16 @@ impl<'a> ContextMenuHandler for ContextMenuHandlerAdapter<'a> { } fn convert_to_ui_menu_item( - item: &crate::engine::event::ui::MenuItem, + item: &espanso_engine::event::ui::MenuItem, ) -> espanso_ui::menu::MenuItem { match item { - crate::engine::event::ui::MenuItem::Simple(simple) => { + espanso_engine::event::ui::MenuItem::Simple(simple) => { espanso_ui::menu::MenuItem::Simple(espanso_ui::menu::SimpleMenuItem { id: simple.id, label: simple.label.clone(), }) } - crate::engine::event::ui::MenuItem::Sub(sub) => { + espanso_engine::event::ui::MenuItem::Sub(sub) => { espanso_ui::menu::MenuItem::Sub(espanso_ui::menu::SubMenuItem { label: sub.label.clone(), items: sub @@ -65,6 +65,6 @@ fn convert_to_ui_menu_item( .collect(), }) } - crate::engine::event::ui::MenuItem::Separator => espanso_ui::menu::MenuItem::Separator, + espanso_engine::event::ui::MenuItem::Separator => espanso_ui::menu::MenuItem::Separator, } } diff --git a/espanso/src/cli/worker/engine/dispatch/executor/event_injector.rs b/espanso/src/cli/worker/engine/dispatch/executor/event_injector.rs index f1a83f3..36d8be9 100644 --- a/espanso/src/cli/worker/engine/dispatch/executor/event_injector.rs +++ b/espanso/src/cli/worker/engine/dispatch/executor/event_injector.rs @@ -21,7 +21,7 @@ use std::convert::TryInto; use espanso_inject::{InjectionOptions, Injector}; -use crate::engine::dispatch::TextInjector; +use espanso_engine::dispatch::TextInjector; use super::InjectParamsProvider; diff --git a/espanso/src/cli/worker/engine/dispatch/executor/icon.rs b/espanso/src/cli/worker/engine/dispatch/executor/icon.rs index aae1562..a0c6450 100644 --- a/espanso/src/cli/worker/engine/dispatch/executor/icon.rs +++ b/espanso/src/cli/worker/engine/dispatch/executor/icon.rs @@ -19,7 +19,7 @@ use espanso_ui::{UIRemote, icons::TrayIcon}; -use crate::engine::{dispatch::IconHandler, event::ui::IconStatus}; +use espanso_engine::{dispatch::IconHandler, event::ui::IconStatus}; pub struct IconHandlerAdapter<'a> { remote: &'a dyn UIRemote, diff --git a/espanso/src/cli/worker/engine/dispatch/executor/key_injector.rs b/espanso/src/cli/worker/engine/dispatch/executor/key_injector.rs index 571e4e3..08aad9d 100644 --- a/espanso/src/cli/worker/engine/dispatch/executor/key_injector.rs +++ b/espanso/src/cli/worker/engine/dispatch/executor/key_injector.rs @@ -20,7 +20,7 @@ use std::convert::TryInto; use espanso_inject::{InjectionOptions, Injector}; -use crate::engine::dispatch::KeyInjector; +use espanso_engine::dispatch::KeyInjector; use super::InjectParamsProvider; @@ -36,7 +36,7 @@ impl<'a> KeyInjectorAdapter<'a> { } impl<'a> KeyInjector for KeyInjectorAdapter<'a> { - fn inject_sequence(&self, keys: &[crate::engine::event::input::Key]) -> anyhow::Result<()> { + fn inject_sequence(&self, keys: &[espanso_engine::event::input::Key]) -> anyhow::Result<()> { let params = self.params_provider.get(); let injection_options = InjectionOptions { @@ -53,47 +53,47 @@ impl<'a> KeyInjector for KeyInjectorAdapter<'a> { } } -fn convert_to_inject_key(key: &crate::engine::event::input::Key) -> espanso_inject::keys::Key { +fn convert_to_inject_key(key: &espanso_engine::event::input::Key) -> espanso_inject::keys::Key { match key { - crate::engine::event::input::Key::Alt => espanso_inject::keys::Key::Alt, - crate::engine::event::input::Key::CapsLock => espanso_inject::keys::Key::CapsLock, - crate::engine::event::input::Key::Control => espanso_inject::keys::Key::Control, - crate::engine::event::input::Key::Meta => espanso_inject::keys::Key::Meta, - crate::engine::event::input::Key::NumLock => espanso_inject::keys::Key::NumLock, - crate::engine::event::input::Key::Shift => espanso_inject::keys::Key::Shift, - crate::engine::event::input::Key::Enter => espanso_inject::keys::Key::Enter, - crate::engine::event::input::Key::Tab => espanso_inject::keys::Key::Tab, - crate::engine::event::input::Key::Space => espanso_inject::keys::Key::Space, - crate::engine::event::input::Key::ArrowDown => espanso_inject::keys::Key::ArrowDown, - crate::engine::event::input::Key::ArrowLeft => espanso_inject::keys::Key::ArrowLeft, - crate::engine::event::input::Key::ArrowRight => espanso_inject::keys::Key::ArrowRight, - crate::engine::event::input::Key::ArrowUp => espanso_inject::keys::Key::ArrowUp, - crate::engine::event::input::Key::End => espanso_inject::keys::Key::End, - crate::engine::event::input::Key::Home => espanso_inject::keys::Key::Home, - crate::engine::event::input::Key::PageDown => espanso_inject::keys::Key::PageDown, - crate::engine::event::input::Key::PageUp => espanso_inject::keys::Key::PageUp, - crate::engine::event::input::Key::Escape => espanso_inject::keys::Key::Escape, - crate::engine::event::input::Key::Backspace => espanso_inject::keys::Key::Backspace, - crate::engine::event::input::Key::F1 => espanso_inject::keys::Key::F1, - crate::engine::event::input::Key::F2 => espanso_inject::keys::Key::F2, - crate::engine::event::input::Key::F3 => espanso_inject::keys::Key::F3, - crate::engine::event::input::Key::F4 => espanso_inject::keys::Key::F4, - crate::engine::event::input::Key::F5 => espanso_inject::keys::Key::F5, - crate::engine::event::input::Key::F6 => espanso_inject::keys::Key::F6, - crate::engine::event::input::Key::F7 => espanso_inject::keys::Key::F7, - crate::engine::event::input::Key::F8 => espanso_inject::keys::Key::F8, - crate::engine::event::input::Key::F9 => espanso_inject::keys::Key::F9, - crate::engine::event::input::Key::F10 => espanso_inject::keys::Key::F10, - crate::engine::event::input::Key::F11 => espanso_inject::keys::Key::F11, - crate::engine::event::input::Key::F12 => espanso_inject::keys::Key::F12, - crate::engine::event::input::Key::F13 => espanso_inject::keys::Key::F13, - crate::engine::event::input::Key::F14 => espanso_inject::keys::Key::F14, - crate::engine::event::input::Key::F15 => espanso_inject::keys::Key::F15, - crate::engine::event::input::Key::F16 => espanso_inject::keys::Key::F16, - crate::engine::event::input::Key::F17 => espanso_inject::keys::Key::F17, - crate::engine::event::input::Key::F18 => espanso_inject::keys::Key::F18, - crate::engine::event::input::Key::F19 => espanso_inject::keys::Key::F19, - crate::engine::event::input::Key::F20 => espanso_inject::keys::Key::F20, - crate::engine::event::input::Key::Other(raw) => espanso_inject::keys::Key::Raw(*raw), + espanso_engine::event::input::Key::Alt => espanso_inject::keys::Key::Alt, + espanso_engine::event::input::Key::CapsLock => espanso_inject::keys::Key::CapsLock, + espanso_engine::event::input::Key::Control => espanso_inject::keys::Key::Control, + espanso_engine::event::input::Key::Meta => espanso_inject::keys::Key::Meta, + espanso_engine::event::input::Key::NumLock => espanso_inject::keys::Key::NumLock, + espanso_engine::event::input::Key::Shift => espanso_inject::keys::Key::Shift, + espanso_engine::event::input::Key::Enter => espanso_inject::keys::Key::Enter, + espanso_engine::event::input::Key::Tab => espanso_inject::keys::Key::Tab, + espanso_engine::event::input::Key::Space => espanso_inject::keys::Key::Space, + espanso_engine::event::input::Key::ArrowDown => espanso_inject::keys::Key::ArrowDown, + espanso_engine::event::input::Key::ArrowLeft => espanso_inject::keys::Key::ArrowLeft, + espanso_engine::event::input::Key::ArrowRight => espanso_inject::keys::Key::ArrowRight, + espanso_engine::event::input::Key::ArrowUp => espanso_inject::keys::Key::ArrowUp, + espanso_engine::event::input::Key::End => espanso_inject::keys::Key::End, + espanso_engine::event::input::Key::Home => espanso_inject::keys::Key::Home, + espanso_engine::event::input::Key::PageDown => espanso_inject::keys::Key::PageDown, + espanso_engine::event::input::Key::PageUp => espanso_inject::keys::Key::PageUp, + espanso_engine::event::input::Key::Escape => espanso_inject::keys::Key::Escape, + espanso_engine::event::input::Key::Backspace => espanso_inject::keys::Key::Backspace, + espanso_engine::event::input::Key::F1 => espanso_inject::keys::Key::F1, + espanso_engine::event::input::Key::F2 => espanso_inject::keys::Key::F2, + espanso_engine::event::input::Key::F3 => espanso_inject::keys::Key::F3, + espanso_engine::event::input::Key::F4 => espanso_inject::keys::Key::F4, + espanso_engine::event::input::Key::F5 => espanso_inject::keys::Key::F5, + espanso_engine::event::input::Key::F6 => espanso_inject::keys::Key::F6, + espanso_engine::event::input::Key::F7 => espanso_inject::keys::Key::F7, + espanso_engine::event::input::Key::F8 => espanso_inject::keys::Key::F8, + espanso_engine::event::input::Key::F9 => espanso_inject::keys::Key::F9, + espanso_engine::event::input::Key::F10 => espanso_inject::keys::Key::F10, + espanso_engine::event::input::Key::F11 => espanso_inject::keys::Key::F11, + espanso_engine::event::input::Key::F12 => espanso_inject::keys::Key::F12, + espanso_engine::event::input::Key::F13 => espanso_inject::keys::Key::F13, + espanso_engine::event::input::Key::F14 => espanso_inject::keys::Key::F14, + espanso_engine::event::input::Key::F15 => espanso_inject::keys::Key::F15, + espanso_engine::event::input::Key::F16 => espanso_inject::keys::Key::F16, + espanso_engine::event::input::Key::F17 => espanso_inject::keys::Key::F17, + espanso_engine::event::input::Key::F18 => espanso_inject::keys::Key::F18, + espanso_engine::event::input::Key::F19 => espanso_inject::keys::Key::F19, + espanso_engine::event::input::Key::F20 => espanso_inject::keys::Key::F20, + espanso_engine::event::input::Key::Other(raw) => espanso_inject::keys::Key::Raw(*raw), } } diff --git a/espanso/src/cli/worker/engine/dispatch/executor/secure_input.rs b/espanso/src/cli/worker/engine/dispatch/executor/secure_input.rs index 8d393a9..40ae47c 100644 --- a/espanso/src/cli/worker/engine/dispatch/executor/secure_input.rs +++ b/espanso/src/cli/worker/engine/dispatch/executor/secure_input.rs @@ -21,7 +21,7 @@ use std::process::Stdio; use anyhow::{bail, Context}; use log::{error, info}; -use crate::engine::dispatch::SecureInputManager; +use espanso_engine::dispatch::SecureInputManager; pub struct SecureInputManagerAdapter {} diff --git a/espanso/src/cli/worker/engine/funnel/detect.rs b/espanso/src/cli/worker/engine/funnel/detect.rs index 035612e..3c7deba 100644 --- a/espanso/src/cli/worker/engine/funnel/detect.rs +++ b/espanso/src/cli/worker/engine/funnel/detect.rs @@ -18,9 +18,15 @@ */ use crossbeam::channel::{Receiver, Select, SelectedOperation}; -use espanso_detect::event::{InputEvent}; +use espanso_detect::event::InputEvent; -use crate::engine::{event::{Event, EventType, SourceId, input::{HotKeyEvent, Key, KeyboardEvent, MouseButton, MouseEvent, Status, Variant}}, funnel}; +use espanso_engine::{ + event::{ + input::{HotKeyEvent, Key, KeyboardEvent, MouseButton, MouseEvent, Status, Variant}, + Event, EventType, SourceId, + }, + funnel, +}; pub struct DetectSource { pub receiver: Receiver<(InputEvent, SourceId)>, @@ -39,105 +45,99 @@ impl<'a> funnel::Source<'a> for DetectSource { InputEvent::Keyboard(keyboard_event) => Event { source_id, etype: EventType::Keyboard(KeyboardEvent { - key: keyboard_event.key.into(), + key: convert_to_engine_key(keyboard_event.key), value: keyboard_event.value, - status: keyboard_event.status.into(), - variant: keyboard_event.variant.map(|variant| variant.into()), + status: convert_to_engine_status(keyboard_event.status), + variant: keyboard_event + .variant + .map(|variant| convert_to_engine_variant(variant)), }), }, InputEvent::Mouse(mouse_event) => Event { source_id, etype: EventType::Mouse(MouseEvent { - status: mouse_event.status.into(), - button: mouse_event.button.into(), + status: convert_to_engine_status(mouse_event.status), + button: convert_to_engine_mouse_button(mouse_event.button), }), }, InputEvent::HotKey(hotkey_event) => Event { source_id, etype: EventType::HotKey(HotKeyEvent { hotkey_id: hotkey_event.hotkey_id, - }) - } + }), + }, } } } -impl From for Key { - fn from(key: espanso_detect::event::Key) -> Self { - match key { - espanso_detect::event::Key::Alt => Key::Alt, - espanso_detect::event::Key::CapsLock => Key::CapsLock, - espanso_detect::event::Key::Control => Key::Control, - espanso_detect::event::Key::Meta => Key::Meta, - espanso_detect::event::Key::NumLock => Key::NumLock, - espanso_detect::event::Key::Shift => Key::Shift, - espanso_detect::event::Key::Enter => Key::Enter, - espanso_detect::event::Key::Tab => Key::Tab, - espanso_detect::event::Key::Space => Key::Space, - espanso_detect::event::Key::ArrowDown => Key::ArrowDown, - espanso_detect::event::Key::ArrowLeft => Key::ArrowLeft, - espanso_detect::event::Key::ArrowRight => Key::ArrowRight, - espanso_detect::event::Key::ArrowUp => Key::ArrowUp, - espanso_detect::event::Key::End => Key::End, - espanso_detect::event::Key::Home => Key::Home, - espanso_detect::event::Key::PageDown => Key::PageDown, - espanso_detect::event::Key::PageUp => Key::PageUp, - espanso_detect::event::Key::Escape => Key::Escape, - espanso_detect::event::Key::Backspace => Key::Backspace, - espanso_detect::event::Key::F1 => Key::F1, - espanso_detect::event::Key::F2 => Key::F2, - espanso_detect::event::Key::F3 => Key::F3, - espanso_detect::event::Key::F4 => Key::F4, - espanso_detect::event::Key::F5 => Key::F5, - espanso_detect::event::Key::F6 => Key::F6, - espanso_detect::event::Key::F7 => Key::F7, - espanso_detect::event::Key::F8 => Key::F8, - espanso_detect::event::Key::F9 => Key::F9, - espanso_detect::event::Key::F10 => Key::F10, - espanso_detect::event::Key::F11 => Key::F11, - espanso_detect::event::Key::F12 => Key::F12, - espanso_detect::event::Key::F13 => Key::F13, - espanso_detect::event::Key::F14 => Key::F14, - espanso_detect::event::Key::F15 => Key::F15, - espanso_detect::event::Key::F16 => Key::F16, - espanso_detect::event::Key::F17 => Key::F17, - espanso_detect::event::Key::F18 => Key::F18, - espanso_detect::event::Key::F19 => Key::F19, - espanso_detect::event::Key::F20 => Key::F20, - espanso_detect::event::Key::Other(code) => Key::Other(code), - } +pub fn convert_to_engine_key(key: espanso_detect::event::Key) -> Key { + match key { + espanso_detect::event::Key::Alt => Key::Alt, + espanso_detect::event::Key::CapsLock => Key::CapsLock, + espanso_detect::event::Key::Control => Key::Control, + espanso_detect::event::Key::Meta => Key::Meta, + espanso_detect::event::Key::NumLock => Key::NumLock, + espanso_detect::event::Key::Shift => Key::Shift, + espanso_detect::event::Key::Enter => Key::Enter, + espanso_detect::event::Key::Tab => Key::Tab, + espanso_detect::event::Key::Space => Key::Space, + espanso_detect::event::Key::ArrowDown => Key::ArrowDown, + espanso_detect::event::Key::ArrowLeft => Key::ArrowLeft, + espanso_detect::event::Key::ArrowRight => Key::ArrowRight, + espanso_detect::event::Key::ArrowUp => Key::ArrowUp, + espanso_detect::event::Key::End => Key::End, + espanso_detect::event::Key::Home => Key::Home, + espanso_detect::event::Key::PageDown => Key::PageDown, + espanso_detect::event::Key::PageUp => Key::PageUp, + espanso_detect::event::Key::Escape => Key::Escape, + espanso_detect::event::Key::Backspace => Key::Backspace, + espanso_detect::event::Key::F1 => Key::F1, + espanso_detect::event::Key::F2 => Key::F2, + espanso_detect::event::Key::F3 => Key::F3, + espanso_detect::event::Key::F4 => Key::F4, + espanso_detect::event::Key::F5 => Key::F5, + espanso_detect::event::Key::F6 => Key::F6, + espanso_detect::event::Key::F7 => Key::F7, + espanso_detect::event::Key::F8 => Key::F8, + espanso_detect::event::Key::F9 => Key::F9, + espanso_detect::event::Key::F10 => Key::F10, + espanso_detect::event::Key::F11 => Key::F11, + espanso_detect::event::Key::F12 => Key::F12, + espanso_detect::event::Key::F13 => Key::F13, + espanso_detect::event::Key::F14 => Key::F14, + espanso_detect::event::Key::F15 => Key::F15, + espanso_detect::event::Key::F16 => Key::F16, + espanso_detect::event::Key::F17 => Key::F17, + espanso_detect::event::Key::F18 => Key::F18, + espanso_detect::event::Key::F19 => Key::F19, + espanso_detect::event::Key::F20 => Key::F20, + espanso_detect::event::Key::Other(code) => Key::Other(code), } } -impl From for Variant { - fn from(variant: espanso_detect::event::Variant) -> Self { - match variant { - espanso_detect::event::Variant::Left => Variant::Left, - espanso_detect::event::Variant::Right => Variant::Right, - } +pub fn convert_to_engine_variant(variant: espanso_detect::event::Variant) -> Variant { + match variant { + espanso_detect::event::Variant::Left => Variant::Left, + espanso_detect::event::Variant::Right => Variant::Right, } } -impl From for Status { - fn from(status: espanso_detect::event::Status) -> Self { - match status { - espanso_detect::event::Status::Pressed => Status::Pressed, - espanso_detect::event::Status::Released => Status::Released, - } +pub fn convert_to_engine_status(status: espanso_detect::event::Status) -> Status { + match status { + espanso_detect::event::Status::Pressed => Status::Pressed, + espanso_detect::event::Status::Released => Status::Released, } } -impl From for MouseButton { - fn from(button: espanso_detect::event::MouseButton) -> Self { - match button { - espanso_detect::event::MouseButton::Left => MouseButton::Left, - espanso_detect::event::MouseButton::Right => MouseButton::Right, - espanso_detect::event::MouseButton::Middle => MouseButton::Middle, - espanso_detect::event::MouseButton::Button1 => MouseButton::Button1, - espanso_detect::event::MouseButton::Button2 => MouseButton::Button2, - espanso_detect::event::MouseButton::Button3 => MouseButton::Button3, - espanso_detect::event::MouseButton::Button4 => MouseButton::Button4, - espanso_detect::event::MouseButton::Button5 => MouseButton::Button5, - } +pub fn convert_to_engine_mouse_button(button: espanso_detect::event::MouseButton) -> MouseButton { + match button { + espanso_detect::event::MouseButton::Left => MouseButton::Left, + espanso_detect::event::MouseButton::Right => MouseButton::Right, + espanso_detect::event::MouseButton::Middle => MouseButton::Middle, + espanso_detect::event::MouseButton::Button1 => MouseButton::Button1, + espanso_detect::event::MouseButton::Button2 => MouseButton::Button2, + espanso_detect::event::MouseButton::Button3 => MouseButton::Button3, + espanso_detect::event::MouseButton::Button4 => MouseButton::Button4, + espanso_detect::event::MouseButton::Button5 => MouseButton::Button5, } } diff --git a/espanso/src/cli/worker/engine/funnel/exit.rs b/espanso/src/cli/worker/engine/funnel/exit.rs index 74da016..3efb006 100644 --- a/espanso/src/cli/worker/engine/funnel/exit.rs +++ b/espanso/src/cli/worker/engine/funnel/exit.rs @@ -19,7 +19,7 @@ use crossbeam::channel::{Receiver, Select, SelectedOperation}; -use crate::engine::{event::{Event, EventType, ExitMode}, funnel}; +use espanso_engine::{event::{Event, EventType, ExitMode}, funnel}; use super::sequencer::Sequencer; diff --git a/espanso/src/cli/worker/engine/funnel/modifier.rs b/espanso/src/cli/worker/engine/funnel/modifier.rs index f2eea12..ba3229f 100644 --- a/espanso/src/cli/worker/engine/funnel/modifier.rs +++ b/espanso/src/cli/worker/engine/funnel/modifier.rs @@ -24,7 +24,7 @@ use std::{ use log::warn; -use crate::engine::process::ModifierStatusProvider; +use espanso_engine::process::ModifierStatusProvider; /// This duration represents the maximum length for which a pressed modifier /// event is considered valid. This is useful when the "release" event is diff --git a/espanso/src/cli/worker/engine/funnel/secure_input.rs b/espanso/src/cli/worker/engine/funnel/secure_input.rs index 72953e5..527c80b 100644 --- a/espanso/src/cli/worker/engine/funnel/secure_input.rs +++ b/espanso/src/cli/worker/engine/funnel/secure_input.rs @@ -19,12 +19,10 @@ use crossbeam::channel::{Receiver, Select, SelectedOperation}; -use crate::{ - cli::worker::secure_input::SecureInputEvent, - engine::{ - event::{internal::SecureInputEnabledEvent, Event, EventType}, - funnel, - }, +use crate::cli::worker::secure_input::SecureInputEvent; +use espanso_engine::{ + event::{internal::SecureInputEnabledEvent, Event, EventType}, + funnel, }; use super::sequencer::Sequencer; diff --git a/espanso/src/cli/worker/engine/funnel/sequencer.rs b/espanso/src/cli/worker/engine/funnel/sequencer.rs index 91866bd..001d26c 100644 --- a/espanso/src/cli/worker/engine/funnel/sequencer.rs +++ b/espanso/src/cli/worker/engine/funnel/sequencer.rs @@ -22,7 +22,7 @@ use std::sync::{ Arc, }; -use crate::engine::{event::SourceId, process::EventSequenceProvider}; +use espanso_engine::{event::SourceId, process::EventSequenceProvider}; #[derive(Clone)] pub struct Sequencer { diff --git a/espanso/src/cli/worker/engine/funnel/ui.rs b/espanso/src/cli/worker/engine/funnel/ui.rs index 4601f70..ded79c5 100644 --- a/espanso/src/cli/worker/engine/funnel/ui.rs +++ b/espanso/src/cli/worker/engine/funnel/ui.rs @@ -20,7 +20,7 @@ use crossbeam::channel::{Receiver, Select, SelectedOperation}; use espanso_ui::event::UIEvent; -use crate::engine::{ +use espanso_engine::{ event::{input::ContextMenuClickedEvent, Event, EventType}, funnel, }; diff --git a/espanso/src/cli/worker/engine/mod.rs b/espanso/src/cli/worker/engine/mod.rs index 5a1bf19..105ea91 100644 --- a/espanso/src/cli/worker/engine/mod.rs +++ b/espanso/src/cli/worker/engine/mod.rs @@ -23,6 +23,7 @@ use anyhow::Result; use crossbeam::channel::Receiver; use espanso_config::{config::ConfigStore, matches::store::MatchStore}; use espanso_detect::SourceCreationOptions; +use espanso_engine::event::ExitMode; use espanso_inject::{InjectorCreationOptions, KeyboardStateProvider}; use espanso_path::Paths; use espanso_ui::{event::UIEvent, UIRemote}; @@ -41,7 +42,7 @@ use crate::{cli::worker::{context::Context, engine::{dispatch::executor::{clipbo extension::{clipboard::ClipboardAdapter, form::FormProviderAdapter}, RendererAdapter, }, - }}, match_cache::{CombinedMatchCache, MatchCache}}, common_flags::{WORKER_START_REASON_CONFIG_CHANGED, WORKER_START_REASON_KEYBOARD_LAYOUT_CHANGED, WORKER_START_REASON_MANUAL}, engine::event::ExitMode, preferences::Preferences}; + }}, match_cache::{CombinedMatchCache, MatchCache}}, common_flags::{WORKER_START_REASON_CONFIG_CHANGED, WORKER_START_REASON_KEYBOARD_LAYOUT_CHANGED, WORKER_START_REASON_MANUAL}, preferences::Preferences}; use super::secure_input::SecureInputEvent; @@ -100,13 +101,13 @@ pub fn initialize_and_spawn( secure_input_receiver, &sequencer, ); - let sources: Vec<&dyn crate::engine::funnel::Source> = vec![ + let sources: Vec<&dyn espanso_engine::funnel::Source> = vec![ &detect_source, &exit_source, &ui_source, &secure_input_source, ]; - let funnel = crate::engine::funnel::default(&sources); + let funnel = espanso_engine::funnel::default(&sources); let rolling_matcher = RollingMatcherAdapter::new( &match_converter.get_rolling_matches(), @@ -121,7 +122,7 @@ pub fn initialize_and_spawn( }, ); let matchers: Vec< - &dyn crate::engine::process::Matcher< + &dyn espanso_engine::process::Matcher< super::engine::process::middleware::matcher::MatcherState, >, > = vec![&rolling_matcher, ®ex_matcher]; @@ -171,7 +172,7 @@ pub fn initialize_and_spawn( let disable_options = process::middleware::disable::extract_disable_options(&*config_manager.default()); - let mut processor = crate::engine::process::default( + let mut processor = espanso_engine::process::default( &matchers, &config_manager, &selector, @@ -193,7 +194,7 @@ pub fn initialize_and_spawn( let context_menu_adapter = ContextMenuHandlerAdapter::new(&*ui_remote); let icon_adapter = IconHandlerAdapter::new(&*ui_remote); let secure_input_adapter = SecureInputManagerAdapter::new(); - let dispatcher = crate::engine::dispatch::default( + let dispatcher = espanso_engine::dispatch::default( &event_injector, &clipboard_injector, &config_manager, @@ -233,7 +234,7 @@ pub fn initialize_and_spawn( } } - let mut engine = crate::engine::Engine::new(&funnel, &mut processor, &dispatcher); + let mut engine = espanso_engine::Engine::new(&funnel, &mut processor, &dispatcher); let exit_mode = engine.run(); info!("engine eventloop has terminated, propagating exit event..."); diff --git a/espanso/src/cli/worker/engine/process/middleware/disable.rs b/espanso/src/cli/worker/engine/process/middleware/disable.rs index f5ca7f8..b78e28c 100644 --- a/espanso/src/cli/worker/engine/process/middleware/disable.rs +++ b/espanso/src/cli/worker/engine/process/middleware/disable.rs @@ -19,8 +19,11 @@ use std::time::Duration; -use crate::engine::{event::input::{Key, Variant}, process::DisableOptions}; use espanso_config::config::Config; +use espanso_engine::{ + event::input::{Key, Variant}, + process::DisableOptions, +}; pub fn extract_disable_options(config: &dyn Config) -> DisableOptions { let (toggle_key, variant) = match config.toggle_key() { @@ -29,7 +32,7 @@ pub fn extract_disable_options(config: &dyn Config) -> DisableOptions { espanso_config::config::ToggleKey::Meta => (Some(Key::Meta), None), espanso_config::config::ToggleKey::Alt => (Some(Key::Alt), None), espanso_config::config::ToggleKey::Shift => (Some(Key::Shift), None), - espanso_config::config::ToggleKey::RightCtrl => (Some(Key::Control), Some(Variant::Right)), + espanso_config::config::ToggleKey::RightCtrl => (Some(Key::Control), Some(Variant::Right)), espanso_config::config::ToggleKey::RightAlt => (Some(Key::Alt), Some(Variant::Right)), espanso_config::config::ToggleKey::RightShift => (Some(Key::Shift), Some(Variant::Right)), espanso_config::config::ToggleKey::RightMeta => (Some(Key::Meta), Some(Variant::Right)), diff --git a/espanso/src/cli/worker/engine/process/middleware/image_resolve.rs b/espanso/src/cli/worker/engine/process/middleware/image_resolve.rs index 1737393..2b1bf88 100644 --- a/espanso/src/cli/worker/engine/process/middleware/image_resolve.rs +++ b/espanso/src/cli/worker/engine/process/middleware/image_resolve.rs @@ -19,21 +19,19 @@ use espanso_path::Paths; -use crate::engine::process::PathProvider; +use espanso_engine::process::PathProvider; pub struct PathProviderAdapter<'a> { paths: &'a Paths, } -impl <'a> PathProviderAdapter<'a> { +impl<'a> PathProviderAdapter<'a> { pub fn new(paths: &'a Paths) -> Self { - Self { - paths, - } + Self { paths } } } -impl <'a> PathProvider for PathProviderAdapter<'a> { +impl<'a> PathProvider for PathProviderAdapter<'a> { fn get_config_path(&self) -> &std::path::Path { &self.paths.config } diff --git a/espanso/src/cli/worker/engine/process/middleware/match_select.rs b/espanso/src/cli/worker/engine/process/middleware/match_select.rs index fd65be5..714527a 100644 --- a/espanso/src/cli/worker/engine/process/middleware/match_select.rs +++ b/espanso/src/cli/worker/engine/process/middleware/match_select.rs @@ -17,12 +17,10 @@ * along with espanso. If not, see . */ +use espanso_engine::process::MatchSelector; use log::error; -use crate::{ - engine::process::MatchSelector, - gui::{SearchItem, SearchUI}, -}; +use crate::gui::{SearchItem, SearchUI}; const MAX_LABEL_LEN: usize = 100; diff --git a/espanso/src/cli/worker/engine/process/middleware/matcher/mod.rs b/espanso/src/cli/worker/engine/process/middleware/matcher/mod.rs index bc38fae..9eda638 100644 --- a/espanso/src/cli/worker/engine/process/middleware/matcher/mod.rs +++ b/espanso/src/cli/worker/engine/process/middleware/matcher/mod.rs @@ -17,18 +17,18 @@ * along with espanso. If not, see . */ -use espanso_match::rolling::matcher::RollingMatcherState; -use espanso_match::regex::RegexMatcherState; -use crate::engine::{ +use espanso_engine::{ event::input::Key, process::{MatchResult, MatcherEvent}, }; +use espanso_match::regex::RegexMatcherState; +use espanso_match::rolling::matcher::RollingMatcherState; use enum_as_inner::EnumAsInner; -pub mod rolling; -pub mod regex; pub mod convert; +pub mod regex; +pub mod rolling; #[derive(Clone, EnumAsInner)] pub enum MatcherState<'a> { @@ -36,73 +36,67 @@ pub enum MatcherState<'a> { 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, - } +pub fn convert_to_match_event(event: &MatcherEvent) -> espanso_match::event::Event { + match event { + MatcherEvent::Key { key, chars } => espanso_match::event::Event::Key { + key: convert_to_match_key(key.clone()), + 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, - } +pub fn convert_to_engine_result(result: espanso_match::MatchResult) -> MatchResult { + MatchResult { + 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, - } +pub fn convert_to_match_key(key: Key) -> espanso_match::event::Key { + 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/process/middleware/matcher/regex.rs b/espanso/src/cli/worker/engine/process/middleware/matcher/regex.rs index 15263c7..313ca02 100644 --- a/espanso/src/cli/worker/engine/process/middleware/matcher/regex.rs +++ b/espanso/src/cli/worker/engine/process/middleware/matcher/regex.rs @@ -17,10 +17,10 @@ * along with espanso. If not, see . */ -use crate::engine::process::{MatchResult, Matcher, MatcherEvent}; +use espanso_engine::process::{MatchResult, Matcher, MatcherEvent}; use espanso_match::regex::{RegexMatch, RegexMatcher, RegexMatcherOptions}; -use super::MatcherState; +use super::{convert_to_engine_result, convert_to_match_event, MatcherState}; pub struct RegexMatcherAdapterOptions { pub max_buffer_size: usize, @@ -32,9 +32,12 @@ pub struct RegexMatcherAdapter { impl RegexMatcherAdapter { pub fn new(matches: &[RegexMatch], options: &RegexMatcherAdapterOptions) -> Self { - let matcher = RegexMatcher::new(matches, RegexMatcherOptions { - max_buffer_size: options.max_buffer_size, - }); + let matcher = RegexMatcher::new( + matches, + RegexMatcherOptions { + max_buffer_size: options.max_buffer_size, + }, + ); Self { matcher } } @@ -55,12 +58,12 @@ impl<'a> Matcher<'a, MatcherState<'a>> for RegexMatcherAdapter { panic!("invalid state type received in RegexMatcherAdapter") } }); - let event = event.into(); + let event = convert_to_match_event(event); 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(); + let results: Vec = results.into_iter().map(convert_to_engine_result).collect(); (enum_state, results) } diff --git a/espanso/src/cli/worker/engine/process/middleware/matcher/rolling.rs b/espanso/src/cli/worker/engine/process/middleware/matcher/rolling.rs index ec8975e..f5d96b0 100644 --- a/espanso/src/cli/worker/engine/process/middleware/matcher/rolling.rs +++ b/espanso/src/cli/worker/engine/process/middleware/matcher/rolling.rs @@ -22,11 +22,9 @@ use espanso_match::rolling::{ RollingMatch, }; -use crate::engine::{ - process::{MatchResult, Matcher, MatcherEvent}, -}; +use espanso_engine::process::{MatchResult, Matcher, MatcherEvent}; -use super::MatcherState; +use super::{convert_to_engine_result, convert_to_match_event, MatcherState}; pub struct RollingMatcherAdapterOptions { pub char_word_separators: Vec, @@ -65,12 +63,12 @@ impl<'a> Matcher<'a, MatcherState<'a>> for RollingMatcherAdapter { panic!("invalid state type received in RollingMatcherAdapter") } }); - let event = event.into(); + let event = convert_to_match_event(event); let (state, results) = self.matcher.process(prev_state, event); let enum_state = MatcherState::Rolling(state); - let results: Vec = results.into_iter().map(|result| result.into()).collect(); + let results: Vec = results.into_iter().map(convert_to_engine_result).collect(); (enum_state, results) } diff --git a/espanso/src/cli/worker/engine/process/middleware/multiplex.rs b/espanso/src/cli/worker/engine/process/middleware/multiplex.rs index 360144a..be197ba 100644 --- a/espanso/src/cli/worker/engine/process/middleware/multiplex.rs +++ b/espanso/src/cli/worker/engine/process/middleware/multiplex.rs @@ -19,16 +19,14 @@ use espanso_config::matches::{Match, MatchEffect}; -use crate::{ - cli::worker::{builtin::BuiltInMatch, context::Context}, - engine::{ - event::{ - internal::DetectedMatch, - internal::{ImageRequestedEvent, RenderingRequestedEvent, TextFormat}, - EventType, - }, - process::Multiplexer, +use crate::cli::worker::{builtin::BuiltInMatch, context::Context}; +use espanso_engine::{ + event::{ + internal::DetectedMatch, + internal::{ImageRequestedEvent, RenderingRequestedEvent, TextFormat}, + EventType, }, + process::Multiplexer, }; pub trait MatchProvider<'a> { @@ -46,7 +44,7 @@ pub struct MultiplexAdapter<'a> { } impl<'a> MultiplexAdapter<'a> { - pub fn new(provider: &'a dyn MatchProvider<'a>, context: &'a Context) -> Self { + pub fn new(provider: &'a dyn MatchProvider<'a>, context: &'a dyn Context) -> Self { Self { provider, context } } } diff --git a/espanso/src/cli/worker/engine/process/middleware/render/mod.rs b/espanso/src/cli/worker/engine/process/middleware/render/mod.rs index 64c1510..0a5e793 100644 --- a/espanso/src/cli/worker/engine/process/middleware/render/mod.rs +++ b/espanso/src/cli/worker/engine/process/middleware/render/mod.rs @@ -27,9 +27,7 @@ use espanso_config::{ }; use espanso_render::{CasingStyle, Context, RenderOptions, Template, Value, Variable}; -use crate::{ - engine::process::{Renderer, RendererError}, -}; +use espanso_engine::process::{Renderer, RendererError}; pub trait MatchProvider<'a> { fn matches(&self) -> Vec<&'a Match>; @@ -200,7 +198,7 @@ impl<'a> Renderer<'a> for RendererAdapter<'a> { let context = context_cache .entry(config.id()) .or_insert_with(|| generate_context(&match_set, &self.template_map, &self.global_vars_map)); - + let raw_match = self.match_provider.get(match_id); let propagate_case = raw_match.map(is_propagate_case).unwrap_or(false); let preferred_uppercasing_style = raw_match.and_then(extract_uppercasing_style); @@ -221,11 +219,14 @@ 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.insert(0, Variable { - name, - var_type: "echo".to_string(), - params, - }) + augmented.vars.insert( + 0, + Variable { + name, + var_type: "echo".to_string(), + params, + }, + ) } Some(augmented) } else { diff --git a/espanso/src/cli/worker/ipc.rs b/espanso/src/cli/worker/ipc.rs index 5384bac..3d651b3 100644 --- a/espanso/src/cli/worker/ipc.rs +++ b/espanso/src/cli/worker/ipc.rs @@ -21,10 +21,11 @@ use std::path::Path; use anyhow::Result; use crossbeam::channel::Sender; +use espanso_engine::event::ExitMode; use espanso_ipc::{EventHandlerResponse, IPCServer}; use log::{error, warn}; -use crate::{engine::event::ExitMode, ipc::IPCEvent}; +use crate::ipc::IPCEvent; pub fn initialize_and_spawn(runtime_dir: &Path, exit_notify: Sender) -> Result<()> { let server = crate::ipc::create_worker_ipc_server(runtime_dir)?; @@ -32,38 +33,38 @@ pub fn initialize_and_spawn(runtime_dir: &Path, exit_notify: Sender) - std::thread::Builder::new() .name("worker-ipc-handler".to_string()) .spawn(move || { - server.run(Box::new(move |event| { - match event { - IPCEvent::Exit => { - if let Err(err) = exit_notify.send(ExitMode::Exit) { - error!( - "experienced error while sending exit signal from worker ipc handler: {}", - err - ); - } - - EventHandlerResponse::NoResponse - } - IPCEvent::ExitAllProcesses => { - if let Err(err) = exit_notify.send(ExitMode::ExitAllProcesses) { - error!( - "experienced error while sending exit signal from worker ipc handler: {}", - err - ); - } - - EventHandlerResponse::NoResponse - } - unexpected_event => { - warn!( - "received unexpected event in worker ipc handler: {:?}", - unexpected_event + server + .run(Box::new(move |event| match event { + IPCEvent::Exit => { + if let Err(err) = exit_notify.send(ExitMode::Exit) { + error!( + "experienced error while sending exit signal from worker ipc handler: {}", + err ); - - EventHandlerResponse::NoResponse } + + EventHandlerResponse::NoResponse } - })).expect("unable to spawn IPC server"); + IPCEvent::ExitAllProcesses => { + if let Err(err) = exit_notify.send(ExitMode::ExitAllProcesses) { + error!( + "experienced error while sending exit signal from worker ipc handler: {}", + err + ); + } + + EventHandlerResponse::NoResponse + } + unexpected_event => { + warn!( + "received unexpected event in worker ipc handler: {:?}", + unexpected_event + ); + + EventHandlerResponse::NoResponse + } + })) + .expect("unable to spawn IPC server"); })?; Ok(()) diff --git a/espanso/src/cli/worker/match_cache.rs b/espanso/src/cli/worker/match_cache.rs index 987a615..632dc8a 100644 --- a/espanso/src/cli/worker/match_cache.rs +++ b/espanso/src/cli/worker/match_cache.rs @@ -59,17 +59,17 @@ impl<'a> super::engine::process::middleware::render::MatchProvider<'a> for Match } } -impl<'a> crate::engine::process::MatchInfoProvider for MatchCache<'a> { - fn get_force_mode(&self, match_id: i32) -> Option { +impl<'a> espanso_engine::process::MatchInfoProvider for MatchCache<'a> { + fn get_force_mode(&self, match_id: i32) -> Option { let m = self.cache.get(&match_id)?; if let MatchEffect::Text(text_effect) = &m.effect { if let Some(force_mode) = &text_effect.force_mode { match force_mode { espanso_config::matches::TextInjectMode::Keys => { - return Some(crate::engine::event::effect::TextInjectMode::Keys) + return Some(espanso_engine::event::effect::TextInjectMode::Keys) } espanso_config::matches::TextInjectMode::Clipboard => { - return Some(crate::engine::event::effect::TextInjectMode::Clipboard) + return Some(espanso_engine::event::effect::TextInjectMode::Clipboard) } } } @@ -155,7 +155,7 @@ impl<'a> super::engine::process::middleware::multiplex::MatchProvider<'a> } } -impl<'a> crate::engine::process::MatchProvider for CombinedMatchCache<'a> { +impl<'a> espanso_engine::process::MatchProvider for CombinedMatchCache<'a> { fn get_all_matches_ids(&self) -> Vec { let mut ids: Vec = self.builtin_match_cache.keys().copied().collect(); ids.extend(self.user_match_cache.ids()); diff --git a/espanso/src/cli/worker/mod.rs b/espanso/src/cli/worker/mod.rs index b7c0b26..120ffd0 100644 --- a/espanso/src/cli/worker/mod.rs +++ b/espanso/src/cli/worker/mod.rs @@ -18,10 +18,10 @@ */ use crossbeam::channel::unbounded; +use espanso_engine::event::ExitMode; use log::{debug, error, info}; use crate::{ - engine::event::ExitMode, exit_code::{ WORKER_ALREADY_RUNNING, WORKER_EXIT_ALL_PROCESSES, WORKER_GENERAL_ERROR, WORKER_LEGACY_ALREADY_RUNNING, WORKER_RESTART, WORKER_SUCCESS, @@ -62,9 +62,7 @@ fn worker_main(args: CliModuleArgs) -> i32 { let cli_args = args.cli_args.expect("missing cli_args in worker main"); // When restarted, the daemon passes the reason why the worker was restarted (config_change, etc) - let start_reason = cli_args - .value_of("start-reason") - .map(String::from); + let start_reason = cli_args.value_of("start-reason").map(String::from); debug!("starting with start-reason = {:?}", start_reason); // Avoid running multiple worker instances diff --git a/espanso/src/engine/dispatch/default.rs b/espanso/src/engine/dispatch/default.rs deleted file mode 100644 index 86cc83c..0000000 --- a/espanso/src/engine/dispatch/default.rs +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 super::{ContextMenuHandler, Event, IconHandler, ImageInjector, SecureInputManager}; -use super::{ModeProvider, Dispatcher, Executor, KeyInjector, TextInjector, HtmlInjector}; - -pub struct DefaultDispatcher<'a> { - executors: Vec>, -} - -impl<'a> DefaultDispatcher<'a> { - pub fn new( - event_injector: &'a dyn TextInjector, - clipboard_injector: &'a dyn TextInjector, - mode_provider: &'a dyn ModeProvider, - key_injector: &'a dyn KeyInjector, - html_injector: &'a dyn HtmlInjector, - image_injector: &'a dyn ImageInjector, - context_menu_handler: &'a dyn ContextMenuHandler, - icon_handler: &'a dyn IconHandler, - secure_input_manager: &'a dyn SecureInputManager, - ) -> Self { - Self { - executors: vec![ - Box::new(super::executor::text_inject::TextInjectExecutor::new( - event_injector, - clipboard_injector, - mode_provider, - )), - Box::new(super::executor::key_inject::KeyInjectExecutor::new( - key_injector, - )), - Box::new(super::executor::html_inject::HtmlInjectExecutor::new( - html_injector, - )), - Box::new(super::executor::image_inject::ImageInjectExecutor::new( - image_injector, - )), - Box::new(super::executor::context_menu::ContextMenuExecutor::new( - context_menu_handler, - )), - Box::new(super::executor::icon_update::IconUpdateExecutor::new( - icon_handler, - )), - Box::new(super::executor::secure_input::SecureInputExecutor::new( - secure_input_manager, - )), - ], - } - } -} - -impl<'a> Dispatcher for DefaultDispatcher<'a> { - fn dispatch(&self, event: Event) { - for executor in self.executors.iter() { - if executor.execute(&event) { - break; - } - } - } -} diff --git a/espanso/src/engine/dispatch/executor/context_menu.rs b/espanso/src/engine/dispatch/executor/context_menu.rs deleted file mode 100644 index 9345c29..0000000 --- a/espanso/src/engine/dispatch/executor/context_menu.rs +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 super::super::{Event, Executor}; -use crate::engine::event::{ui::MenuItem, EventType}; -use anyhow::Result; -use log::error; - -pub trait ContextMenuHandler { - fn show_context_menu(&self, items: &[MenuItem]) -> Result<()>; -} - -pub struct ContextMenuExecutor<'a> { - handler: &'a dyn ContextMenuHandler, -} - -impl<'a> ContextMenuExecutor<'a> { - pub fn new(handler: &'a dyn ContextMenuHandler) -> Self { - Self { handler } - } -} - -impl<'a> Executor for ContextMenuExecutor<'a> { - fn execute(&self, event: &Event) -> bool { - if let EventType::ShowContextMenu(context_menu_event) = &event.etype { - if let Err(error) = self.handler.show_context_menu(&context_menu_event.items) { - error!("context menu handler reported an error: {:?}", error); - } - - return true; - } - - false - } -} - -// TODO: test diff --git a/espanso/src/engine/dispatch/executor/html_inject.rs b/espanso/src/engine/dispatch/executor/html_inject.rs deleted file mode 100644 index df72cf4..0000000 --- a/espanso/src/engine/dispatch/executor/html_inject.rs +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 super::super::{Event, Executor}; -use crate::engine::event::EventType; -use anyhow::Result; -use log::error; - -pub trait HtmlInjector { - fn inject_html(&self, html: &str, fallback: &str) -> Result<()>; -} - -pub struct HtmlInjectExecutor<'a> { - injector: &'a dyn HtmlInjector, -} - -impl<'a> HtmlInjectExecutor<'a> { - pub fn new(injector: &'a dyn HtmlInjector) -> Self { - Self { injector } - } -} - -impl<'a> Executor for HtmlInjectExecutor<'a> { - fn execute(&self, event: &Event) -> bool { - if let EventType::HtmlInject(inject_event) = &event.etype { - // Render the text fallback for those applications that don't support HTML clipboard - let decorator = html2text::render::text_renderer::TrivialDecorator::new(); - let fallback_text = - html2text::from_read_with_decorator(inject_event.html.as_bytes(), 1000000, decorator); - - if let Err(error) = self - .injector - .inject_html(&inject_event.html, &fallback_text) - { - error!("html injector reported an error: {:?}", error); - } - - return true; - } - - false - } -} - -// TODO: test diff --git a/espanso/src/engine/dispatch/executor/icon_update.rs b/espanso/src/engine/dispatch/executor/icon_update.rs deleted file mode 100644 index 95395a3..0000000 --- a/espanso/src/engine/dispatch/executor/icon_update.rs +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 super::super::{Event, Executor}; -use crate::engine::event::{EventType, ui::{IconStatus}}; -use anyhow::Result; -use log::error; - -pub trait IconHandler { - fn update_icon(&self, status: &IconStatus) -> Result<()>; -} - -pub struct IconUpdateExecutor<'a> { - handler: &'a dyn IconHandler, -} - -impl<'a> IconUpdateExecutor<'a> { - pub fn new(handler: &'a dyn IconHandler) -> Self { - Self { handler } - } -} - -impl<'a> Executor for IconUpdateExecutor<'a> { - fn execute(&self, event: &Event) -> bool { - if let EventType::IconStatusChange(m_event) = &event.etype { - if let Err(error) = self.handler.update_icon(&m_event.status) { - error!("icon handler reported an error: {:?}", error); - } - - return true; - } - - false - } -} - -// TODO: test diff --git a/espanso/src/engine/dispatch/executor/image_inject.rs b/espanso/src/engine/dispatch/executor/image_inject.rs deleted file mode 100644 index 1fdcfd2..0000000 --- a/espanso/src/engine/dispatch/executor/image_inject.rs +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 super::super::{Event, Executor}; -use crate::engine::event::EventType; -use anyhow::Result; -use log::error; - -pub trait ImageInjector { - fn inject_image(&self, path: &str) -> Result<()>; -} - -pub struct ImageInjectExecutor<'a> { - injector: &'a dyn ImageInjector, -} - -impl<'a> ImageInjectExecutor<'a> { - pub fn new(injector: &'a dyn ImageInjector) -> Self { - Self { injector } - } -} - -impl<'a> Executor for ImageInjectExecutor<'a> { - fn execute(&self, event: &Event) -> bool { - if let EventType::ImageInject(inject_event) = &event.etype { - if let Err(error) = self - .injector - .inject_image(&inject_event.image_path) - { - error!("image injector reported an error: {:?}", error); - } - - return true; - } - - false - } -} - -// TODO: test diff --git a/espanso/src/engine/dispatch/executor/key_inject.rs b/espanso/src/engine/dispatch/executor/key_inject.rs deleted file mode 100644 index 851066e..0000000 --- a/espanso/src/engine/dispatch/executor/key_inject.rs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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::event::EventType; - -use super::super::{Event, Executor, KeyInjector}; -use log::error; - -pub struct KeyInjectExecutor<'a> { - injector: &'a dyn KeyInjector, -} - -impl<'a> KeyInjectExecutor<'a> { - pub fn new(injector: &'a dyn KeyInjector) -> Self { - Self { injector } - } -} - -impl<'a> Executor for KeyInjectExecutor<'a> { - fn execute(&self, event: &Event) -> bool { - if let EventType::KeySequenceInject(inject_event) = &event.etype { - if let Err(error) = self.injector.inject_sequence(&inject_event.keys) { - error!("key injector reported an error: {}", error); - } - return true; - } - - false - } -} diff --git a/espanso/src/engine/dispatch/executor/mod.rs b/espanso/src/engine/dispatch/executor/mod.rs deleted file mode 100644 index 586244c..0000000 --- a/espanso/src/engine/dispatch/executor/mod.rs +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 . - */ - -pub mod context_menu; -pub mod icon_update; -pub mod image_inject; -pub mod html_inject; -pub mod key_inject; -pub mod secure_input; -pub mod text_inject; \ No newline at end of file diff --git a/espanso/src/engine/dispatch/executor/secure_input.rs b/espanso/src/engine/dispatch/executor/secure_input.rs deleted file mode 100644 index 6cf56b0..0000000 --- a/espanso/src/engine/dispatch/executor/secure_input.rs +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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::event::EventType; - -use super::super::{Event, Executor}; -use anyhow::Result; -use log::error; - -pub trait SecureInputManager { - fn display_secure_input_troubleshoot(&self) -> Result<()>; - fn launch_secure_input_autofix(&self) -> Result<()>; -} - -pub struct SecureInputExecutor<'a> { - manager: &'a dyn SecureInputManager, -} - -impl<'a> SecureInputExecutor<'a> { - pub fn new(manager: &'a dyn SecureInputManager) -> Self { - Self { manager } - } -} - -impl<'a> Executor for SecureInputExecutor<'a> { - fn execute(&self, event: &Event) -> bool { - if let EventType::DisplaySecureInputTroubleshoot = &event.etype { - if let Err(error) = self.manager.display_secure_input_troubleshoot() { - error!("unable to display secure input troubleshoot: {}", error); - } - return true; - } else if let EventType::LaunchSecureInputAutoFix = &event.etype { - if let Err(error) = self.manager.launch_secure_input_autofix() { - error!("unable to launch secure input autofix: {}", error); - } - return true; - } - - - false - } -} \ No newline at end of file diff --git a/espanso/src/engine/dispatch/executor/text_inject.rs b/espanso/src/engine/dispatch/executor/text_inject.rs deleted file mode 100644 index f0c2109..0000000 --- a/espanso/src/engine/dispatch/executor/text_inject.rs +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 anyhow::Result; -use super::super::{Event, Executor}; -use crate::engine::event::{EventType, effect::TextInjectMode}; -use log::{error, trace}; - -pub trait TextInjector { - fn name(&self) -> &'static str; - fn inject_text(&self, text: &str) -> Result<()>; -} - -pub trait ModeProvider { - fn active_mode(&self) -> Mode; -} - -pub enum Mode { - Event, - Clipboard, - Auto { - // Maximum size after which the clipboard backend - // is used over the event one to speed up the injection. - clipboard_threshold: usize, - } -} - -pub struct TextInjectExecutor<'a> { - event_injector: &'a dyn TextInjector, - clipboard_injector: &'a dyn TextInjector, - mode_provider: &'a dyn ModeProvider, -} - -impl<'a> TextInjectExecutor<'a> { - pub fn new( - event_injector: &'a dyn TextInjector, - clipboard_injector: &'a dyn TextInjector, - mode_provider: &'a dyn ModeProvider, - ) -> Self { - Self { - event_injector, - clipboard_injector, - mode_provider, - } - } -} - -impl<'a> Executor for TextInjectExecutor<'a> { - fn execute(&self, event: &Event) -> bool { - if let EventType::TextInject(inject_event) = &event.etype { - let active_mode = self.mode_provider.active_mode(); - - let injector = if let Some(force_mode) = &inject_event.force_mode { - if let TextInjectMode::Keys = force_mode { - self.event_injector - } else { - self.clipboard_injector - } - } else if let Mode::Clipboard = active_mode { - self.clipboard_injector - } else if let Mode::Event = active_mode { - self.event_injector - } else if let Mode::Auto { clipboard_threshold } = active_mode { - if inject_event.text.chars().count() > clipboard_threshold { - self.clipboard_injector - } else if cfg!(target_os = "linux") { - if inject_event.text.chars().all(|c| c.is_ascii()) { - self.event_injector - } else { - self.clipboard_injector - } - } else { - self.event_injector - } - } else { - self.event_injector - }; - - trace!("using injector: {}", injector.name()); - - if let Err(error) = injector.inject_text(&inject_event.text) { - error!("text injector ({}) reported an error: {:?}", injector.name(), error); - } - - return true; - } - - false - } -} - -// TODO: test diff --git a/espanso/src/engine/dispatch/mod.rs b/espanso/src/engine/dispatch/mod.rs deleted file mode 100644 index 0072d75..0000000 --- a/espanso/src/engine/dispatch/mod.rs +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 anyhow::Result; - -use super::{event::input::Key, Event}; - -mod default; -mod executor; - -pub trait Executor { - fn execute(&self, event: &Event) -> bool; -} - -pub trait Dispatcher { - fn dispatch(&self, event: Event); -} - -// Re-export dependency injection entities -pub use executor::html_inject::HtmlInjector; -pub use executor::text_inject::{Mode, ModeProvider, TextInjector}; -pub use executor::image_inject::{ImageInjector}; -pub use executor::context_menu::{ContextMenuHandler}; -pub use executor::icon_update::IconHandler; -pub use executor::secure_input::SecureInputManager; - -// TODO: move into module -pub trait KeyInjector { - fn inject_sequence(&self, keys: &[Key]) -> Result<()>; -} - -pub fn default<'a>( - event_injector: &'a dyn TextInjector, - clipboard_injector: &'a dyn TextInjector, - mode_provider: &'a dyn ModeProvider, - key_injector: &'a dyn KeyInjector, - html_injector: &'a dyn HtmlInjector, - image_injector: &'a dyn ImageInjector, - context_menu_handler: &'a dyn ContextMenuHandler, - icon_handler: &'a dyn IconHandler, - secure_input_manager: &'a dyn SecureInputManager, -) -> impl Dispatcher + 'a { - default::DefaultDispatcher::new( - event_injector, - clipboard_injector, - mode_provider, - key_injector, - html_injector, - image_injector, - context_menu_handler, - icon_handler, - secure_input_manager, - ) -} diff --git a/espanso/src/engine/event/effect.rs b/espanso/src/engine/event/effect.rs deleted file mode 100644 index e8937b0..0000000 --- a/espanso/src/engine/event/effect.rs +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 super::input::Key; - -#[derive(Debug, Clone, PartialEq)] -pub struct TriggerCompensationEvent { - pub trigger: String, - pub left_separator: Option, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct CursorHintCompensationEvent { - pub cursor_hint_back_count: usize, -} - -#[derive(Debug, Clone)] -pub struct TextInjectRequest { - pub text: String, - pub force_mode: Option, -} - -#[derive(Debug, Clone)] -pub struct MarkdownInjectRequest { - pub markdown: String, -} - -#[derive(Debug, Clone)] -pub struct HtmlInjectRequest { - pub html: String, -} - -#[derive(Debug, PartialEq, Clone)] -pub enum TextInjectMode { - Keys, - Clipboard, -} - -#[derive(Debug, Clone)] -pub struct KeySequenceInjectRequest { - pub keys: Vec, -} - -#[derive(Debug, Clone)] -pub struct ImageInjectRequest { - pub image_path: String, -} \ No newline at end of file diff --git a/espanso/src/engine/event/input.rs b/espanso/src/engine/event/input.rs deleted file mode 100644 index b0f9f21..0000000 --- a/espanso/src/engine/event/input.rs +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 . - */ - -#[derive(Debug, PartialEq, Clone)] -pub enum Status { - Pressed, - Released, -} - -#[derive(Debug, PartialEq, Clone)] -pub enum Variant { - Left, - Right, -} - -#[derive(Debug, PartialEq, Clone)] -pub struct KeyboardEvent { - pub key: Key, - pub value: Option, - pub status: Status, - pub variant: Option, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum MouseButton { - Left, - Right, - Middle, - Button1, - Button2, - Button3, - Button4, - Button5, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct MouseEvent { - pub button: MouseButton, - pub status: Status, -} - -#[derive(Debug, Clone, 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, - - // Other keys, includes the raw code provided by the operating system - Other(i32), -} - -#[derive(Debug, Clone, PartialEq)] -pub struct ContextMenuClickedEvent { - pub context_item_id: u32, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct HotKeyEvent { - pub hotkey_id: i32, -} \ No newline at end of file diff --git a/espanso/src/engine/event/internal.rs b/espanso/src/engine/event/internal.rs deleted file mode 100644 index a35acad..0000000 --- a/espanso/src/engine/event/internal.rs +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 std::collections::HashMap; - -#[derive(Debug, Clone, PartialEq)] -pub struct MatchesDetectedEvent { - pub matches: Vec, -} - -#[derive(Debug, Clone, PartialEq, Default)] -pub struct DetectedMatch { - pub id: i32, - pub trigger: Option, - pub left_separator: Option, - pub right_separator: Option, - pub args: HashMap, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct MatchSelectedEvent { - pub chosen: DetectedMatch, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct CauseCompensatedMatchEvent { - pub m: DetectedMatch, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct RenderingRequestedEvent { - pub match_id: i32, - pub trigger: Option, - pub left_separator: Option, - pub right_separator: Option, - pub trigger_args: HashMap, - pub format: TextFormat, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum TextFormat { - Plain, - Markdown, - Html, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct ImageRequestedEvent { - pub match_id: i32, - pub image_path: String, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct ImageResolvedEvent { - pub image_path: String, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct RenderedEvent { - pub match_id: i32, - pub body: String, - pub format: TextFormat, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct DiscardPreviousEvent { - // All Events with a source_id smaller than this one will be discarded - pub minimum_source_id: u32, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct SecureInputEnabledEvent { - pub app_name: String, - pub app_path: String, -} \ No newline at end of file diff --git a/espanso/src/engine/event/mod.rs b/espanso/src/engine/event/mod.rs deleted file mode 100644 index 7e642bc..0000000 --- a/espanso/src/engine/event/mod.rs +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 . - */ - -pub mod input; -pub mod effect; -pub mod internal; -pub mod ui; - -pub type SourceId = u32; - -#[derive(Debug, Clone)] -pub struct Event { - // The source id is a unique, monothonically increasing number - // that is given to each event by the source and is propagated - // to all consequential events. - // For example, if a keyboard event with source_id = 5 generates - // a detected match event, this event will have source_id = 5 - pub source_id: SourceId, - pub etype: EventType, -} - -impl Event { - pub fn caused_by(cause_id: SourceId, event_type: EventType) -> Event { - Event { - source_id: cause_id, - etype: event_type, - } - } -} - -#[derive(Debug, Clone)] -pub enum EventType { - NOOP, - ProcessingError(String), - ExitRequested(ExitMode), - Exit(ExitMode), - Heartbeat, - - // Inputs - Keyboard(input::KeyboardEvent), - Mouse(input::MouseEvent), - HotKey(input::HotKeyEvent), - TrayIconClicked, - ContextMenuClicked(input::ContextMenuClickedEvent), - - // Internal - MatchesDetected(internal::MatchesDetectedEvent), - MatchSelected(internal::MatchSelectedEvent), - CauseCompensatedMatch(internal::CauseCompensatedMatchEvent), - - RenderingRequested(internal::RenderingRequestedEvent), - ImageRequested(internal::ImageRequestedEvent), - Rendered(internal::RenderedEvent), - ImageResolved(internal::ImageResolvedEvent), - MatchInjected, - DiscardPrevious(internal::DiscardPreviousEvent), - - Disabled, - Enabled, - DisableRequest, - EnableRequest, - SecureInputEnabled(internal::SecureInputEnabledEvent), - SecureInputDisabled, - - // Effects - TriggerCompensation(effect::TriggerCompensationEvent), - CursorHintCompensation(effect::CursorHintCompensationEvent), - - KeySequenceInject(effect::KeySequenceInjectRequest), - TextInject(effect::TextInjectRequest), - MarkdownInject(effect::MarkdownInjectRequest), - HtmlInject(effect::HtmlInjectRequest), - ImageInject(effect::ImageInjectRequest), - - // UI - ShowContextMenu(ui::ShowContextMenuEvent), - IconStatusChange(ui::IconStatusChangeEvent), - DisplaySecureInputTroubleshoot, - ShowSearchBar, - - // Other - LaunchSecureInputAutoFix, -} - -#[derive(Debug, Clone)] -pub enum ExitMode { - Exit, - ExitAllProcesses, - RestartWorker, -} \ No newline at end of file diff --git a/espanso/src/engine/event/ui.rs b/espanso/src/engine/event/ui.rs deleted file mode 100644 index 76e4ad0..0000000 --- a/espanso/src/engine/event/ui.rs +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 . - */ - -#[derive(Debug, Clone, PartialEq)] -pub struct ShowContextMenuEvent { - pub items: Vec, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum MenuItem { - Simple(SimpleMenuItem), - Sub(SubMenuItem), - Separator, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct SimpleMenuItem { - pub id: u32, - pub label: String, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct SubMenuItem { - pub label: String, - pub items: Vec, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct IconStatusChangeEvent { - pub status: IconStatus -} - -#[derive(Debug, Clone, PartialEq)] -pub enum IconStatus { - Enabled, - Disabled, - SecureInputDisabled, -} \ No newline at end of file diff --git a/espanso/src/engine/funnel/default.rs b/espanso/src/engine/funnel/default.rs deleted file mode 100644 index cfca9fc..0000000 --- a/espanso/src/engine/funnel/default.rs +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 crossbeam::channel::Select; - -use super::{Funnel, FunnelResult, Source}; - -pub struct DefaultFunnel<'a> { - sources: &'a [&'a dyn Source<'a>], -} - -impl <'a> DefaultFunnel<'a> { - pub fn new(sources: &'a [&'a dyn Source<'a>]) -> Self { - Self { - sources - } - } -} - -impl <'a> Funnel for DefaultFunnel<'a> { - fn receive(&self) -> FunnelResult { - let mut select = Select::new(); - - // First register all the sources to the select operation - for source in self.sources.iter() { - source.register(&mut select); - } - - // Wait for the first source (blocking operation) - let op = select.select(); - let source = self - .sources - .get(op.index()) - .expect("invalid source index returned by select operation"); - - // Receive (and convert) the event - let event = source.receive(op); - FunnelResult::Event(event) - } -} diff --git a/espanso/src/engine/funnel/mod.rs b/espanso/src/engine/funnel/mod.rs deleted file mode 100644 index db63349..0000000 --- a/espanso/src/engine/funnel/mod.rs +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 crossbeam::{channel::Select, channel::SelectedOperation}; - -use self::default::DefaultFunnel; - -use super::Event; - -mod default; - -pub trait Source<'a> { - fn register<'b>(&'a self, select: &mut Select<'a>) -> usize; - fn receive<'b>(&'a self, op: SelectedOperation) -> Event; -} - -pub trait Funnel { - fn receive(&self) -> FunnelResult; -} - -pub enum FunnelResult { - Event(Event), - EndOfStream, -} - -pub fn default<'a>(sources: &'a [&'a dyn Source<'a>]) -> impl Funnel + 'a { - DefaultFunnel::new(sources) -} \ No newline at end of file diff --git a/espanso/src/engine/mod.rs b/espanso/src/engine/mod.rs deleted file mode 100644 index 7045a95..0000000 --- a/espanso/src/engine/mod.rs +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 log::{debug}; - -use self::{dispatch::Dispatcher, event::{Event, EventType, ExitMode}, funnel::{Funnel, FunnelResult}, process::Processor}; - -pub mod dispatch; -pub mod event; -pub mod process; -pub mod funnel; - -pub struct Engine<'a> { - funnel: &'a dyn Funnel, - processor: &'a mut dyn Processor, - dispatcher: &'a dyn Dispatcher, -} - -impl <'a> Engine<'a> { - pub fn new(funnel: &'a dyn Funnel, processor: &'a mut dyn Processor, dispatcher: &'a dyn Dispatcher) -> Self { - Self { - funnel, - processor, - dispatcher, - } - } - - pub fn run(&mut self) -> ExitMode { - loop { - match self.funnel.receive() { - FunnelResult::Event(event) => { - let processed_events = self.processor.process(event); - for event in processed_events { - if let EventType::Exit(mode) = &event.etype { - debug!("exit event received with mode {:?}, exiting engine", mode); - return mode.clone(); - } - - self.dispatcher.dispatch(event); - } - } - FunnelResult::EndOfStream => { - debug!("end of stream received"); - return ExitMode::Exit; - } - } - } - } -} diff --git a/espanso/src/engine/process/default.rs b/espanso/src/engine/process/default.rs deleted file mode 100644 index 6af7f0f..0000000 --- a/espanso/src/engine/process/default.rs +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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 log::trace; - -use super::{DisableOptions, MatchFilter, MatchInfoProvider, MatchProvider, MatchSelector, Matcher, MatcherMiddlewareConfigProvider, Middleware, Multiplexer, PathProvider, Processor, Renderer, middleware::{ - match_select::MatchSelectMiddleware, matcher::MatcherMiddleware, multiplex::MultiplexMiddleware, - render::RenderMiddleware, action::{ActionMiddleware, EventSequenceProvider}, cursor_hint::CursorHintMiddleware, cause::CauseCompensateMiddleware, - delay_modifiers::{DelayForModifierReleaseMiddleware, ModifierStatusProvider}, markdown::MarkdownMiddleware, - past_discard::PastEventsDiscardMiddleware, - }}; -use crate::engine::{event::{Event, EventType}, process::middleware::{context_menu::ContextMenuMiddleware, disable::DisableMiddleware, exit::ExitMiddleware, hotkey::HotKeyMiddleware, icon_status::IconStatusMiddleware, image_resolve::ImageResolverMiddleware, search::SearchMiddleware}}; -use std::collections::VecDeque; - -pub struct DefaultProcessor<'a> { - event_queue: VecDeque, - middleware: Vec>, -} - -impl<'a> DefaultProcessor<'a> { - pub fn new( - matchers: &'a [&'a dyn Matcher<'a, MatcherState>], - match_filter: &'a dyn MatchFilter, - match_selector: &'a dyn MatchSelector, - multiplexer: &'a dyn Multiplexer, - renderer: &'a dyn Renderer<'a>, - match_info_provider: &'a dyn MatchInfoProvider, - modifier_status_provider: &'a dyn ModifierStatusProvider, - event_sequence_provider: &'a dyn EventSequenceProvider, - path_provider: &'a dyn PathProvider, - disable_options: DisableOptions, - matcher_options_provider: &'a dyn MatcherMiddlewareConfigProvider, - match_provider: &'a dyn MatchProvider, - ) -> DefaultProcessor<'a> { - Self { - event_queue: VecDeque::new(), - middleware: vec![ - Box::new(PastEventsDiscardMiddleware::new()), - Box::new(DisableMiddleware::new(disable_options)), - Box::new(IconStatusMiddleware::new()), - Box::new(MatcherMiddleware::new(matchers, matcher_options_provider)), - Box::new(ContextMenuMiddleware::new()), - Box::new(HotKeyMiddleware::new()), - Box::new(MatchSelectMiddleware::new(match_filter, match_selector)), - Box::new(CauseCompensateMiddleware::new()), - Box::new(MultiplexMiddleware::new(multiplexer)), - Box::new(RenderMiddleware::new(renderer)), - Box::new(ImageResolverMiddleware::new(path_provider)), - Box::new(CursorHintMiddleware::new()), - Box::new(ExitMiddleware::new()), - Box::new(ActionMiddleware::new(match_info_provider, event_sequence_provider)), - Box::new(SearchMiddleware::new(match_provider)), - Box::new(MarkdownMiddleware::new()), - Box::new(DelayForModifierReleaseMiddleware::new(modifier_status_provider)), - ], - } - } - - fn process_one(&mut self) -> Option { - if let Some(event) = self.event_queue.pop_back() { - let mut current_event = event; - - let mut current_queue = VecDeque::new(); - let mut dispatch = |event: Event| { - trace!("dispatched event: {:?}", event); - current_queue.push_front(event); - }; - - trace!("--------------- new event -----------------"); - for middleware in self.middleware.iter() { - trace!("middleware '{}' received event: {:?}", middleware.name(), current_event); - - current_event = middleware.next(current_event, &mut dispatch); - - trace!("middleware '{}' produced event: {:?}", middleware.name(), current_event); - - if let EventType::NOOP = current_event.etype { - trace!("interrupting chain as the event is NOOP"); - break; - } - } - - while let Some(event) = current_queue.pop_back() { - self.event_queue.push_front(event); - } - - Some(current_event) - } else { - None - } - } -} - -impl<'a> Processor for DefaultProcessor<'a> { - fn process(&mut self, event: Event) -> Vec { - self.event_queue.push_front(event); - - let mut processed_events = Vec::new(); - - while !self.event_queue.is_empty() { - if let Some(event) = self.process_one() { - processed_events.push(event); - } - } - - processed_events - } -} diff --git a/espanso/src/engine/process/middleware/action.rs b/espanso/src/engine/process/middleware/action.rs deleted file mode 100644 index d1c96d8..0000000 --- a/espanso/src/engine/process/middleware/action.rs +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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 super::super::Middleware; -use crate::engine::event::{ - effect::{ - HtmlInjectRequest, ImageInjectRequest, KeySequenceInjectRequest, MarkdownInjectRequest, - TextInjectMode, TextInjectRequest, - }, - input::Key, - internal::{DiscardPreviousEvent, TextFormat}, - Event, EventType, -}; - -pub trait MatchInfoProvider { - fn get_force_mode(&self, match_id: i32) -> Option; -} - -pub trait EventSequenceProvider { - fn get_next_id(&self) -> u32; -} - -pub struct ActionMiddleware<'a> { - match_info_provider: &'a dyn MatchInfoProvider, - event_sequence_provider: &'a dyn EventSequenceProvider, -} - -impl<'a> ActionMiddleware<'a> { - pub fn new( - match_info_provider: &'a dyn MatchInfoProvider, - event_sequence_provider: &'a dyn EventSequenceProvider, - ) -> Self { - Self { - match_info_provider, - event_sequence_provider, - } - } -} - -impl<'a> Middleware for ActionMiddleware<'a> { - fn name(&self) -> &'static str { - "action" - } - - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event { - match &event.etype { - EventType::Rendered(_) | EventType::ImageResolved(_) => { - dispatch(Event::caused_by(event.source_id, EventType::MatchInjected)); - dispatch(Event::caused_by( - event.source_id, - EventType::DiscardPrevious(DiscardPreviousEvent { - minimum_source_id: self.event_sequence_provider.get_next_id(), - }), - )); - - match &event.etype { - EventType::Rendered(m_event) => Event::caused_by( - event.source_id, - match m_event.format { - TextFormat::Plain => EventType::TextInject(TextInjectRequest { - text: m_event.body.clone(), - force_mode: self.match_info_provider.get_force_mode(m_event.match_id), - }), - TextFormat::Html => EventType::HtmlInject(HtmlInjectRequest { - html: m_event.body.clone(), - }), - TextFormat::Markdown => EventType::MarkdownInject(MarkdownInjectRequest { - markdown: m_event.body.clone(), - }), - }, - ), - EventType::ImageResolved(m_event) => Event::caused_by( - event.source_id, - EventType::ImageInject(ImageInjectRequest { - image_path: m_event.image_path.clone(), - }), - ), - _ => unreachable!() - } - } - EventType::CursorHintCompensation(m_event) => { - dispatch(Event::caused_by( - event.source_id, - EventType::DiscardPrevious(DiscardPreviousEvent { - minimum_source_id: self.event_sequence_provider.get_next_id(), - }), - )); - - Event::caused_by( - event.source_id, - EventType::KeySequenceInject(KeySequenceInjectRequest { - keys: (0..m_event.cursor_hint_back_count) - .map(|_| Key::ArrowLeft) - .collect(), - }), - ) - } - EventType::TriggerCompensation(m_event) => { - let mut backspace_count = m_event.trigger.chars().count(); - - // We want to preserve the left separator if present - if let Some(left_separator) = &m_event.left_separator { - backspace_count -= left_separator.chars().count(); - } - - Event::caused_by( - event.source_id, - EventType::KeySequenceInject(KeySequenceInjectRequest { - keys: (0..backspace_count).map(|_| Key::Backspace).collect(), - }), - ) - } - _ => event, - } - - // TODO: handle images - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/cause.rs b/espanso/src/engine/process/middleware/cause.rs deleted file mode 100644 index cb1f357..0000000 --- a/espanso/src/engine/process/middleware/cause.rs +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 super::super::Middleware; -use crate::engine::{event::{Event, EventType, effect::TriggerCompensationEvent, internal::CauseCompensatedMatchEvent}}; - -pub struct CauseCompensateMiddleware {} - -impl CauseCompensateMiddleware { - pub fn new() -> Self { - Self {} - } -} - -impl Middleware for CauseCompensateMiddleware { - fn name(&self) -> &'static str { - "cause_compensate" - } - - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event { - if let EventType::MatchSelected(m_event) = &event.etype { - let compensated_event = - Event::caused_by(event.source_id, EventType::CauseCompensatedMatch(CauseCompensatedMatchEvent { m: m_event.chosen.clone() })); - - if let Some(trigger) = &m_event.chosen.trigger { - dispatch(compensated_event); - - // Before the event, place a trigger compensation - return Event::caused_by(event.source_id, EventType::TriggerCompensation(TriggerCompensationEvent { - trigger: trigger.clone(), - left_separator: m_event.chosen.left_separator.clone(), - })); - } else { - return compensated_event; - } - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/context_menu.rs b/espanso/src/engine/process/middleware/context_menu.rs deleted file mode 100644 index f4109ce..0000000 --- a/espanso/src/engine/process/middleware/context_menu.rs +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of espanso. - * - * Copyright id: (), label: () id: (), label: () id: (), label: ()(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 std::cell::RefCell; - -use super::super::Middleware; -use crate::engine::event::{ - ui::{MenuItem, ShowContextMenuEvent, SimpleMenuItem}, - Event, EventType, ExitMode, -}; - -const CONTEXT_ITEM_EXIT: u32 = 0; -const CONTEXT_ITEM_RELOAD: u32 = 1; -const CONTEXT_ITEM_ENABLE: u32 = 2; -const CONTEXT_ITEM_DISABLE: u32 = 3; -const CONTEXT_ITEM_SECURE_INPUT_EXPLAIN: u32 = 4; -const CONTEXT_ITEM_SECURE_INPUT_TRIGGER_WORKAROUND: u32 = 5; -const CONTEXT_ITEM_OPEN_SEARCH: u32 = 6; - -pub struct ContextMenuMiddleware { - is_enabled: RefCell, - is_secure_input_enabled: RefCell, -} - -impl ContextMenuMiddleware { - pub fn new() -> Self { - Self { - is_enabled: RefCell::new(true), - is_secure_input_enabled: RefCell::new(false), - } - } -} - -impl Middleware for ContextMenuMiddleware { - fn name(&self) -> &'static str { - "context_menu" - } - - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event { - let mut is_enabled = self.is_enabled.borrow_mut(); - let mut is_secure_input_enabled = self.is_secure_input_enabled.borrow_mut(); - - match &event.etype { - EventType::TrayIconClicked => { - // TODO: fetch top matches for the active config to be added - - let mut items = vec![ - MenuItem::Simple(if *is_enabled { - SimpleMenuItem { - id: CONTEXT_ITEM_DISABLE, - label: "Disable".to_string(), - } - } else { - SimpleMenuItem { - id: CONTEXT_ITEM_ENABLE, - label: "Enable".to_string(), - } - }), - MenuItem::Simple(SimpleMenuItem { - id: CONTEXT_ITEM_OPEN_SEARCH, - label: "Open search bar".to_string(), - }), - MenuItem::Separator, - MenuItem::Simple(SimpleMenuItem { - id: CONTEXT_ITEM_RELOAD, - label: "Reload config".to_string(), - }), - MenuItem::Separator, - MenuItem::Simple(SimpleMenuItem { - id: CONTEXT_ITEM_EXIT, - label: "Exit espanso".to_string(), - }), - ]; - - if *is_secure_input_enabled { - items.insert(0, MenuItem::Simple(SimpleMenuItem { - id: CONTEXT_ITEM_SECURE_INPUT_EXPLAIN, - label: "Why is espanso not working?".to_string(), - })); - items.insert(1, MenuItem::Simple(SimpleMenuItem { - id: CONTEXT_ITEM_SECURE_INPUT_TRIGGER_WORKAROUND, - label: "Launch SecureInput auto-fix".to_string(), - })); - items.insert(2, MenuItem::Separator); - } - - // TODO: my idea is to use a set of reserved u32 ids for built-in - // actions such as Exit, Open Editor etc - // then we need some u32 for the matches, so we need to create - // a mapping structure match_id <-> context-menu-id - return Event::caused_by( - event.source_id, - EventType::ShowContextMenu(ShowContextMenuEvent { - // TODO: add actual entries - items, - }), - ); - } - EventType::ContextMenuClicked(context_click_event) => { - match context_click_event.context_item_id { - CONTEXT_ITEM_EXIT => Event::caused_by( - event.source_id, - EventType::ExitRequested(ExitMode::ExitAllProcesses), - ), - CONTEXT_ITEM_RELOAD => Event::caused_by( - event.source_id, - EventType::ExitRequested(ExitMode::RestartWorker), - ), - CONTEXT_ITEM_ENABLE => { - dispatch(Event::caused_by(event.source_id, EventType::EnableRequest)); - Event::caused_by(event.source_id, EventType::NOOP) - } - CONTEXT_ITEM_DISABLE => { - dispatch(Event::caused_by(event.source_id, EventType::DisableRequest)); - Event::caused_by(event.source_id, EventType::NOOP) - } - CONTEXT_ITEM_SECURE_INPUT_EXPLAIN => { - dispatch(Event::caused_by(event.source_id, EventType::DisplaySecureInputTroubleshoot)); - Event::caused_by(event.source_id, EventType::NOOP) - } - CONTEXT_ITEM_SECURE_INPUT_TRIGGER_WORKAROUND => { - dispatch(Event::caused_by(event.source_id, EventType::LaunchSecureInputAutoFix)); - Event::caused_by(event.source_id, EventType::NOOP) - } - CONTEXT_ITEM_OPEN_SEARCH => { - dispatch(Event::caused_by(event.source_id, EventType::ShowSearchBar)); - Event::caused_by(event.source_id, EventType::NOOP) - } - custom => { - // TODO: handle dynamic items - todo!() - } - } - } - EventType::Disabled => { - *is_enabled = false; - event - } - EventType::Enabled => { - *is_enabled = true; - event - } - EventType::SecureInputEnabled(_) => { - *is_secure_input_enabled = true; - event - } - EventType::SecureInputDisabled => { - *is_secure_input_enabled = false; - event - } - _ => event, - } - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/cursor_hint.rs b/espanso/src/engine/process/middleware/cursor_hint.rs deleted file mode 100644 index 603150e..0000000 --- a/espanso/src/engine/process/middleware/cursor_hint.rs +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 super::super::Middleware; -use crate::engine::{event::{Event, EventType, effect::CursorHintCompensationEvent, internal::RenderedEvent}}; - -pub struct CursorHintMiddleware {} - -impl CursorHintMiddleware { - pub fn new() -> Self { - Self {} - } -} - -impl Middleware for CursorHintMiddleware { - fn name(&self) -> &'static str { - "cursor_hint" - } - - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event { - if let EventType::Rendered(m_event) = event.etype { - let (body, cursor_hint_back_count) = process_cursor_hint(m_event.body); - - if let Some(cursor_hint_back_count) = cursor_hint_back_count { - dispatch(Event::caused_by(event.source_id, EventType::CursorHintCompensation(CursorHintCompensationEvent { - cursor_hint_back_count, - }))); - } - - // Alter the rendered event to remove the cursor hint from the body - return Event::caused_by(event.source_id, EventType::Rendered(RenderedEvent { - body, - ..m_event - })); - } - - event - } -} - -// TODO: test -fn process_cursor_hint(body: String) -> (String, Option) { - if let Some(index) = body.find("$|$") { - // Convert the byte index to a char index - let char_str = &body[0..index]; - let char_index = char_str.chars().count(); - let total_size = body.chars().count(); - - // Remove the $|$ placeholder - let body = body.replace("$|$", ""); - - // Calculate the amount of rewind moves needed (LEFT ARROW). - // Subtract also 3, equal to the number of chars of the placeholder "$|$" - let moves = total_size - char_index - 3; - (body, Some(moves)) - } else { - (body, None) - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/delay_modifiers.rs b/espanso/src/engine/process/middleware/delay_modifiers.rs deleted file mode 100644 index a35d681..0000000 --- a/espanso/src/engine/process/middleware/delay_modifiers.rs +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 std::{ - time::{Duration, Instant}, -}; - -use log::{trace, warn}; - -use super::super::Middleware; -use crate::engine::event::{Event, EventType}; - -/// Maximum time to wait for modifiers being released before -/// giving up. -const MODIFIER_DELAY_TIMEOUT: Duration = Duration::from_secs(3); - -pub trait ModifierStatusProvider { - fn is_any_conflicting_modifier_pressed(&self) -> bool; -} - -/// This middleware is used to delay the injection of text until -/// all modifiers have been released. This is needed as otherwise, -/// injections might misbehave as pressed modifiers might alter -/// the keys being injected. -pub struct DelayForModifierReleaseMiddleware<'a> { - provider: &'a dyn ModifierStatusProvider, -} - -impl <'a> DelayForModifierReleaseMiddleware<'a> { - pub fn new(provider: &'a dyn ModifierStatusProvider) -> Self { - Self { - provider - } - } -} - -impl <'a> Middleware for DelayForModifierReleaseMiddleware<'a> { - fn name(&self) -> &'static str { - "delay_modifiers" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if is_injection_event(&event.etype) { - let start = Instant::now(); - while self.provider.is_any_conflicting_modifier_pressed() { - if Instant::now().duration_since(start) > MODIFIER_DELAY_TIMEOUT { - warn!("injection delay has timed out, please release the modifier keys (SHIFT, CTRL, ALT, CMD) to trigger an expansion"); - break; - } - - // TODO: here we might show a popup window to tell the users to release those keys - - trace!("delaying injection event as some modifiers are pressed"); - std::thread::sleep(Duration::from_millis(100)); - } - } - - event - } -} - -fn is_injection_event(event_type: &EventType) -> bool { - match event_type { - EventType::TriggerCompensation(_) => true, - EventType::CursorHintCompensation(_) => true, - EventType::KeySequenceInject(_) => true, - EventType::TextInject(_) => true, - _ => false, - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/disable.rs b/espanso/src/engine/process/middleware/disable.rs deleted file mode 100644 index 0a7c01f..0000000 --- a/espanso/src/engine/process/middleware/disable.rs +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 std::{ - cell::RefCell, - time::{Duration, Instant}, -}; - -use log::info; - -use super::super::Middleware; -use crate::engine::event::{ - input::{Key, KeyboardEvent, Status, Variant}, - Event, EventType, -}; - -pub struct DisableOptions { - pub toggle_key: Option, - pub toggle_key_variant: Option, - pub toggle_key_maximum_window: Duration, - // TODO: toggle shortcut? -} - -pub struct DisableMiddleware { - enabled: RefCell, - last_toggle_press: RefCell>, - options: DisableOptions, -} - -impl DisableMiddleware { - pub fn new(options: DisableOptions) -> Self { - Self { - enabled: RefCell::new(true), - last_toggle_press: RefCell::new(None), - options, - } - } -} - -impl Middleware for DisableMiddleware { - fn name(&self) -> &'static str { - "disable" - } - - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event { - let mut has_status_changed = false; - let mut enabled = self.enabled.borrow_mut(); - - match &event.etype { - EventType::Keyboard(m_event) => { - if is_toggle_key(m_event, &self.options) { - let mut last_toggle_press = self.last_toggle_press.borrow_mut(); - if let Some(previous_press) = *last_toggle_press { - if previous_press.elapsed() < self.options.toggle_key_maximum_window { - *enabled = !*enabled; - *last_toggle_press = None; - has_status_changed = true; - } else { - *last_toggle_press = Some(Instant::now()); - } - } else { - *last_toggle_press = Some(Instant::now()); - } - } - }, - EventType::EnableRequest => { - *enabled = true; - has_status_changed = true; - }, - EventType::DisableRequest => { - *enabled = false; - has_status_changed = true; - } - _ => {} - } - - if has_status_changed { - info!("toggled enabled state, is_enabled = {}", *enabled); - dispatch(Event::caused_by( - event.source_id, - if *enabled { - EventType::Enabled - } else { - EventType::Disabled - }, - )) - } - - // Block keyboard events when disabled - if let EventType::Keyboard(_) = &event.etype { - if !*enabled { - return Event::caused_by(event.source_id, EventType::NOOP); - } - } - // TODO: also ignore hotkey and mouse events - - event - } -} - -fn is_toggle_key(event: &KeyboardEvent, options: &DisableOptions) -> bool { - if event.status != Status::Released { - return false; - } - - if options - .toggle_key - .as_ref() - .map(|key| key == &event.key) - .unwrap_or(false) - { - if let (Some(variant), Some(e_variant)) = (&options.toggle_key_variant, &event.variant) { - variant == e_variant - } else { - true - } - } else { - false - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/exit.rs b/espanso/src/engine/process/middleware/exit.rs deleted file mode 100644 index 205b5f1..0000000 --- a/espanso/src/engine/process/middleware/exit.rs +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 log::debug; - -use super::super::Middleware; -use crate::engine::{event::{Event, EventType}}; - -pub struct ExitMiddleware {} - -impl ExitMiddleware { - pub fn new() -> Self { - Self {} - } -} - -impl Middleware for ExitMiddleware { - fn name(&self) -> &'static str { - "exit" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if let EventType::ExitRequested(mode) = &event.etype { - debug!("received ExitRequested event with mode: {:?}, dispatching exit", mode); - return Event::caused_by(event.source_id, EventType::Exit(mode.clone())); - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/hotkey.rs b/espanso/src/engine/process/middleware/hotkey.rs deleted file mode 100644 index 1a42d80..0000000 --- a/espanso/src/engine/process/middleware/hotkey.rs +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of espanso id: (), trigger: (), trigger: (), left_separator: (), right_separator: (), args: () left_separator: (), right_separator: (), args: () id: (), trigger: (), left_separator: (), right_separator: (), args: (). - * - * 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 super::super::Middleware; -use crate::engine::{event::{Event, EventType, internal::{DetectedMatch, MatchesDetectedEvent}}}; - -pub struct HotKeyMiddleware {} - -impl HotKeyMiddleware { - pub fn new() -> Self { - Self {} - } -} - -impl Middleware for HotKeyMiddleware { - fn name(&self) -> &'static str { - "hotkey" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if let EventType::HotKey(m_event) = &event.etype { - return Event::caused_by(event.source_id, EventType::MatchesDetected(MatchesDetectedEvent { - matches: vec![ - DetectedMatch { - id: m_event.hotkey_id, - ..Default::default() - } - ], - })); - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/icon_status.rs b/espanso/src/engine/process/middleware/icon_status.rs deleted file mode 100644 index 67ae4ba..0000000 --- a/espanso/src/engine/process/middleware/icon_status.rs +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 std::{ - cell::RefCell, -}; - -use super::super::Middleware; -use crate::engine::event::{Event, EventType, ui::{IconStatus, IconStatusChangeEvent}}; - -pub struct IconStatusMiddleware { - enabled: RefCell, - secure_input_enabled: RefCell, -} - -impl IconStatusMiddleware { - pub fn new() -> Self { - Self { - enabled: RefCell::new(true), - secure_input_enabled: RefCell::new(false), - } - } -} - -impl Middleware for IconStatusMiddleware { - fn name(&self) -> &'static str { - "icon_status" - } - - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event { - let mut enabled = self.enabled.borrow_mut(); - let mut secure_input_enabled = self.secure_input_enabled.borrow_mut(); - - let mut did_update = true; - match &event.etype { - EventType::Enabled => *enabled = true, - EventType::Disabled => *enabled = false, - EventType::SecureInputEnabled(_) => *secure_input_enabled = true, - EventType::SecureInputDisabled => *secure_input_enabled = false, - _ => did_update = false, - } - - if did_update { - let status = if *enabled { - if *secure_input_enabled { - IconStatus::SecureInputDisabled - } else { - IconStatus::Enabled - } - } else { - IconStatus::Disabled - }; - - dispatch(Event::caused_by(event.source_id, EventType::IconStatusChange(IconStatusChangeEvent { - status, - }))); - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/image_resolve.rs b/espanso/src/engine/process/middleware/image_resolve.rs deleted file mode 100644 index 7710611..0000000 --- a/espanso/src/engine/process/middleware/image_resolve.rs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 std::{ - path::Path, -}; - -use log::{error}; - -use super::super::Middleware; -use crate::engine::event::{Event, EventType, internal::ImageResolvedEvent}; - -pub trait PathProvider { - fn get_config_path(&self) -> &Path; -} - -pub struct ImageResolverMiddleware<'a> { - provider: &'a dyn PathProvider, -} - -impl<'a> ImageResolverMiddleware<'a> { - pub fn new(provider: &'a dyn PathProvider) -> Self { - Self { provider } - } -} - -impl<'a> Middleware for ImageResolverMiddleware<'a> { - fn name(&self) -> &'static str { - "image_resolve" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if let EventType::ImageRequested(m_event) = &event.etype { - // On Windows, we have to replace the forward / with the backslash \ in the path - let path = if cfg!(target_os = "windows") { - m_event.image_path.replace("/", "\\") - } else { - m_event.image_path.to_owned() - }; - - let path = if path.contains("$CONFIG") { - let config_path = match self.provider.get_config_path().canonicalize() { - Ok(path) => path, - Err(err) => { - error!("unable to canonicalize the config path into the image resolver: {}", err); - self.provider.get_config_path().to_owned() - }, - }; - path.replace("$CONFIG", &config_path.to_string_lossy()) - } else { - path - }; - - return Event::caused_by(event.source_id, EventType::ImageResolved(ImageResolvedEvent { - image_path: path, - })) - } - - - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/markdown.rs b/espanso/src/engine/process/middleware/markdown.rs deleted file mode 100644 index 7ba0d8e..0000000 --- a/espanso/src/engine/process/middleware/markdown.rs +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 super::super::Middleware; -use crate::engine::event::{Event, EventType, effect::{HtmlInjectRequest}}; - -// Convert markdown injection requests to HTML on the fly -pub struct MarkdownMiddleware {} - -impl MarkdownMiddleware { - pub fn new() -> Self { - Self {} - } -} - -impl Middleware for MarkdownMiddleware { - fn name(&self) -> &'static str { - "markdown" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if let EventType::MarkdownInject(m_event) = &event.etype { - // Render the markdown into HTML - let html = markdown::to_html(&m_event.markdown); - let mut html = html.trim(); - - // Remove the surrounding paragraph - if html.starts_with("

") { - html = html.trim_start_matches("

"); - } - if html.ends_with("

") { - html = html.trim_end_matches("

"); - } - - return Event::caused_by(event.source_id, EventType::HtmlInject(HtmlInjectRequest { - html: html.to_owned(), - })) - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/match_select.rs b/espanso/src/engine/process/middleware/match_select.rs deleted file mode 100644 index 6929e63..0000000 --- a/espanso/src/engine/process/middleware/match_select.rs +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 log::{debug, error}; - -use super::super::Middleware; -use crate::engine::{event::{Event, EventType, internal::{MatchSelectedEvent}}, process::{MatchFilter, MatchSelector}}; - -pub struct MatchSelectMiddleware<'a> { - match_filter: &'a dyn MatchFilter, - match_selector: &'a dyn MatchSelector, -} - -impl<'a> MatchSelectMiddleware<'a> { - pub fn new(match_filter: &'a dyn MatchFilter, match_selector: &'a dyn MatchSelector) -> Self { - Self { - match_filter, - match_selector, - } - } -} - -impl<'a> Middleware for MatchSelectMiddleware<'a> { - fn name(&self) -> &'static str { - "match_select" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if let EventType::MatchesDetected(m_event) = event.etype { - let matches_ids: Vec = m_event.matches.iter().map(|m| m.id).collect(); - - // Find the matches that are actually valid in the current context - let valid_ids = self.match_filter.filter_active(&matches_ids); - - return match valid_ids.len() { - 0 => Event::caused_by(event.source_id, EventType::NOOP), // No valid matches, consume the event - 1 => { - // Only one match, no need to show a selection dialog - let m = m_event - .matches - .into_iter() - .find(|m| m.id == *valid_ids.first().unwrap()); - if let Some(m) = m { - Event::caused_by(event.source_id, EventType::MatchSelected(MatchSelectedEvent { chosen: m })) - } else { - error!("MatchSelectMiddleware could not find the correspondent match"); - Event::caused_by(event.source_id, EventType::NOOP) - } - } - _ => { - // Multiple matches, we need to ask the user which one to use - if let Some(selected_id) = self.match_selector.select(&valid_ids) { - let m = m_event - .matches - .into_iter() - .find(|m| m.id == selected_id); - if let Some(m) = m { - Event::caused_by(event.source_id, EventType::MatchSelected(MatchSelectedEvent { chosen: m })) - } else { - error!("MatchSelectMiddleware could not find the correspondent match"); - Event::caused_by(event.source_id, EventType::NOOP) - } - } else { - debug!("MatchSelectMiddleware did not receive any match selection"); - Event::caused_by(event.source_id, EventType::NOOP) - } - } - }; - } - - event - } -} - -// TODO: test \ No newline at end of file diff --git a/espanso/src/engine/process/middleware/matcher.rs b/espanso/src/engine/process/middleware/matcher.rs deleted file mode 100644 index 6d54c52..0000000 --- a/espanso/src/engine/process/middleware/matcher.rs +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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 log::trace; -use std::{cell::RefCell, collections::VecDeque}; - -use super::super::Middleware; -use crate::engine::{ - event::{ - input::{Key, Status}, - internal::{DetectedMatch, MatchesDetectedEvent}, - Event, EventType, - }, - process::{Matcher, MatcherEvent}, -}; - -pub trait MatcherMiddlewareConfigProvider { - fn max_history_size(&self) -> usize; -} - -pub struct MatcherMiddleware<'a, State> { - matchers: &'a [&'a dyn Matcher<'a, State>], - - matcher_states: RefCell>>, - - max_history_size: usize, -} - -impl<'a, State> MatcherMiddleware<'a, State> { - pub fn new(matchers: &'a [&'a dyn Matcher<'a, State>], options_provider: &'a dyn MatcherMiddlewareConfigProvider) -> Self { - let max_history_size = options_provider.max_history_size(); - - Self { - matchers, - matcher_states: RefCell::new(VecDeque::new()), - max_history_size, - } - } -} - -impl<'a, State> Middleware for MatcherMiddleware<'a, State> { - fn name(&self) -> &'static str { - "matcher" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if is_event_of_interest(&event.etype) { - let mut matcher_states = self.matcher_states.borrow_mut(); - let prev_states = if !matcher_states.is_empty() { - matcher_states.get(matcher_states.len() - 1) - } else { - None - }; - - if let EventType::Keyboard(keyboard_event) = &event.etype { - // Backspace handling - if keyboard_event.key == Key::Backspace { - trace!("popping the last matcher state"); - matcher_states.pop_back(); - return event; - } - } - - // Some keys (such as the arrow keys) and mouse clicks prevent espanso from building - // an accurate key buffer, so we need to invalidate it. - if is_invalidating_event(&event.etype) { - trace!("invalidating event detected, clearing matching state"); - matcher_states.clear(); - return event; - } - - let mut all_results = Vec::new(); - - if let Some(matcher_event) = convert_to_matcher_event(&event.etype) { - let mut new_states = Vec::new(); - for (i, matcher) in self.matchers.iter().enumerate() { - let prev_state = prev_states.and_then(|states| states.get(i)); - - let (state, results) = matcher.process(prev_state, &matcher_event); - all_results.extend(results); - - new_states.push(state); - } - - matcher_states.push_back(new_states); - if matcher_states.len() > self.max_history_size { - matcher_states.pop_front(); - } - - if !all_results.is_empty() { - return Event::caused_by( - event.source_id, - EventType::MatchesDetected(MatchesDetectedEvent { - matches: all_results - .into_iter() - .map(|result| DetectedMatch { - id: result.id, - trigger: Some(result.trigger), - right_separator: result.right_separator, - left_separator: result.left_separator, - args: result.args, - }) - .collect(), - }), - ); - } - } - } - - event - } -} - -fn is_event_of_interest(event_type: &EventType) -> bool { - match event_type { - EventType::Keyboard(keyboard_event) => { - if keyboard_event.status != Status::Pressed { - // Skip non-press events - false - } else { - match keyboard_event.key { - // Skip modifier keys - Key::Alt => false, - Key::Shift => false, - Key::CapsLock => false, - Key::Meta => false, - Key::NumLock => false, - Key::Control => false, - - _ => true, - } - } - } - EventType::Mouse(mouse_event) => mouse_event.status == Status::Pressed, - EventType::MatchInjected => true, - _ => false, - } -} - -fn convert_to_matcher_event(event_type: &EventType) -> Option { - match event_type { - EventType::Keyboard(keyboard_event) => Some(MatcherEvent::Key { - key: keyboard_event.key.clone(), - chars: keyboard_event.value.clone(), - }), - EventType::Mouse(_) => Some(MatcherEvent::VirtualSeparator), - EventType::MatchInjected => Some(MatcherEvent::VirtualSeparator), - _ => None, - } -} - -fn is_invalidating_event(event_type: &EventType) -> bool { - match event_type { - EventType::Keyboard(keyboard_event) => match keyboard_event.key { - Key::ArrowDown => true, - Key::ArrowLeft => true, - Key::ArrowRight => true, - Key::ArrowUp => true, - Key::End => true, - Key::Home => true, - Key::PageDown => true, - Key::PageUp => true, - Key::Escape => true, - _ => false, - }, - EventType::Mouse(_) => true, - _ => false, - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/mod.rs b/espanso/src/engine/process/middleware/mod.rs deleted file mode 100644 index d585c07..0000000 --- a/espanso/src/engine/process/middleware/mod.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 . - */ - -pub mod action; -pub mod cause; -pub mod context_menu; -pub mod cursor_hint; -pub mod delay_modifiers; -pub mod disable; -pub mod exit; -pub mod hotkey; -pub mod icon_status; -pub mod image_resolve; -pub mod match_select; -pub mod matcher; -pub mod markdown; -pub mod multiplex; -pub mod past_discard; -pub mod render; -pub mod search; diff --git a/espanso/src/engine/process/middleware/multiplex.rs b/espanso/src/engine/process/middleware/multiplex.rs deleted file mode 100644 index 41e4b83..0000000 --- a/espanso/src/engine/process/middleware/multiplex.rs +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 log::error; - -use super::super::Middleware; -use crate::engine::{ - event::{Event, EventType}, - process::Multiplexer, -}; - -pub struct MultiplexMiddleware<'a> { - multiplexer: &'a dyn Multiplexer, -} - -impl<'a> MultiplexMiddleware<'a> { - pub fn new(multiplexer: &'a dyn Multiplexer) -> Self { - Self { multiplexer } - } -} - -impl<'a> Middleware for MultiplexMiddleware<'a> { - fn name(&self) -> &'static str { - "multiplex" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if let EventType::CauseCompensatedMatch(m_event) = event.etype { - return match self.multiplexer.convert(m_event.m) { - Some(new_event) => Event::caused_by(event.source_id, new_event), - None => { - error!("match multiplexing failed"); - Event::caused_by(event.source_id, EventType::NOOP) - } - }; - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/past_discard.rs b/espanso/src/engine/process/middleware/past_discard.rs deleted file mode 100644 index c2ad8d7..0000000 --- a/espanso/src/engine/process/middleware/past_discard.rs +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 std::cell::RefCell; - -use log::trace; - -use super::super::Middleware; -use crate::engine::{event::{Event, EventType, SourceId}}; - -/// This middleware discards all events that have a source_id smaller than its -/// configured threshold. This useful to discard past events that might have -/// been stuck in the event queue for too long. -pub struct PastEventsDiscardMiddleware { - source_id_threshold: RefCell, -} - -impl PastEventsDiscardMiddleware { - pub fn new() -> Self { - Self { - source_id_threshold: RefCell::new(0), - } - } -} - -impl Middleware for PastEventsDiscardMiddleware { - fn name(&self) -> &'static str { - "past_discard" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - let mut source_id_threshold = self.source_id_threshold.borrow_mut(); - - // Filter out previous events - if event.source_id < *source_id_threshold { - trace!("discarding previous event: {:?}", event); - return Event::caused_by(event.source_id, EventType::NOOP); - } - - // Update the minimum threshold - if let EventType::DiscardPrevious(m_event) = &event.etype { - trace!("updating minimum source id threshold for events to: {}", m_event.minimum_source_id); - *source_id_threshold = m_event.minimum_source_id; - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/render.rs b/espanso/src/engine/process/middleware/render.rs deleted file mode 100644 index 128e0b4..0000000 --- a/espanso/src/engine/process/middleware/render.rs +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 log::error; - -use super::super::Middleware; -use crate::engine::{ - event::{ - internal::RenderedEvent, - Event, EventType, - }, - process::{Renderer, RendererError}, -}; - -pub struct RenderMiddleware<'a> { - renderer: &'a dyn Renderer<'a>, -} - -impl<'a> RenderMiddleware<'a> { - pub fn new(renderer: &'a dyn Renderer<'a>) -> Self { - Self { renderer } - } -} - -impl<'a> Middleware for RenderMiddleware<'a> { - fn name(&self) -> &'static str { - "render" - } - - fn next(&self, event: Event, _: &mut dyn FnMut(Event)) -> Event { - if let EventType::RenderingRequested(m_event) = event.etype { - match self.renderer.render( - m_event.match_id, - m_event.trigger.as_deref(), - m_event.trigger_args, - ) { - Ok(body) => { - let body = if let Some(right_separator) = m_event.right_separator { - format!("{}{}", body, right_separator) - } else { - body - }; - - return Event::caused_by( - event.source_id, - EventType::Rendered(RenderedEvent { - match_id: m_event.match_id, - body, - format: m_event.format, - }), - ); - } - Err(err) => match err.downcast_ref::() { - Some(RendererError::Aborted) => return Event::caused_by(event.source_id, EventType::NOOP), - _ => { - error!("error during rendering: {}", err); - return Event::caused_by(event.source_id, EventType::ProcessingError("An error has occurred during rendering, please examine the logs or contact support.".to_string())); - } - }, - } - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/middleware/search.rs b/espanso/src/engine/process/middleware/search.rs deleted file mode 100644 index 90becca..0000000 --- a/espanso/src/engine/process/middleware/search.rs +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 std::collections::HashMap; - -use super::super::Middleware; -use crate::engine::{event::{ - internal::{DetectedMatch, MatchesDetectedEvent}, - Event, EventType, - }}; - -pub trait MatchProvider { - fn get_all_matches_ids(&self) -> Vec; -} - -pub struct SearchMiddleware<'a> { - match_provider: &'a dyn MatchProvider, -} - -impl<'a> SearchMiddleware<'a> { - pub fn new(match_provider: &'a dyn MatchProvider) -> Self { - Self { match_provider } - } -} - -impl<'a> Middleware for SearchMiddleware<'a> { - fn name(&self) -> &'static str { - "search" - } - - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event { - if let EventType::ShowSearchBar = event.etype { - let detected_matches = Event::caused_by( - event.source_id, - EventType::MatchesDetected(MatchesDetectedEvent { - matches: self - .match_provider - .get_all_matches_ids() - .into_iter() - .map(|id| DetectedMatch { - id, - trigger: None, - left_separator: None, - right_separator: None, - args: HashMap::new(), - }) - .collect(), - }), - ); - dispatch(detected_matches); - - return Event::caused_by(event.source_id, EventType::NOOP); - } - - event - } -} - -// TODO: test diff --git a/espanso/src/engine/process/mod.rs b/espanso/src/engine/process/mod.rs deleted file mode 100644 index 9c3f26a..0000000 --- a/espanso/src/engine/process/mod.rs +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 super::{Event, event::{EventType, input::Key, internal::DetectedMatch}}; -use anyhow::Result; -use std::collections::HashMap; -use thiserror::Error; - -mod default; -mod middleware; - -pub trait Middleware { - fn name(&self) -> &'static str; - fn next(&self, event: Event, dispatch: &mut dyn FnMut(Event)) -> Event; -} - -pub trait Processor { - fn process(&mut self, event: Event) -> Vec; -} - -// Dependency inversion entities - -// TODO: move these traits inside the various modules and then re-export it - -pub trait Matcher<'a, State> { - fn process( - &'a self, - prev_state: Option<&State>, - event: &MatcherEvent, - ) -> (State, Vec); -} - -#[derive(Debug)] -pub enum MatcherEvent { - Key { key: Key, chars: Option }, - VirtualSeparator, -} - -#[derive(Debug, Clone, PartialEq)] -pub struct MatchResult { - pub id: i32, - pub trigger: String, - pub left_separator: Option, - pub right_separator: Option, - pub args: HashMap, -} - -pub trait MatchFilter { - fn filter_active(&self, matches_ids: &[i32]) -> Vec; -} - -pub trait MatchSelector { - fn select(&self, matches_ids: &[i32]) -> Option; -} - -pub trait Multiplexer { - fn convert( - &self, - m: DetectedMatch, - ) -> Option; -} - -pub trait Renderer<'a> { - fn render(&'a self, match_id: i32, trigger: Option<&str>, trigger_args: HashMap) -> Result; -} - -#[derive(Error, Debug)] -pub enum RendererError { - #[error("rendering error")] - RenderingError(#[from] anyhow::Error), - - #[error("match not found")] - NotFound, - - #[error("aborted")] - Aborted, -} - -pub use middleware::action::{MatchInfoProvider, EventSequenceProvider}; -pub use middleware::delay_modifiers::ModifierStatusProvider; -pub use middleware::image_resolve::PathProvider; -pub use middleware::disable::DisableOptions; -pub use middleware::matcher::MatcherMiddlewareConfigProvider; -pub use middleware::search::MatchProvider; - -pub fn default<'a, MatcherState>( - matchers: &'a [&'a dyn Matcher<'a, MatcherState>], - match_filter: &'a dyn MatchFilter, - match_selector: &'a dyn MatchSelector, - multiplexer: &'a dyn Multiplexer, - renderer: &'a dyn Renderer<'a>, - match_info_provider: &'a dyn MatchInfoProvider, - modifier_status_provider: &'a dyn ModifierStatusProvider, - event_sequence_provider: &'a dyn EventSequenceProvider, - path_provider: &'a dyn PathProvider, - disable_options: DisableOptions, - matcher_options_provider: &'a dyn MatcherMiddlewareConfigProvider, - match_provider: &'a dyn MatchProvider, -) -> impl Processor + 'a { - default::DefaultProcessor::new( - matchers, - match_filter, - match_selector, - multiplexer, - renderer, - match_info_provider, - modifier_status_provider, - event_sequence_provider, - path_provider, - disable_options, - matcher_options_provider, - match_provider, - ) -} diff --git a/espanso/src/main.rs b/espanso/src/main.rs index 0a1f90c..356d59a 100644 --- a/espanso/src/main.rs +++ b/espanso/src/main.rs @@ -42,7 +42,6 @@ mod capabilities; mod cli; mod common_flags; mod config; -mod engine; mod exit_code; mod gui; mod icon;