diff --git a/espanso-engine/src/event/internal.rs b/espanso-engine/src/event/internal.rs
index 872a7ce..0ffb83d 100644
--- a/espanso-engine/src/event/internal.rs
+++ b/espanso-engine/src/event/internal.rs
@@ -89,3 +89,10 @@ pub struct SecureInputEnabledEvent {
pub app_name: String,
pub app_path: String,
}
+
+#[derive(Debug, Clone, PartialEq)]
+pub struct UndoEvent {
+ pub match_id: i32,
+ pub trigger: String,
+ pub replace: String,
+}
\ No newline at end of file
diff --git a/espanso-engine/src/event/mod.rs b/espanso-engine/src/event/mod.rs
index 5d9c53f..f43eb96 100644
--- a/espanso-engine/src/event/mod.rs
+++ b/espanso-engine/src/event/mod.rs
@@ -71,6 +71,7 @@ pub enum EventType {
ImageResolved(internal::ImageResolvedEvent),
MatchInjected,
DiscardPrevious(internal::DiscardPreviousEvent),
+ Undo(internal::UndoEvent),
Disabled,
Enabled,
diff --git a/espanso-engine/src/process/default.rs b/espanso-engine/src/process/default.rs
index 95e42f5..36670b8 100644
--- a/espanso-engine/src/process/default.rs
+++ b/espanso-engine/src/process/default.rs
@@ -19,8 +19,7 @@
use log::trace;
-use super::{
- middleware::{
+use super::{DisableOptions, MatchFilter, MatchInfoProvider, MatchProvider, MatchSelector, Matcher, MatcherMiddlewareConfigProvider, Middleware, Multiplexer, PathProvider, Processor, Renderer, UndoEnabledProvider, middleware::{
action::{ActionMiddleware, EventSequenceProvider},
cause::CauseCompensateMiddleware,
cursor_hint::CursorHintMiddleware,
@@ -31,18 +30,8 @@ use super::{
multiplex::MultiplexMiddleware,
past_discard::PastEventsDiscardMiddleware,
render::RenderMiddleware,
- },
- DisableOptions, MatchFilter, MatchInfoProvider, MatchProvider, MatchSelector, Matcher,
- MatcherMiddlewareConfigProvider, Middleware, Multiplexer, PathProvider, Processor, Renderer,
-};
-use crate::{
- event::{Event, EventType},
- process::middleware::{
- context_menu::ContextMenuMiddleware, disable::DisableMiddleware, exit::ExitMiddleware,
- hotkey::HotKeyMiddleware, icon_status::IconStatusMiddleware,
- image_resolve::ImageResolverMiddleware, search::SearchMiddleware,
- },
-};
+ }};
+use crate::{event::{Event, EventType}, process::middleware::{context_menu::ContextMenuMiddleware, disable::DisableMiddleware, exit::ExitMiddleware, hotkey::HotKeyMiddleware, icon_status::IconStatusMiddleware, image_resolve::ImageResolverMiddleware, search::SearchMiddleware, undo::UndoMiddleware}};
use std::collections::VecDeque;
pub struct DefaultProcessor<'a> {
@@ -65,6 +54,7 @@ impl<'a> DefaultProcessor<'a> {
disable_options: DisableOptions,
matcher_options_provider: &'a dyn MatcherMiddlewareConfigProvider,
match_provider: &'a dyn MatchProvider,
+ undo_enabled_provider: &'a dyn UndoEnabledProvider,
) -> DefaultProcessor<'a> {
Self {
event_queue: VecDeque::new(),
@@ -82,6 +72,7 @@ impl<'a> DefaultProcessor<'a> {
Box::new(ImageResolverMiddleware::new(path_provider)),
Box::new(CursorHintMiddleware::new()),
Box::new(ExitMiddleware::new()),
+ Box::new(UndoMiddleware::new(undo_enabled_provider)),
Box::new(ActionMiddleware::new(
match_info_provider,
event_sequence_provider,
diff --git a/espanso-engine/src/process/middleware/action.rs b/espanso-engine/src/process/middleware/action.rs
index 5d65651..41d97ed 100644
--- a/espanso-engine/src/process/middleware/action.rs
+++ b/espanso-engine/src/process/middleware/action.rs
@@ -126,10 +126,28 @@ impl<'a> Middleware for ActionMiddleware<'a> {
}),
)
}
+ EventType::Undo(m_event) => {
+ // We subtract one, because the backspace that triggered the undo feature
+ // already removed the last char
+ let backspace_count = m_event.replace.chars().count() - 1;
+
+ dispatch(Event::caused_by(
+ event.source_id,
+ EventType::TextInject(TextInjectRequest {
+ text: m_event.trigger.clone(),
+ force_mode: self.match_info_provider.get_force_mode(m_event.match_id),
+ }),
+ ));
+
+ Event::caused_by(
+ event.source_id,
+ EventType::KeySequenceInject(KeySequenceInjectRequest {
+ keys: (0..backspace_count).map(|_| Key::Backspace).collect(),
+ }),
+ )
+ }
_ => event,
}
-
- // TODO: handle images
}
}
diff --git a/espanso-engine/src/process/middleware/mod.rs b/espanso-engine/src/process/middleware/mod.rs
index 40c72b6..3a7e3eb 100644
--- a/espanso-engine/src/process/middleware/mod.rs
+++ b/espanso-engine/src/process/middleware/mod.rs
@@ -34,3 +34,4 @@ pub mod multiplex;
pub mod past_discard;
pub mod render;
pub mod search;
+pub mod undo;
diff --git a/espanso-engine/src/process/middleware/undo.rs b/espanso-engine/src/process/middleware/undo.rs
new file mode 100644
index 0000000..29421e2
--- /dev/null
+++ b/espanso-engine/src/process/middleware/undo.rs
@@ -0,0 +1,115 @@
+/*
+ * 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::event::{
+ input::{Key, Status},
+ internal::{TextFormat, UndoEvent},
+ Event, EventType,
+};
+
+pub trait UndoEnabledProvider {
+ fn is_undo_enabled(&self) -> bool;
+}
+
+pub struct UndoMiddleware<'a> {
+ undo_enabled_provider: &'a dyn UndoEnabledProvider,
+ record: RefCell