feat(config): add pre_paste_delay configuration option
This commit is contained in:
parent
a40125715f
commit
139fa7e511
96
Cargo.lock
generated
96
Cargo.lock
generated
|
@ -220,6 +220,12 @@ dependencies = [
|
|||
"libdbus-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "difference"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "1.0.5"
|
||||
|
@ -251,6 +257,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.7"
|
||||
|
@ -334,6 +346,7 @@ dependencies = [
|
|||
"glob",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"mockall",
|
||||
"ordered-float",
|
||||
"regex",
|
||||
"serde",
|
||||
|
@ -455,6 +468,21 @@ dependencies = [
|
|||
"widestring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fragile"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
|
@ -684,6 +712,33 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mockall"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18d614ad23f9bb59119b8b5670a85c7ba92c5e9adf4385c81ea00c51c8be33d5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"downcast",
|
||||
"fragile",
|
||||
"lazy_static",
|
||||
"mockall_derive",
|
||||
"predicates",
|
||||
"predicates-tree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mockall_derive"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd4234635bca06fc96c7368d038061e0aae1b00a764dc817e900dc974e3deea"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "named_pipe"
|
||||
version = "0.4.1"
|
||||
|
@ -699,6 +754,12 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "normalize-line-endings"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
|
||||
|
||||
[[package]]
|
||||
name = "notify-rust"
|
||||
version = "4.2.2"
|
||||
|
@ -829,6 +890,35 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df"
|
||||
dependencies = [
|
||||
"difference",
|
||||
"float-cmp",
|
||||
"normalize-line-endings",
|
||||
"predicates-core",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"treeline",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
|
@ -1288,6 +1378,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "treeline"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
|
|
|
@ -20,4 +20,5 @@ ordered-float = "2.0"
|
|||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3.7"
|
||||
tempfile = "3.2.0"
|
||||
tempfile = "3.2.0"
|
||||
mockall = "0.9.1"
|
22
espanso-config/src/config/default.rs
Normal file
22
espanso-config/src/config/default.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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(crate) const DEFAULT_CLIPBOARD_THRESHOLD: usize = 100;
|
||||
|
||||
pub(crate) const DEFAULT_PRE_PASTE_DELAY: usize = 100;
|
|
@ -25,16 +25,33 @@ mod parse;
|
|||
mod path;
|
||||
mod resolve;
|
||||
mod util;
|
||||
pub(crate) mod default;
|
||||
pub(crate) mod store;
|
||||
|
||||
#[cfg(test)]
|
||||
use mockall::{automock, predicate::*};
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait Config: Send {
|
||||
fn id(&self) -> i32;
|
||||
fn label(&self) -> &str;
|
||||
fn match_paths(&self) -> &[String];
|
||||
fn backend(&self) -> Backend;
|
||||
fn clipboard_threshold(&self) -> usize;
|
||||
|
||||
fn is_match(&self, app: &AppProperties) -> bool;
|
||||
// Number of chars after which a match is injected with the clipboard
|
||||
// backend instead of the default one. This is done for efficiency
|
||||
// reasons, as injecting a long match through separate events becomes
|
||||
// slow for long strings.
|
||||
fn clipboard_threshold(&self) -> usize;
|
||||
|
||||
// Delay (in ms) that espanso should wait to trigger the paste shortcut
|
||||
// after copying the content in the clipboard. This is needed because
|
||||
// if we trigger a "paste" shortcut before the content is actually
|
||||
// copied in the clipboard, the operation will fail.
|
||||
fn pre_paste_delay(&self) -> usize;
|
||||
|
||||
// TODO: add other delay options (start by the ones needed in clipboard injector)
|
||||
|
||||
fn is_match<'a>(&self, app: &AppProperties<'a>) -> bool;
|
||||
}
|
||||
|
||||
pub trait ConfigStore: Send {
|
||||
|
|
|
@ -30,6 +30,8 @@ pub(crate) struct ParsedConfig {
|
|||
pub backend: Option<String>,
|
||||
pub clipboard_threshold: Option<usize>,
|
||||
|
||||
pub pre_paste_delay: Option<usize>,
|
||||
|
||||
// Includes
|
||||
pub includes: Option<Vec<String>>,
|
||||
pub excludes: Option<Vec<String>>,
|
||||
|
|
|
@ -36,6 +36,9 @@ pub(crate) struct YAMLConfig {
|
|||
#[serde(default)]
|
||||
pub clipboard_threshold: Option<usize>,
|
||||
|
||||
#[serde(default)]
|
||||
pub pre_paste_delay: Option<usize>,
|
||||
|
||||
#[serde(default)]
|
||||
pub includes: Option<Vec<String>>,
|
||||
|
||||
|
@ -86,6 +89,9 @@ impl TryFrom<YAMLConfig> for ParsedConfig {
|
|||
label: yaml_config.label,
|
||||
backend: yaml_config.backend,
|
||||
clipboard_threshold: yaml_config.clipboard_threshold,
|
||||
|
||||
pre_paste_delay: yaml_config.pre_paste_delay,
|
||||
|
||||
use_standard_includes: yaml_config.use_standard_includes,
|
||||
includes: yaml_config.includes,
|
||||
extra_includes: yaml_config.extra_includes,
|
||||
|
@ -112,6 +118,7 @@ mod tests {
|
|||
label: "test"
|
||||
backend: clipboard
|
||||
clipboard_threshold: 200
|
||||
pre_paste_delay: 300
|
||||
|
||||
use_standard_includes: true
|
||||
includes: ["test1"]
|
||||
|
@ -136,6 +143,8 @@ mod tests {
|
|||
backend: Some("clipboard".to_string()),
|
||||
clipboard_threshold: Some(200),
|
||||
|
||||
pre_paste_delay: Some(300),
|
||||
|
||||
use_standard_includes: Some(true),
|
||||
includes: Some(vec!["test1".to_string()]),
|
||||
extra_includes: Some(vec!["test2".to_string()]),
|
||||
|
|
|
@ -17,7 +17,13 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use super::{AppProperties, Backend, Config, parse::ParsedConfig, path::calculate_paths, util::os_matches};
|
||||
use super::{
|
||||
default::{DEFAULT_CLIPBOARD_THRESHOLD, DEFAULT_PRE_PASTE_DELAY},
|
||||
parse::ParsedConfig,
|
||||
path::calculate_paths,
|
||||
util::os_matches,
|
||||
AppProperties, Backend, Config,
|
||||
};
|
||||
use crate::{counter::next_id, merge};
|
||||
use anyhow::Result;
|
||||
use log::error;
|
||||
|
@ -118,7 +124,13 @@ impl Config for ResolvedConfig {
|
|||
}
|
||||
|
||||
fn backend(&self) -> Backend {
|
||||
match self.parsed.backend.as_deref().map(|b| b.to_lowercase()).as_deref() {
|
||||
match self
|
||||
.parsed
|
||||
.backend
|
||||
.as_deref()
|
||||
.map(|b| b.to_lowercase())
|
||||
.as_deref()
|
||||
{
|
||||
Some("clipboard") => Backend::Clipboard,
|
||||
Some("inject") => Backend::Inject,
|
||||
Some("auto") => Backend::Auto,
|
||||
|
@ -130,7 +142,17 @@ impl Config for ResolvedConfig {
|
|||
}
|
||||
|
||||
fn clipboard_threshold(&self) -> usize {
|
||||
self.parsed.clipboard_threshold.unwrap_or(100)
|
||||
self
|
||||
.parsed
|
||||
.clipboard_threshold
|
||||
.unwrap_or(DEFAULT_CLIPBOARD_THRESHOLD)
|
||||
}
|
||||
|
||||
fn pre_paste_delay(&self) -> usize {
|
||||
self
|
||||
.parsed
|
||||
.pre_paste_delay
|
||||
.unwrap_or(DEFAULT_PRE_PASTE_DELAY)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,6 +212,7 @@ impl ResolvedConfig {
|
|||
label,
|
||||
backend,
|
||||
clipboard_threshold,
|
||||
pre_paste_delay,
|
||||
includes,
|
||||
excludes,
|
||||
extra_includes,
|
||||
|
|
|
@ -126,52 +126,22 @@ impl DefaultConfigStore {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::MockConfig;
|
||||
|
||||
struct MockConfig {
|
||||
label: String,
|
||||
is_match: bool,
|
||||
}
|
||||
|
||||
impl MockConfig {
|
||||
pub fn new(label: &str, is_match: bool) -> Self {
|
||||
Self {
|
||||
label: label.to_string(),
|
||||
is_match,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config for MockConfig {
|
||||
fn id(&self) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
fn label(&self) -> &str {
|
||||
&self.label
|
||||
}
|
||||
|
||||
fn match_paths(&self) -> &[String] {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn is_match(&self, _: &crate::config::AppProperties) -> bool {
|
||||
self.is_match
|
||||
}
|
||||
|
||||
fn backend(&self) -> crate::config::Backend {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn clipboard_threshold(&self) -> usize {
|
||||
unimplemented!()
|
||||
}
|
||||
pub fn new_mock(label: &'static str, is_match: bool) -> MockConfig {
|
||||
let label = label.to_owned();
|
||||
let mut mock = MockConfig::new();
|
||||
mock.expect_id().return_const(0);
|
||||
mock.expect_label().return_const(label);
|
||||
mock.expect_is_match().return_const(is_match);
|
||||
mock
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_store_selects_correctly() {
|
||||
let default = MockConfig::new("default", false);
|
||||
let custom1 = MockConfig::new("custom1", false);
|
||||
let custom2 = MockConfig::new("custom2", true);
|
||||
let default = new_mock("default", false);
|
||||
let custom1 = new_mock("custom1", false);
|
||||
let custom2 = new_mock("custom2", true);
|
||||
|
||||
let store = DefaultConfigStore {
|
||||
default: Box::new(default),
|
||||
|
@ -193,9 +163,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn config_store_active_fallback_to_default_if_no_match() {
|
||||
let default = MockConfig::new("default", false);
|
||||
let custom1 = MockConfig::new("custom1", false);
|
||||
let custom2 = MockConfig::new("custom2", false);
|
||||
let default = new_mock("default", false);
|
||||
let custom1 = new_mock("custom1", false);
|
||||
let custom2 = new_mock("custom2", false);
|
||||
|
||||
let store = DefaultConfigStore {
|
||||
default: Box::new(default),
|
||||
|
|
|
@ -22,7 +22,10 @@ use regex::Regex;
|
|||
use std::{collections::HashMap, path::Path};
|
||||
|
||||
use self::config::LegacyConfig;
|
||||
use crate::matches::{MatchEffect, group::loader::yaml::parse::{YAMLMatch, YAMLVariable}};
|
||||
use crate::matches::{
|
||||
group::loader::yaml::parse::{YAMLMatch, YAMLVariable},
|
||||
MatchEffect,
|
||||
};
|
||||
use crate::{config::store::DefaultConfigStore, counter::StructId};
|
||||
use crate::{
|
||||
config::Config,
|
||||
|
@ -139,10 +142,7 @@ fn deduplicate_matches(
|
|||
}
|
||||
|
||||
// TODO: test case of matches with inner variables
|
||||
fn deduplicate_vars(
|
||||
vars: &mut [Variable],
|
||||
var_map: &mut HashMap<Variable, StructId>,
|
||||
) {
|
||||
fn deduplicate_vars(vars: &mut [Variable], var_map: &mut HashMap<Variable, StructId>) {
|
||||
for v in vars.iter_mut() {
|
||||
let mut v_without_id = v.clone();
|
||||
v_without_id.id = 0;
|
||||
|
@ -254,7 +254,11 @@ impl Config for LegacyInteropConfig {
|
|||
}
|
||||
|
||||
fn clipboard_threshold(&self) -> usize {
|
||||
100
|
||||
crate::config::default::DEFAULT_CLIPBOARD_THRESHOLD
|
||||
}
|
||||
|
||||
fn pre_paste_delay(&self) -> usize {
|
||||
crate::config::default::DEFAULT_PRE_PASTE_DELAY
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,8 +476,21 @@ mod tests {
|
|||
exec: None,
|
||||
});
|
||||
|
||||
for (i, m) in match_store.query(default_config.match_paths()).matches.into_iter().enumerate() {
|
||||
assert_eq!(m.id, match_store.query(active_config.match_paths()).matches.get(i).unwrap().id);
|
||||
for (i, m) in match_store
|
||||
.query(default_config.match_paths())
|
||||
.matches
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
assert_eq!(
|
||||
m.id,
|
||||
match_store
|
||||
.query(active_config.match_paths())
|
||||
.matches
|
||||
.get(i)
|
||||
.unwrap()
|
||||
.id
|
||||
);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
|
Loading…
Reference in New Issue
Block a user