diff --git a/espanso/src/cli/worker/config.rs b/espanso/src/cli/worker/config.rs
index 980f1ac..d9625c2 100644
--- a/espanso/src/cli/worker/config.rs
+++ b/espanso/src/cli/worker/config.rs
@@ -17,7 +17,7 @@
* along with espanso. If not, see .
*/
-use std::collections::HashSet;
+use std::{collections::HashSet, sync::Arc};
use espanso_config::{
config::{AppProperties, Config, ConfigStore},
@@ -45,19 +45,19 @@ impl<'a> ConfigManager<'a> {
}
}
- pub fn active(&self) -> &'a dyn Config {
+ pub fn active(&self) -> Arc {
let current_app = self.app_info_provider.get_info();
let info = to_app_properties(¤t_app);
self.config_store.active(&info)
}
- pub fn active_context(&self) -> (&'a dyn Config, MatchSet) {
+ pub fn active_context(&self) -> (Arc, MatchSet) {
let config = self.active();
let match_paths = config.match_paths();
- (config, self.match_store.query(&match_paths))
+ (config.clone(), self.match_store.query(&match_paths))
}
- pub fn default(&self) -> &'a dyn Config {
+ pub fn default(&self) -> Arc{
self.config_store.default()
}
}
@@ -86,16 +86,19 @@ impl<'a> crate::engine::process::MatchFilter for ConfigManager<'a> {
}
impl<'a> super::engine::process::middleware::render::ConfigProvider<'a> for ConfigManager<'a> {
- fn configs(&self) -> Vec<(&'a dyn Config, MatchSet)> {
+ fn configs(&self) -> Vec<(Arc, MatchSet)> {
self
.config_store
.configs()
.into_iter()
- .map(|config| (config, self.match_store.query(config.match_paths())))
+ .map(|config| {
+ let match_set = self.match_store.query(config.match_paths());
+ (config, match_set)
+ })
.collect()
}
- fn active(&self) -> (&'a dyn Config, MatchSet) {
+ fn active(&self) -> (Arc, MatchSet) {
self.active_context()
}
}
diff --git a/espanso/src/cli/worker/engine/mod.rs b/espanso/src/cli/worker/engine/mod.rs
index 51b14dc..c9a4305 100644
--- a/espanso/src/cli/worker/engine/mod.rs
+++ b/espanso/src/cli/worker/engine/mod.rs
@@ -172,7 +172,7 @@ pub fn initialize_and_spawn(
let path_provider = PathProviderAdapter::new(&paths);
let disable_options =
- process::middleware::disable::extract_disable_options(config_manager.default());
+ process::middleware::disable::extract_disable_options(&*config_manager.default());
let mut processor = crate::engine::process::default(
&matchers,
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 70e1602..64c1510 100644
--- a/espanso/src/cli/worker/engine/process/middleware/render/mod.rs
+++ b/espanso/src/cli/worker/engine/process/middleware/render/mod.rs
@@ -17,7 +17,7 @@
* along with espanso. If not, see .
*/
-use std::{cell::RefCell, collections::HashMap};
+use std::{cell::RefCell, collections::HashMap, sync::Arc};
pub mod extension;
@@ -37,8 +37,8 @@ pub trait MatchProvider<'a> {
}
pub trait ConfigProvider<'a> {
- fn configs(&self) -> Vec<(&'a dyn Config, MatchSet)>;
- fn active(&self) -> (&'a dyn Config, MatchSet);
+ fn configs(&self) -> Vec<(Arc, MatchSet)>;
+ fn active(&self) -> (Arc, MatchSet);
}
pub struct RendererAdapter<'a> {
diff --git a/espanso/src/main.rs b/espanso/src/main.rs
index 9d9a951..32f2cd2 100644
--- a/espanso/src/main.rs
+++ b/espanso/src/main.rs
@@ -49,6 +49,7 @@ mod ipc;
mod lock;
#[macro_use]
mod logging;
+mod patch;
mod path;
mod preferences;
mod util;
diff --git a/espanso/src/patch/config_store.rs b/espanso/src/patch/config_store.rs
new file mode 100644
index 0000000..2a8b4fa
--- /dev/null
+++ b/espanso/src/patch/config_store.rs
@@ -0,0 +1,79 @@
+/*
+ * 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::sync::Arc;
+
+use espanso_config::config::{ConfigStore, Config};
+use log::debug;
+
+use super::PatchDefinition;
+
+pub struct PatchedConfigStore {
+ config_store: Box,
+ patches: Vec,
+}
+
+impl PatchedConfigStore {
+ pub fn from_store(config_store: Box) -> Self {
+ Self::from_store_with_patches(config_store, super::get_builtin_patches())
+ }
+
+ pub fn from_store_with_patches(config_store: Box, patches: Vec) -> Self {
+ // Only keep the patches that should be active in the current system
+ let active_patches = patches.into_iter().filter(|patch| {
+ let should_be_activated = (patch.should_be_activated)();
+
+ if should_be_activated {
+ debug!("activating '{}' patch", patch.name);
+ } else {
+ debug!("skipping '{}' patch", patch.name);
+ }
+
+ should_be_activated
+ }).collect();
+
+ Self {
+ config_store,
+ patches: active_patches,
+ }
+ }
+}
+
+impl ConfigStore for PatchedConfigStore {
+ fn default(&self) -> Arc {
+ self.config_store.default()
+ }
+
+ fn active<'f>(
+ &'f self,
+ app: &espanso_config::config::AppProperties,
+ ) -> Arc{
+ todo!()
+ }
+
+ fn configs(&self) -> Vec> {
+ todo!()
+ }
+
+ fn get_all_match_paths(&self) -> std::collections::HashSet {
+ self.config_store.get_all_match_paths()
+ }
+}
+
+// TODO: test
\ No newline at end of file
diff --git a/espanso/src/patch/mod.rs b/espanso/src/patch/mod.rs
new file mode 100644
index 0000000..303e3a3
--- /dev/null
+++ b/espanso/src/patch/mod.rs
@@ -0,0 +1,125 @@
+/*
+ * 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::sync::Arc;
+
+use espanso_config::config::{AppProperties, Backend, Config, ToggleKey};
+
+mod config_store;
+mod patches;
+
+pub fn get_builtin_patches() -> Vec {
+ // TODO
+ vec![
+ patches::win::onenote_for_windows_10::patch(),
+ ]
+}
+
+// TODO: fix visibility levels (pub/pub(crate))
+
+// TODO: patches should be "merged" at runtime with the active config, unless a config option (like "apply_patch")
+// is set. This is needed because we still want to allow the user to define user-specific configs without
+// losing the patch-specific changes
+
+pub struct PatchDefinition {
+ pub name: &'static str,
+ pub should_be_activated: fn() -> bool,
+ pub patch_config: fn(config: Arc) -> Arc,
+}
+
+pub struct DefaultPatchedConfig {
+ base: Arc,
+}
+
+pub trait PatchedConfig: Config {
+ // TODO: can we pass a simple reference here?
+ fn get_base(&self) -> Arc;
+
+ fn id(&self) -> i32 {
+ self.get_base().id()
+ }
+
+ fn label(&self) -> &str {
+ self.get_base().label()
+ }
+
+ fn match_paths(&self) -> &[String] {
+ self.get_base().match_paths()
+ }
+
+ fn backend(&self) -> Backend {
+ self.get_base().backend()
+ }
+
+ fn clipboard_threshold(&self) -> usize {
+ self.get_base().clipboard_threshold()
+ }
+
+ fn pre_paste_delay(&self) -> usize {
+ self.get_base().pre_paste_delay()
+ }
+
+ fn paste_shortcut_event_delay(&self) -> usize {
+ self.get_base().paste_shortcut_event_delay()
+ }
+
+ fn paste_shortcut(&self) -> Option {
+ self.get_base().paste_shortcut()
+ }
+
+ fn disable_x11_fast_inject(&self) -> bool {
+ self.get_base().disable_x11_fast_inject()
+ }
+
+ fn toggle_key(&self) -> Option {
+ self.get_base().toggle_key()
+ }
+
+ fn auto_restart(&self) -> bool {
+ self.get_base().auto_restart()
+ }
+
+ fn preserve_clipboard(&self) -> bool {
+ self.get_base().preserve_clipboard()
+ }
+
+ fn restore_clipboard_delay(&self) -> usize {
+ self.get_base().restore_clipboard_delay()
+ }
+
+ fn inject_delay(&self) -> Option {
+ self.get_base().inject_delay()
+ }
+
+ fn key_delay(&self) -> Option {
+ self.get_base().key_delay()
+ }
+
+ fn word_separators(&self) -> Vec {
+ self.get_base().word_separators()
+ }
+
+ fn backspace_limit(&self) -> usize {
+ self.get_base().backspace_limit()
+ }
+
+ fn is_match<'a>(&self, app: &AppProperties<'a>) -> bool {
+ self.get_base().is_match(app)
+ }
+}
diff --git a/espanso/src/patch/patches/mod.rs b/espanso/src/patch/patches/mod.rs
new file mode 100644
index 0000000..6303b8f
--- /dev/null
+++ b/espanso/src/patch/patches/mod.rs
@@ -0,0 +1,96 @@
+/*
+ * 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 win;
+
+
+
+// #[macro_export]
+// macro_rules! create_patch {
+// // TODO: add function body
+// ( $should_be_activated:expr, $( $config_field:ident ->$config_type:ty ),* ) => {
+// {
+// $(
+// if $child.$x.is_none() {
+// $child.$x = $parent.$x.clone();
+// }
+// )*
+
+// // Build a temporary object to verify that all fields
+// // are being used at compile time
+// $t {
+// $(
+// $x: None,
+// )*
+// };
+// }
+// {
+// use crate::patch::{ConfigProxy, Patch};
+
+// pub struct PatchImpl<'a> {
+// patched_config: PatchedConfig<'a>,
+// }
+
+// impl<'a> PatchImpl<'a> {
+// pub fn new(default: &'a dyn Config) -> Self {
+// Self {
+// patched_config: PatchedConfig::new(default),
+// }
+// }
+// }
+
+// impl<'a> Patch<'a> for PatchImpl<'a> {
+// fn should_be_activated(&self) -> bool {
+// $should_be_activated
+// }
+
+// fn patch_name(&self) -> &'static str {
+// todo!()
+// }
+
+// fn config(&self) -> &'a dyn Config {
+// &self.patched_config
+// }
+// }
+
+// pub struct PatchedConfig<'a> {
+// default: &'a dyn Config,
+// }
+
+// impl<'a> PatchedConfig<'a> {
+// pub fn new(default: &'a dyn Config) -> Self {
+// Self { default }
+// }
+// }
+
+// impl<'a> ConfigProxy<'a> for PatchedConfig<'a> {
+// fn get_default(&self) -> &'a dyn espanso_config::config::Config {
+// self.default
+// }
+
+// $(
+// fn $config_field(&self) -> $config_type {
+// todo!()
+// }
+// )*
+// }
+
+// }
+// };
+// }
diff --git a/espanso/src/patch/patches/win/mod.rs b/espanso/src/patch/patches/win/mod.rs
new file mode 100644
index 0000000..c3cc1a7
--- /dev/null
+++ b/espanso/src/patch/patches/win/mod.rs
@@ -0,0 +1,20 @@
+/*
+ * 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 onenote_for_windows_10;
\ No newline at end of file
diff --git a/espanso/src/patch/patches/win/onenote_for_windows_10.rs b/espanso/src/patch/patches/win/onenote_for_windows_10.rs
new file mode 100644
index 0000000..ea8a788
--- /dev/null
+++ b/espanso/src/patch/patches/win/onenote_for_windows_10.rs
@@ -0,0 +1,30 @@
+/*
+ * 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::patch::PatchDefinition;
+
+pub fn patch() -> PatchDefinition {
+ PatchDefinition {
+ name: file!(),
+ should_be_activated: || cfg!(target_os = "windows"),
+ patch_config: |base| {
+ todo!()
+ },
+ }
+}