From 92d99c30bcfe451c39caf316e2d7ae736921bb3e Mon Sep 17 00:00:00 2001 From: Matt Harrison Date: Wed, 11 Dec 2019 12:12:40 -0500 Subject: [PATCH 01/10] preserve the current clipboard when using the Clipboard backend. Store the current clipboard and restore it after the expansion has been pasted. This prevents your current clipboard from being lost if using the Clipboard backend. --- src/engine.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine.rs b/src/engine.rs index 79f5e3d..151835d 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -205,8 +205,10 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa } }, BackendType::Clipboard => { + let previous_clipboard_content = self.clipboard_manager.get_clipboard().unwrap_or(String::from("")); self.clipboard_manager.set_clipboard(&target_string); self.keyboard_manager.trigger_paste(&config.paste_shortcut); + self.clipboard_manager.set_clipboard(&previous_clipboard_content); }, } From 2789fd93ad7c888247a1e80396c1414592892c5b Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 20:37:54 +0100 Subject: [PATCH 02/10] Version bump 0.4.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8302dbe..3acfc1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -370,7 +370,7 @@ dependencies = [ [[package]] name = "espanso" -version = "0.4.0" +version = "0.4.1" dependencies = [ "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 985ca3d..e4c7b17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "espanso" -version = "0.4.0" +version = "0.4.1" authors = ["Federico Terzi "] license = "GPL-3.0" description = "Cross-platform Text Expander written in Rust" From 1f5cdc025dbfbe311f47b4edfd9b050cd5517004 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 20:42:53 +0100 Subject: [PATCH 03/10] Fix #139 #134 --- src/main.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2b6ab0d..5d59a2a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -402,9 +402,24 @@ fn start_daemon(config_set: ConfigSet) { #[cfg(target_os = "linux")] fn start_daemon(config_set: ConfigSet) { - if config_set.default.use_system_agent { - use std::process::Command; + use std::process::{Command, Stdio}; + // Check if Systemd is available in the system + let status = Command::new("systemctl") + .args(&["--version"]) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .status(); + + // If Systemd is not available in the system, espanso should default to unmanaged mode + // See issue https://github.com/federico-terzi/espanso/issues/139 + let force_unmanaged = if let Err(status) = status { + true + } else { + false + }; + + if config_set.default.use_system_agent && !force_unmanaged { // Make sure espanso is currently registered in systemd let res = Command::new("systemctl") .args(&["--user", "is-enabled", "espanso.service"]) @@ -442,6 +457,10 @@ fn start_daemon(config_set: ConfigSet) { eprintln!("Error starting systemd daemon: {}", res.unwrap_err()); } }else{ + if force_unmanaged { + eprintln!("Systemd is not available in this system, switching to unmanaged mode."); + } + fork_daemon(config_set); } } From 284482e2d54cbd1ca7e44c84b5b14f1ae5019e10 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 21:57:06 +0100 Subject: [PATCH 04/10] Attempt to improve support for Simple terminal on linux. #112 --- native/liblinuxbridge/bridge.cpp | 8 ++++++++ native/liblinuxbridge/bridge.h | 5 +++++ src/bridge/linux.rs | 1 + src/keyboard/linux.rs | 2 ++ 4 files changed, 16 insertions(+) diff --git a/native/liblinuxbridge/bridge.cpp b/native/liblinuxbridge/bridge.cpp index 5695fa3..6e4e5b3 100644 --- a/native/liblinuxbridge/bridge.cpp +++ b/native/liblinuxbridge/bridge.cpp @@ -303,6 +303,10 @@ void trigger_shift_ins_paste() { xdo_send_keysequence_window(xdo_context, CURRENTWINDOW, "Shift+Insert", 8000); } +void trigger_alt_shift_ins_paste() { + xdo_send_keysequence_window(xdo_context, CURRENTWINDOW, "Shift+Alt+Insert", 8000); +} + // SYSTEM MODULE // Function taken from the wmlib tool source code @@ -465,8 +469,12 @@ int32_t is_current_window_terminal() { return 1; }else if (strstr(class_buffer, "Terminator") != NULL) { // Terminator return 1; + }else if (strstr(class_buffer, "stterm") != NULL) { // Simple terminal 3 + return 2; }else if (strstr(class_buffer, "St") != NULL) { // Simple terminal return 1; + }else if (strstr(class_buffer, "st") != NULL) { // Simple terminal 2 + return 1; }else if (strstr(class_buffer, "Alacritty") != NULL) { // Alacritty terminal return 1; } diff --git a/native/liblinuxbridge/bridge.h b/native/liblinuxbridge/bridge.h index 9d07122..ce55253 100644 --- a/native/liblinuxbridge/bridge.h +++ b/native/liblinuxbridge/bridge.h @@ -87,6 +87,11 @@ extern "C" void trigger_terminal_paste(); */ extern "C" void trigger_shift_ins_paste(); +/* + * Trigger alt shift ins pasting( Pressing ALT+SHIFT+INS ) + */ +extern "C" void trigger_alt_shift_ins_paste(); + // SYSTEM MODULE diff --git a/src/bridge/linux.rs b/src/bridge/linux.rs index 4947629..ab609c2 100644 --- a/src/bridge/linux.rs +++ b/src/bridge/linux.rs @@ -43,4 +43,5 @@ extern { pub fn trigger_paste(); pub fn trigger_terminal_paste(); pub fn trigger_shift_ins_paste(); + pub fn trigger_alt_shift_ins_paste(); } \ No newline at end of file diff --git a/src/keyboard/linux.rs b/src/keyboard/linux.rs index 956d89d..2074970 100644 --- a/src/keyboard/linux.rs +++ b/src/keyboard/linux.rs @@ -48,6 +48,8 @@ impl super::KeyboardManager for LinuxKeyboardManager { // so we need to check the correct situation. if is_terminal == 0 { trigger_paste(); + }else if is_terminal == 2 { // Special case for stterm + trigger_alt_shift_ins_paste(); }else{ trigger_terminal_paste(); } From db2ff8c6ca8bf1e5a75cb8f7a65ddee3a4b5d1fa Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 22:05:56 +0100 Subject: [PATCH 05/10] Fix bug that prevented espanso from working with Emacs #122 --- native/liblinuxbridge/bridge.cpp | 4 +++- native/liblinuxbridge/bridge.h | 4 ++-- src/bridge/linux.rs | 2 +- src/keyboard/linux.rs | 8 +++++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/native/liblinuxbridge/bridge.cpp b/native/liblinuxbridge/bridge.cpp index 6e4e5b3..a34661a 100644 --- a/native/liblinuxbridge/bridge.cpp +++ b/native/liblinuxbridge/bridge.cpp @@ -453,7 +453,7 @@ int32_t get_active_window_executable(char *buffer, int32_t size) { return result; } -int32_t is_current_window_terminal() { +int32_t is_current_window_special() { char class_buffer[250]; int res = get_active_window_class(class_buffer, 250); if (res > 0) { @@ -477,6 +477,8 @@ int32_t is_current_window_terminal() { return 1; }else if (strstr(class_buffer, "Alacritty") != NULL) { // Alacritty terminal return 1; + }else if (strstr(class_buffer, "Emacs") != NULL) { // Emacs + return 3; } } diff --git a/native/liblinuxbridge/bridge.h b/native/liblinuxbridge/bridge.h index ce55253..6e921bf 100644 --- a/native/liblinuxbridge/bridge.h +++ b/native/liblinuxbridge/bridge.h @@ -111,8 +111,8 @@ extern "C" int32_t get_active_window_class(char * buffer, int32_t size); extern "C" int32_t get_active_window_executable(char * buffer, int32_t size); /* - * Return 1 if the current window is a terminal window, 0 otherwise. + * Return a value greater than 0 if the current window needs a special paste combination, 0 otherwise. */ -extern "C" int32_t is_current_window_terminal(); +extern "C" int32_t is_current_window_special(); #endif //ESPANSO_BRIDGE_H diff --git a/src/bridge/linux.rs b/src/bridge/linux.rs index ab609c2..90edfc6 100644 --- a/src/bridge/linux.rs +++ b/src/bridge/linux.rs @@ -31,7 +31,7 @@ extern { pub fn get_active_window_name(buffer: *mut c_char, size: i32) -> i32; pub fn get_active_window_class(buffer: *mut c_char, size: i32) -> i32; pub fn get_active_window_executable(buffer: *mut c_char, size: i32) -> i32; - pub fn is_current_window_terminal() -> i32; + pub fn is_current_window_special() -> i32; // Keyboard pub fn register_keypress_callback(cb: extern fn(_self: *mut c_void, *const u8, diff --git a/src/keyboard/linux.rs b/src/keyboard/linux.rs index 2074970..538c375 100644 --- a/src/keyboard/linux.rs +++ b/src/keyboard/linux.rs @@ -42,14 +42,16 @@ impl super::KeyboardManager for LinuxKeyboardManager { unsafe { match shortcut { PasteShortcut::Default => { - let is_terminal = is_current_window_terminal(); + let is_special = is_current_window_special(); // Terminals use a different keyboard combination to paste from clipboard, // so we need to check the correct situation. - if is_terminal == 0 { + if is_special == 0 { trigger_paste(); - }else if is_terminal == 2 { // Special case for stterm + }else if is_special == 2 { // Special case for stterm trigger_alt_shift_ins_paste(); + }else if is_special == 3 { // Special case for Emacs + trigger_shift_ins_paste(); }else{ trigger_terminal_paste(); } From 12fc31700ecb03b63e97eec7b3ec541a730a1d01 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 22:28:43 +0100 Subject: [PATCH 06/10] Add trim option to shell extension and tests --- src/extension/shell.rs | 85 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/src/extension/shell.rs b/src/extension/shell.rs index 4ca4999..113f5d7 100644 --- a/src/extension/shell.rs +++ b/src/extension/shell.rs @@ -56,8 +56,20 @@ impl super::Extension for ShellExtension { match output { Ok(output) => { let output_str = String::from_utf8_lossy(output.stdout.as_slice()); + let mut output_str = output_str.into_owned(); - Some(output_str.into_owned()) + // If specified, trim the output + let trim_opt = params.get(&Value::from("trim")); + if let Some(value) = trim_opt { + let val = value.as_bool(); + if let Some(val) = val { + if val { + output_str = output_str.trim().to_owned() + } + } + } + + Some(output_str) }, Err(e) => { error!("Could not execute cmd '{}', error: {}", cmd, e); @@ -65,4 +77,75 @@ impl super::Extension for ShellExtension { }, } } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::extension::Extension; + + #[test] + fn test_shell_basic() { + let mut params = Mapping::new(); + params.insert(Value::from("cmd"), Value::from("echo hello world")); + + let extension = ShellExtension::new(); + let output = extension.calculate(¶ms); + + assert!(output.is_some()); + assert_eq!(output.unwrap(), "hello world\n"); + } + + #[test] + fn test_shell_trimmed() { + let mut params = Mapping::new(); + params.insert(Value::from("cmd"), Value::from("echo hello world")); + params.insert(Value::from("trim"), Value::from(true)); + + let extension = ShellExtension::new(); + let output = extension.calculate(¶ms); + + assert!(output.is_some()); + assert_eq!(output.unwrap(), "hello world"); + } + + #[test] + fn test_shell_trimmed_2() { + let mut params = Mapping::new(); + params.insert(Value::from("cmd"), Value::from("echo \" hello world \"")); + params.insert(Value::from("trim"), Value::from(true)); + + let extension = ShellExtension::new(); + let output = extension.calculate(¶ms); + + assert!(output.is_some()); + assert_eq!(output.unwrap(), "hello world"); + } + + #[test] + fn test_shell_trimmed_malformed() { + let mut params = Mapping::new(); + params.insert(Value::from("cmd"), Value::from("echo hello world")); + params.insert(Value::from("trim"), Value::from("error")); + + let extension = ShellExtension::new(); + let output = extension.calculate(¶ms); + + assert!(output.is_some()); + assert_eq!(output.unwrap(), "hello world\n"); + } + + #[test] + #[cfg(not(target_os = "windows"))] + fn test_shell_pipes() { + let mut params = Mapping::new(); + params.insert(Value::from("cmd"), Value::from("echo hello world | cat")); + params.insert(Value::from("trim"), Value::from(true)); + + let extension = ShellExtension::new(); + let output = extension.calculate(¶ms); + + assert!(output.is_some()); + assert_eq!(output.unwrap(), "hello world"); + } } \ No newline at end of file From 5db9d92642898ee1505c817cb51e213b5b15b79c Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 22:33:35 +0100 Subject: [PATCH 07/10] Fix shell extension tests on Windows --- src/extension/shell.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/extension/shell.rs b/src/extension/shell.rs index 113f5d7..aa1012a 100644 --- a/src/extension/shell.rs +++ b/src/extension/shell.rs @@ -93,7 +93,12 @@ mod tests { let output = extension.calculate(¶ms); assert!(output.is_some()); - assert_eq!(output.unwrap(), "hello world\n"); + + if cfg!(target_os = "windows") { + assert_eq!(output.unwrap(), "hello world\r\n"); + }else{ + assert_eq!(output.unwrap(), "hello world\n"); + } } #[test] @@ -112,7 +117,12 @@ mod tests { #[test] fn test_shell_trimmed_2() { let mut params = Mapping::new(); - params.insert(Value::from("cmd"), Value::from("echo \" hello world \"")); + if cfg!(target_os = "windows") { + params.insert(Value::from("cmd"), Value::from("echo hello world ")); + }else{ + params.insert(Value::from("cmd"), Value::from("echo \" hello world \"")); + } + params.insert(Value::from("trim"), Value::from(true)); let extension = ShellExtension::new(); @@ -132,7 +142,11 @@ mod tests { let output = extension.calculate(¶ms); assert!(output.is_some()); - assert_eq!(output.unwrap(), "hello world\n"); + if cfg!(target_os = "windows") { + assert_eq!(output.unwrap(), "hello world\r\n"); + }else{ + assert_eq!(output.unwrap(), "hello world\n"); + } } #[test] From 4c172a9d54e5de1e374911c3ad02b92dac01af02 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 22:52:24 +0100 Subject: [PATCH 08/10] Add Random Extension to enable non-deterministic matches --- Cargo.lock | 7 ++-- Cargo.toml | 1 + src/extension/mod.rs | 2 + src/extension/random.rs | 93 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/extension/random.rs diff --git a/Cargo.lock b/Cargo.lock index 3acfc1b..84de321 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,6 +384,7 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1003,7 +1004,7 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1410,7 +1411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1892,7 +1893,7 @@ dependencies = [ "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" diff --git a/Cargo.toml b/Cargo.toml index e4c7b17..fccfc68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ reqwest = "0.9.20" git2 = {version = "0.10.1", features = ["https"]} tempfile = "3.1.0" dialoguer = "0.4.0" +rand = "0.7.2" [target.'cfg(unix)'.dependencies] libc = "0.2.62" diff --git a/src/extension/mod.rs b/src/extension/mod.rs index 26da4cd..4c0f11e 100644 --- a/src/extension/mod.rs +++ b/src/extension/mod.rs @@ -22,6 +22,7 @@ use serde_yaml::Mapping; mod date; mod shell; mod script; +mod random; pub trait Extension { fn name(&self) -> String; @@ -33,5 +34,6 @@ pub fn get_extensions() -> Vec> { Box::new(date::DateExtension::new()), Box::new(shell::ShellExtension::new()), Box::new(script::ScriptExtension::new()), + Box::new(random::RandomExtension::new()), ] } \ No newline at end of file diff --git a/src/extension/random.rs b/src/extension/random.rs new file mode 100644 index 0000000..e44a2e6 --- /dev/null +++ b/src/extension/random.rs @@ -0,0 +1,93 @@ +/* + * This file is part of espanso. + * + * Copyright (C) 2019 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 serde_yaml::{Mapping, Value}; +use rand::seq::SliceRandom; +use log::{warn, error}; + +pub struct RandomExtension {} + +impl RandomExtension { + pub fn new() -> RandomExtension { + RandomExtension{} + } +} + +impl super::Extension for RandomExtension { + fn name(&self) -> String { + String::from("random") + } + + fn calculate(&self, params: &Mapping) -> Option { + let choices = params.get(&Value::from("choices")); + if choices.is_none() { + warn!("No 'choices' parameter specified for random variable"); + return None + } + let choices = choices.unwrap().as_sequence(); + if let Some(choices) = choices { + let str_choices = choices.iter().map(|arg| { + arg.as_str().unwrap_or_default().to_string() + }).collect::>(); + + // Select a random choice between the possibilities + let choice = str_choices.choose(&mut rand::thread_rng()); + + match choice { + Some(output) => { + return Some(output.clone()) + }, + None => { + error!("Could not select a random choice."); + return None + }, + } + + } + + error!("choices array have an invalid format '{:?}'", choices); + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::extension::Extension; + + #[test] + fn test_random_basic() { + let mut params = Mapping::new(); + let choices = vec!( + "first", + "second", + "third", + ); + params.insert(Value::from("choices"), Value::from(choices.clone())); + + let extension = RandomExtension::new(); + let output = extension.calculate(¶ms); + + assert!(output.is_some()); + + let output = output.unwrap(); + + assert!(choices.iter().any(|x| x == &output)); + } +} \ No newline at end of file From 47f2cc1661b620bf0de9a0bb9368cb6b4a14d65c Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Fri, 13 Dec 2019 23:17:53 +0100 Subject: [PATCH 09/10] Add preserve_clipboard mode --- src/config/mod.rs | 5 +++++ src/engine.rs | 30 ++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 64463d4..c849527 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -53,6 +53,7 @@ fn default_use_system_agent() -> bool { true } fn default_config_caching_interval() -> i32 { 800 } fn default_word_separators() -> Vec { vec![' ', ',', '.', '\r', '\n', 22u8 as char] } fn default_toggle_interval() -> u32 { 230 } +fn default_preserve_clipboard() -> bool {false} fn default_backspace_limit() -> i32 { 3 } fn default_exclude_default_matches() -> bool {false} fn default_matches() -> Vec { Vec::new() } @@ -98,6 +99,9 @@ pub struct Configs { #[serde(default = "default_toggle_interval")] pub toggle_interval: u32, + #[serde(default = "default_preserve_clipboard")] + pub preserve_clipboard: bool, + #[serde(default)] pub paste_shortcut: PasteShortcut, @@ -145,6 +149,7 @@ impl Configs { validate_field!(result, self.backspace_limit, default_backspace_limit()); validate_field!(result, self.ipc_server_port, default_ipc_server_port()); validate_field!(result, self.use_system_agent, default_use_system_agent()); + validate_field!(result, self.preserve_clipboard, default_preserve_clipboard()); result } diff --git a/src/engine.rs b/src/engine.rs index 151835d..8f49a5c 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -95,6 +95,19 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa menu } + + fn return_content_if_preserve_clipboard_is_enabled(&self) -> Option { + // If the preserve_clipboard option is enabled, first save the current + // clipboard content in order to restore it later. + if self.config_manager.default_config().preserve_clipboard { + match self.clipboard_manager.get_clipboard() { + Some(clipboard) => {Some(clipboard)}, + None => {None}, + } + }else { + None + } + } } lazy_static! { @@ -119,6 +132,8 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa self.keyboard_manager.delete_string(char_count); + let mut previous_clipboard_content : Option = None; + // Manage the different types of matches match &m.content { // Text Match @@ -205,10 +220,12 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa } }, BackendType::Clipboard => { - let previous_clipboard_content = self.clipboard_manager.get_clipboard().unwrap_or(String::from("")); + // If the preserve_clipboard option is enabled, save the current + // clipboard content to restore it later. + previous_clipboard_content = self.return_content_if_preserve_clipboard_is_enabled(); + self.clipboard_manager.set_clipboard(&target_string); self.keyboard_manager.trigger_paste(&config.paste_shortcut); - self.clipboard_manager.set_clipboard(&previous_clipboard_content); }, } @@ -222,6 +239,10 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa MatchContentType::Image(content) => { // Make sure the image exist beforehand if content.path.exists() { + // If the preserve_clipboard option is enabled, save the current + // clipboard content to restore it later. + previous_clipboard_content = self.return_content_if_preserve_clipboard_is_enabled(); + self.clipboard_manager.set_clipboard_image(&content.path); self.keyboard_manager.trigger_paste(&config.paste_shortcut); }else{ @@ -229,6 +250,11 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa } }, } + + // Restore previous clipboard content + if let Some(previous_clipboard_content) = previous_clipboard_content { + self.clipboard_manager.set_clipboard(&previous_clipboard_content); + } } fn on_enable_update(&self, status: bool) { From 6b6cac059eb8b5d4d6198757772457da6b8aa81d Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sat, 14 Dec 2019 00:01:04 +0100 Subject: [PATCH 10/10] Update readme with new contributors and sponsors --- README.md | 5 ++++- images/githubsponsor.png | Bin 0 -> 22741 bytes images/paypal.png | Bin 0 -> 15794 bytes 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 images/githubsponsor.png create mode 100644 images/paypal.png diff --git a/README.md b/README.md index df78593..976fbde 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ ___ * Works on **Windows**, **macOS** and **Linux** * Works with almost **any program** * Works with **Emojis** 😄 +* Works with **Images** * **Date** expansion support * **Custom scripts** support * **Shell commands** support @@ -54,7 +55,8 @@ espanso is a free, open source software developed in my (little) spare time. If you liked the project and would like to support further development, please consider making a small donation, it really helps :) -[![Donate with PayPal](images/donate.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FHNLR5DRS267E&source=url) +[![Donate with PayPal](images/githubsponsor.png)](https://github.com/sponsors/federico-terzi) +[![Donate with PayPal](images/paypal.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FHNLR5DRS267E&source=url) ## Contributors @@ -65,6 +67,7 @@ Many people helped the project along the way, thanks to all of you. In particula * [Matteo Pellegrino](https://www.matteopellegrino.me/) - MacOS Tester * [Timo Runge](http://timorunge.com/) - MacOS contributor * [NickSeagull](http://nickseagull.github.io/) - Contributor +* [matt-h](https://github.com/matt-h) - Contributor ## Remarks diff --git a/images/githubsponsor.png b/images/githubsponsor.png new file mode 100644 index 0000000000000000000000000000000000000000..2a4d314bf90353975858c5d475432e44f8f1409c GIT binary patch literal 22741 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 PaahWV>IzkI79sxwwlqm6 literal 0 HcmV?d00001 diff --git a/images/paypal.png b/images/paypal.png new file mode 100644 index 0000000000000000000000000000000000000000..23e9e9fcbd697f3db5cf3ddc85a95ec5fd14ec5c GIT binary patch literal 15794 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