diff --git a/Cargo.lock b/Cargo.lock index 25c9dd5..6da9d74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,13 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -164,6 +172,7 @@ dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -209,6 +218,11 @@ name = "linked-hash-map" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "memchr" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "nodrop" version = "0.1.13" @@ -296,6 +310,22 @@ dependencies = [ "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rust-argon2" version = "0.5.1" @@ -384,6 +414,14 @@ dependencies = [ "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-width" version = "0.1.6" @@ -437,6 +475,7 @@ dependencies = [ ] [metadata] +"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" @@ -463,6 +502,7 @@ dependencies = [ "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" @@ -474,6 +514,8 @@ dependencies = [ "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" +"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f" @@ -484,6 +526,7 @@ dependencies = [ "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/Cargo.toml b/Cargo.toml index 461e73f..e544e1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.8" dirs = "2.0.2" clap = "2.33.0" +regex = "1.3.1" [build-dependencies] cmake = "0.1.31" \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 46e971f..c8b697b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,6 +9,7 @@ use serde::{Serialize, Deserialize}; use crate::keyboard::KeyModifier; use crate::system::SystemManager; use std::collections::HashSet; +use regex::Regex; // TODO: add documentation link const DEFAULT_CONFIG_FILE_CONTENT : &str = include_str!("res/config.yaml"); @@ -18,18 +19,19 @@ const DEFAULT_CONFIG_FILE_NAME : &str = "default.yaml"; // Default values for primitives fn default_name() -> String{ "default".to_owned() } -fn default_toggle_interval() -> u32 { - 230 -} -fn default_backspace_limit() -> i32 { - 3 -} +fn default_filter_title() -> String{ "".to_owned() } +fn default_toggle_interval() -> u32 { 230 } +fn default_backspace_limit() -> i32 { 3 } +fn default_matches() -> Vec { Vec::new() } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Configs { #[serde(default = "default_name")] pub name: String, + #[serde(default = "default_filter_title")] + pub filter_title: String, + #[serde(default)] pub toggle_key: KeyModifier, @@ -42,6 +44,7 @@ pub struct Configs { #[serde(default)] pub backend: BackendType, + #[serde(default = "default_matches")] pub matches: Vec } @@ -161,37 +164,77 @@ pub trait ConfigManager { pub struct RuntimeConfigManager { set: ConfigSet, + title_regexps: Vec>, system_manager: S } impl RuntimeConfigManager { pub fn new(set: ConfigSet, system_manager: S) -> RuntimeConfigManager { + // Compile all the regexps + let title_regexps = set.specific.iter().map( + |config| { + if config.filter_title.is_empty() { + None + }else{ + let res = Regex::new(&config.filter_title); + if let Ok(regex) = res { + Some(regex) + }else{ + // TODO: log invalid regex error + None + } + } + } + ).collect(); + RuntimeConfigManager { set, + title_regexps, system_manager } } } +impl RuntimeConfigManager { + fn active_config(&self) -> &Configs { + // TODO: optimize performance by avoiding some of these checks if no Configs use the filters + + let active_title = self.system_manager.get_current_window_title(); + + if let Some(title) = active_title { + for (i, regex) in self.title_regexps.iter().enumerate() { + if let Some(regex) = regex { + if regex.is_match(&title) { + return &self.set.specific[i] + } + } + } + } + + // No matches, return the default mapping + &self.set.default + } +} + impl ConfigManager for RuntimeConfigManager { fn toggle_key(&self) -> &KeyModifier { - &self.set.default.toggle_key + &self.active_config().toggle_key } fn toggle_interval(&self) -> u32 { - self.set.default.toggle_interval + self.active_config().toggle_interval } fn backspace_limit(&self) -> i32 { - self.set.default.backspace_limit + self.active_config().backspace_limit } fn backend(&self) -> &BackendType { - &BackendType::Inject // TODO make dynamic based on system current active app + &self.active_config().backend } fn matches(&self) -> &Vec { - &self.set.default.matches + &self.active_config().matches } } \ No newline at end of file