feat(config): port legacy loader to new project
This commit is contained in:
parent
3217865d4b
commit
1e015eb891
55
Cargo.lock
generated
55
Cargo.lock
generated
|
@ -45,6 +45,12 @@ version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake2b_simd"
|
name = "blake2b_simd"
|
||||||
version = "0.5.11"
|
version = "0.5.11"
|
||||||
|
@ -261,7 +267,9 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"tempdir",
|
"tempdir",
|
||||||
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -681,6 +689,15 @@ version = "0.1.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -688,7 +705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.16",
|
"getrandom 0.1.16",
|
||||||
"redox_syscall",
|
"redox_syscall 0.1.57",
|
||||||
"rust-argon2",
|
"rust-argon2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -736,6 +753,15 @@ version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -853,6 +879,20 @@ dependencies = [
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"rand 0.8.3",
|
||||||
|
"redox_syscall 0.2.5",
|
||||||
|
"remove_dir_all",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
@ -935,6 +975,17 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
|
||||||
|
dependencies = [
|
||||||
|
"same-file",
|
||||||
|
"winapi",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.9.0+wasi-snapshot-preview1"
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
|
@ -1012,7 +1063,7 @@ version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621"
|
checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 0.9.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -14,6 +14,8 @@ glob = "0.3.0"
|
||||||
regex = "1.4.3"
|
regex = "1.4.3"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
dunce = "1.0.1"
|
dunce = "1.0.1"
|
||||||
|
walkdir = "2.3.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempdir = "0.3.7"
|
tempdir = "0.3.7"
|
||||||
|
tempfile = "3.2.0"
|
1890
espanso-config/src/legacy/config.rs
Normal file
1890
espanso-config/src/legacy/config.rs
Normal file
File diff suppressed because it is too large
Load Diff
32
espanso-config/src/legacy/mod.rs
Normal file
32
espanso-config/src/legacy/mod.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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::path::Path;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use crate::{config::ConfigStore, matches::store::MatchStore};
|
||||||
|
|
||||||
|
mod config;
|
||||||
|
mod model;
|
||||||
|
|
||||||
|
pub fn load(base_dir: &Path) -> Result<(Box<dyn ConfigStore>, Box<dyn MatchStore>)> {
|
||||||
|
// TODO: load legacy config set and then convert it to the new format
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
61
espanso-config/src/legacy/model.rs
Normal file
61
espanso-config/src/legacy/model.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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 serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum KeyModifier {
|
||||||
|
CTRL,
|
||||||
|
SHIFT,
|
||||||
|
ALT,
|
||||||
|
META,
|
||||||
|
BACKSPACE,
|
||||||
|
OFF,
|
||||||
|
|
||||||
|
// These are specific variants of the ones above. See issue: #117
|
||||||
|
// https://github.com/federico-terzi/espanso/issues/117
|
||||||
|
LEFT_CTRL,
|
||||||
|
RIGHT_CTRL,
|
||||||
|
LEFT_ALT,
|
||||||
|
RIGHT_ALT,
|
||||||
|
LEFT_META,
|
||||||
|
RIGHT_META,
|
||||||
|
LEFT_SHIFT,
|
||||||
|
RIGHT_SHIFT,
|
||||||
|
|
||||||
|
// Special cases, should not be used in config
|
||||||
|
CAPS_LOCK,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub enum PasteShortcut {
|
||||||
|
Default, // Default one for the current system
|
||||||
|
CtrlV, // Classic Ctrl+V shortcut
|
||||||
|
CtrlShiftV, // Could be used to paste without formatting in many applications
|
||||||
|
ShiftInsert, // Often used in Linux systems
|
||||||
|
CtrlAltV, // Used in some Linux terminals (urxvt)
|
||||||
|
MetaV, // Corresponding to Win+V on Windows and Linux, CMD+V on macOS
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PasteShortcut {
|
||||||
|
fn default() -> Self {
|
||||||
|
PasteShortcut::Default
|
||||||
|
}
|
||||||
|
}
|
12
espanso-config/src/legacy/res/test/config_with_bad_yaml.yml
Normal file
12
espanso-config/src/legacy/res/test/config_with_bad_yaml.yml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
backend: Clipboard
|
||||||
|
|
||||||
|
definitely a bad yaml
|
||||||
|
|
||||||
|
matches:
|
||||||
|
# Default
|
||||||
|
- trigger: ":espanso"
|
||||||
|
replace: "Hi there!"
|
||||||
|
|
||||||
|
# Emojis
|
||||||
|
- trigger: ":lol"
|
||||||
|
replace: "😂"
|
30
espanso-config/src/legacy/res/test/default.yml
Normal file
30
espanso-config/src/legacy/res/test/default.yml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# espanso configuration file
|
||||||
|
|
||||||
|
# This is the default configuration file, change it as you like it
|
||||||
|
# You can refer to the official documentation:
|
||||||
|
# https://espanso.org/docs/
|
||||||
|
|
||||||
|
# Matches are the substitution rules, when you type the "trigger" string
|
||||||
|
# it gets replaced by the "replace" string.
|
||||||
|
matches:
|
||||||
|
# Simple text replacement
|
||||||
|
- trigger: ":espanso"
|
||||||
|
replace: "Hi there!"
|
||||||
|
|
||||||
|
# Dates
|
||||||
|
- trigger: ":date"
|
||||||
|
replace: "{{mydate}}"
|
||||||
|
vars:
|
||||||
|
- name: mydate
|
||||||
|
type: date
|
||||||
|
params:
|
||||||
|
format: "%m/%d/%Y"
|
||||||
|
|
||||||
|
# Shell commands
|
||||||
|
- trigger: ":shell"
|
||||||
|
replace: "{{output}}"
|
||||||
|
vars:
|
||||||
|
- name: output
|
||||||
|
type: shell
|
||||||
|
params:
|
||||||
|
cmd: "echo Hello from your shell"
|
10
espanso-config/src/legacy/res/test/working_config.yml
Normal file
10
espanso-config/src/legacy/res/test/working_config.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
backend: Clipboard
|
||||||
|
|
||||||
|
matches:
|
||||||
|
# Default
|
||||||
|
- trigger: ":espanso"
|
||||||
|
replace: "Hi there!"
|
||||||
|
|
||||||
|
# Emojis
|
||||||
|
- trigger: ":lol"
|
||||||
|
replace: "😂"
|
|
@ -28,6 +28,7 @@ extern crate lazy_static;
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
mod counter;
|
mod counter;
|
||||||
|
mod legacy;
|
||||||
pub mod matches;
|
pub mod matches;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
@ -40,12 +41,15 @@ pub fn load(base_path: &Path) -> Result<(impl ConfigStore, impl MatchStore)> {
|
||||||
let config_store = config::load_store(&config_dir)?;
|
let config_store = config::load_store(&config_dir)?;
|
||||||
let root_paths = config_store.get_all_match_paths();
|
let root_paths = config_store.get_all_match_paths();
|
||||||
|
|
||||||
let mut match_store = matches::store::new();
|
let match_store = matches::store::new(&root_paths.into_iter().collect::<Vec<String>>());
|
||||||
match_store.load(&root_paths.into_iter().collect::<Vec<String>>());
|
|
||||||
|
|
||||||
Ok((config_store, match_store))
|
Ok((config_store, match_store))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_legacy_config(base_dir: &Path) -> bool {
|
||||||
|
!base_dir.join("config").is_dir() && !base_dir.join("match").is_dir()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ConfigError {
|
pub enum ConfigError {
|
||||||
#[error("missing config directory")]
|
#[error("missing config directory")]
|
||||||
|
|
|
@ -34,21 +34,21 @@ pub(crate) struct DefaultMatchStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefaultMatchStore {
|
impl DefaultMatchStore {
|
||||||
pub fn new() -> Self {
|
pub fn new(paths: &[String]) -> Self {
|
||||||
|
let mut groups = HashMap::new();
|
||||||
|
|
||||||
|
// Because match groups can imports other match groups,
|
||||||
|
// we have to load them recursively starting from the
|
||||||
|
// top-level ones.
|
||||||
|
load_match_groups_recursively(&mut groups, paths);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
groups: HashMap::new(),
|
groups,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MatchStore for DefaultMatchStore {
|
impl MatchStore for DefaultMatchStore {
|
||||||
fn load(&mut self, paths: &[String]) {
|
|
||||||
// Because match groups can imports other match groups,
|
|
||||||
// we have to load them recursively starting from the
|
|
||||||
// top-level ones.
|
|
||||||
load_match_groups_recursively(&mut self.groups, paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn query(&self, paths: &[String]) -> MatchSet {
|
fn query(&self, paths: &[String]) -> MatchSet {
|
||||||
let mut matches: Vec<&Match> = Vec::new();
|
let mut matches: Vec<&Match> = Vec::new();
|
||||||
let mut global_vars: Vec<&Variable> = Vec::new();
|
let mut global_vars: Vec<&Variable> = Vec::new();
|
||||||
|
@ -223,9 +223,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut match_store = DefaultMatchStore::new();
|
let match_store = DefaultMatchStore::new(&[base_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
match_store.load(&[base_file.to_string_lossy().to_string()]);
|
|
||||||
|
|
||||||
assert_eq!(match_store.groups.len(), 3);
|
assert_eq!(match_store.groups.len(), 3);
|
||||||
|
|
||||||
|
@ -305,9 +303,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut match_store = DefaultMatchStore::new();
|
let match_store = DefaultMatchStore::new(&[base_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
match_store.load(&[base_file.to_string_lossy().to_string()]);
|
|
||||||
|
|
||||||
assert_eq!(match_store.groups.len(), 3);
|
assert_eq!(match_store.groups.len(), 3);
|
||||||
});
|
});
|
||||||
|
@ -368,9 +364,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut match_store = DefaultMatchStore::new();
|
let match_store = DefaultMatchStore::new(&[base_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
match_store.load(&[base_file.to_string_lossy().to_string()]);
|
|
||||||
|
|
||||||
let match_set = match_store.query(&[base_file.to_string_lossy().to_string()]);
|
let match_set = match_store.query(&[base_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
|
@ -457,9 +451,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut match_store = DefaultMatchStore::new();
|
let match_store = DefaultMatchStore::new(&[base_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
match_store.load(&[base_file.to_string_lossy().to_string()]);
|
|
||||||
|
|
||||||
let match_set = match_store.query(&[base_file.to_string_lossy().to_string()]);
|
let match_set = match_store.query(&[base_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
|
@ -540,12 +532,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut match_store = DefaultMatchStore::new();
|
let match_store = DefaultMatchStore::new(&[base_file.to_string_lossy().to_string(), sub_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
match_store.load(&[
|
|
||||||
base_file.to_string_lossy().to_string(),
|
|
||||||
sub_file.to_string_lossy().to_string(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
let match_set = match_store.query(&[
|
let match_set = match_store.query(&[
|
||||||
base_file.to_string_lossy().to_string(),
|
base_file.to_string_lossy().to_string(),
|
||||||
|
@ -632,9 +619,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut match_store = DefaultMatchStore::new();
|
let match_store = DefaultMatchStore::new(&[base_file.to_string_lossy().to_string()]);
|
||||||
|
|
||||||
match_store.load(&[base_file.to_string_lossy().to_string()]);
|
|
||||||
|
|
||||||
let match_set = match_store.query(&[
|
let match_set = match_store.query(&[
|
||||||
base_file.to_string_lossy().to_string(),
|
base_file.to_string_lossy().to_string(),
|
||||||
|
|
|
@ -22,7 +22,6 @@ use super::{Match, Variable};
|
||||||
mod default;
|
mod default;
|
||||||
|
|
||||||
pub trait MatchStore {
|
pub trait MatchStore {
|
||||||
fn load(&mut self, paths: &[String]);
|
|
||||||
fn query(&self, paths: &[String]) -> MatchSet;
|
fn query(&self, paths: &[String]) -> MatchSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,8 +31,8 @@ pub struct MatchSet<'a> {
|
||||||
pub global_vars: Vec<&'a Variable>,
|
pub global_vars: Vec<&'a Variable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> impl MatchStore {
|
pub fn new(paths: &[String]) -> impl MatchStore {
|
||||||
// TODO: here we can replace the DefaultMatchStore with a caching wrapper
|
// TODO: here we can replace the DefaultMatchStore with a caching wrapper
|
||||||
// that returns the same response for the given "paths" query
|
// that returns the same response for the given "paths" query
|
||||||
default::DefaultMatchStore::new()
|
default::DefaultMatchStore::new(paths)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
pub fn is_yaml_empty(yaml: &str) -> bool {
|
pub fn is_yaml_empty(yaml: &str) -> bool {
|
||||||
for line in yaml.lines() {
|
for line in yaml.lines() {
|
||||||
let trimmed_line = line.trim();
|
let trimmed_line = line.trim();
|
||||||
if !trimmed_line.starts_with("#") && !trimmed_line.is_empty() {
|
if !trimmed_line.starts_with('#') && !trimmed_line.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user