feat(core): first steps in patch system implementation
This commit is contained in:
parent
24910859ac
commit
bc19b412ae
|
@ -17,7 +17,7 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::{collections::HashSet, sync::Arc};
|
||||||
|
|
||||||
use espanso_config::{
|
use espanso_config::{
|
||||||
config::{AppProperties, Config, ConfigStore},
|
config::{AppProperties, Config, ConfigStore},
|
||||||
|
@ -45,19 +45,19 @@ impl<'a> ConfigManager<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active(&self) -> &'a dyn Config {
|
pub fn active(&self) -> Arc<dyn Config> {
|
||||||
let current_app = self.app_info_provider.get_info();
|
let current_app = self.app_info_provider.get_info();
|
||||||
let info = to_app_properties(¤t_app);
|
let info = to_app_properties(¤t_app);
|
||||||
self.config_store.active(&info)
|
self.config_store.active(&info)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_context(&self) -> (&'a dyn Config, MatchSet) {
|
pub fn active_context(&self) -> (Arc<dyn Config>, MatchSet) {
|
||||||
let config = self.active();
|
let config = self.active();
|
||||||
let match_paths = config.match_paths();
|
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<dyn Config>{
|
||||||
self.config_store.default()
|
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> {
|
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<dyn Config>, MatchSet)> {
|
||||||
self
|
self
|
||||||
.config_store
|
.config_store
|
||||||
.configs()
|
.configs()
|
||||||
.into_iter()
|
.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()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn active(&self) -> (&'a dyn Config, MatchSet) {
|
fn active(&self) -> (Arc<dyn Config>, MatchSet) {
|
||||||
self.active_context()
|
self.active_context()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,7 @@ pub fn initialize_and_spawn(
|
||||||
let path_provider = PathProviderAdapter::new(&paths);
|
let path_provider = PathProviderAdapter::new(&paths);
|
||||||
|
|
||||||
let disable_options =
|
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(
|
let mut processor = crate::engine::process::default(
|
||||||
&matchers,
|
&matchers,
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::{cell::RefCell, collections::HashMap};
|
use std::{cell::RefCell, collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
pub mod extension;
|
pub mod extension;
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ pub trait MatchProvider<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ConfigProvider<'a> {
|
pub trait ConfigProvider<'a> {
|
||||||
fn configs(&self) -> Vec<(&'a dyn Config, MatchSet)>;
|
fn configs(&self) -> Vec<(Arc<dyn Config>, MatchSet)>;
|
||||||
fn active(&self) -> (&'a dyn Config, MatchSet);
|
fn active(&self) -> (Arc<dyn Config>, MatchSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RendererAdapter<'a> {
|
pub struct RendererAdapter<'a> {
|
||||||
|
|
|
@ -49,6 +49,7 @@ mod ipc;
|
||||||
mod lock;
|
mod lock;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod logging;
|
mod logging;
|
||||||
|
mod patch;
|
||||||
mod path;
|
mod path;
|
||||||
mod preferences;
|
mod preferences;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
79
espanso/src/patch/config_store.rs
Normal file
79
espanso/src/patch/config_store.rs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use espanso_config::config::{ConfigStore, Config};
|
||||||
|
use log::debug;
|
||||||
|
|
||||||
|
use super::PatchDefinition;
|
||||||
|
|
||||||
|
pub struct PatchedConfigStore {
|
||||||
|
config_store: Box<dyn ConfigStore>,
|
||||||
|
patches: Vec<PatchDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PatchedConfigStore {
|
||||||
|
pub fn from_store(config_store: Box<dyn ConfigStore>) -> Self {
|
||||||
|
Self::from_store_with_patches(config_store, super::get_builtin_patches())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_store_with_patches(config_store: Box<dyn ConfigStore>, patches: Vec<PatchDefinition>) -> 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<dyn Config> {
|
||||||
|
self.config_store.default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn active<'f>(
|
||||||
|
&'f self,
|
||||||
|
app: &espanso_config::config::AppProperties,
|
||||||
|
) -> Arc<dyn Config>{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn configs(&self) -> Vec<Arc<dyn Config>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_all_match_paths(&self) -> std::collections::HashSet<String> {
|
||||||
|
self.config_store.get_all_match_paths()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: test
|
125
espanso/src/patch/mod.rs
Normal file
125
espanso/src/patch/mod.rs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use espanso_config::config::{AppProperties, Backend, Config, ToggleKey};
|
||||||
|
|
||||||
|
mod config_store;
|
||||||
|
mod patches;
|
||||||
|
|
||||||
|
pub fn get_builtin_patches() -> Vec<PatchDefinition> {
|
||||||
|
// 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<dyn Config>) -> Arc<dyn PatchedConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DefaultPatchedConfig {
|
||||||
|
base: Arc<dyn Config>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PatchedConfig: Config {
|
||||||
|
// TODO: can we pass a simple reference here?
|
||||||
|
fn get_base(&self) -> Arc<dyn Config>;
|
||||||
|
|
||||||
|
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<String> {
|
||||||
|
self.get_base().paste_shortcut()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disable_x11_fast_inject(&self) -> bool {
|
||||||
|
self.get_base().disable_x11_fast_inject()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toggle_key(&self) -> Option<ToggleKey> {
|
||||||
|
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<usize> {
|
||||||
|
self.get_base().inject_delay()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_delay(&self) -> Option<usize> {
|
||||||
|
self.get_base().key_delay()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn word_separators(&self) -> Vec<String> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
96
espanso/src/patch/patches/mod.rs
Normal file
96
espanso/src/patch/patches/mod.rs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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!()
|
||||||
|
// }
|
||||||
|
// )*
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
20
espanso/src/patch/patches/win/mod.rs
Normal file
20
espanso/src/patch/patches/win/mod.rs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub mod onenote_for_windows_10;
|
30
espanso/src/patch/patches/win/onenote_for_windows_10.rs
Normal file
30
espanso/src/patch/patches/win/onenote_for_windows_10.rs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::patch::PatchDefinition;
|
||||||
|
|
||||||
|
pub fn patch() -> PatchDefinition {
|
||||||
|
PatchDefinition {
|
||||||
|
name: file!(),
|
||||||
|
should_be_activated: || cfg!(target_os = "windows"),
|
||||||
|
patch_config: |base| {
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user