From 5a729f581049842c69eebe25a2f296d414e773ac Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Mon, 19 Apr 2021 22:03:29 +0200 Subject: [PATCH] feat(config): introduce the uppercase_style option for matches (related to #625) --- .../src/matches/group/loader/yaml/mod.rs | 104 +++++++++++++++++- .../src/matches/group/loader/yaml/parse.rs | 3 + espanso-config/src/matches/mod.rs | 13 ++- 3 files changed, 114 insertions(+), 6 deletions(-) diff --git a/espanso-config/src/matches/group/loader/yaml/mod.rs b/espanso-config/src/matches/group/loader/yaml/mod.rs index 37053a5..e99580c 100644 --- a/espanso-config/src/matches/group/loader/yaml/mod.rs +++ b/espanso-config/src/matches/group/loader/yaml/mod.rs @@ -21,15 +21,18 @@ use crate::{ counter::next_id, matches::{ group::{path::resolve_imports, MatchGroup}, - Match, Variable, + Match, UpperCasingStyle, Variable, }, }; use anyhow::Result; -use log::warn; +use log::{error, warn}; use parse::YAMLMatchGroup; use std::convert::{TryFrom, TryInto}; -use self::{parse::{YAMLMatch, YAMLVariable}, util::convert_params}; +use self::{ + parse::{YAMLMatch, YAMLVariable}, + util::convert_params, +}; use crate::matches::{MatchCause, MatchEffect, TextEffect, TriggerCause}; use super::Importer; @@ -89,6 +92,10 @@ impl TryFrom for Match { type Error = anyhow::Error; fn try_from(yaml_match: YAMLMatch) -> Result { + if yaml_match.uppercase_style.is_some() && yaml_match.propagate_case.is_none() { + warn!("specifying the 'uppercase_style' option without 'propagate_case' has no effect"); + } + let triggers = if let Some(trigger) = yaml_match.trigger { Some(vec![trigger]) } else if let Some(triggers) = yaml_match.triggers { @@ -97,6 +104,24 @@ impl TryFrom for Match { None }; + let uppercase_style = match yaml_match + .uppercase_style + .map(|s| s.to_lowercase()) + .as_deref() + { + Some("uppercase") => UpperCasingStyle::Uppercase, + Some("capitalize") => UpperCasingStyle::Capitalize, + Some("capitalize_words") => UpperCasingStyle::CapitalizeWords, + Some(style) => { + error!( + "unrecognized uppercase_style: {:?}, falling back to the default", + style + ); + TriggerCause::default().uppercase_style + } + _ => TriggerCause::default().uppercase_style, + }; + let cause = if let Some(triggers) = triggers { MatchCause::Trigger(TriggerCause { triggers, @@ -111,6 +136,7 @@ impl TryFrom for Match { propagate_case: yaml_match .propagate_case .unwrap_or(TriggerCause::default().propagate_case), + uppercase_style, }) } else { MatchCause::None @@ -163,7 +189,10 @@ impl TryFrom for Variable { #[cfg(test)] mod tests { use super::*; - use crate::{matches::{Match, Params, Value}, util::tests::use_test_directory}; + use crate::{ + matches::{Match, Params, Value}, + util::tests::use_test_directory, + }; use std::fs::create_dir_all; fn create_match(yaml: &str) -> Result { @@ -332,6 +361,73 @@ mod tests { ) } + #[test] + fn uppercase_style_maps_correctly() { + assert_eq!( + create_match( + r#" + trigger: "Hello" + replace: "world" + uppercase_style: "capitalize" + "# + ) + .unwrap() + .cause + .into_trigger() + .unwrap() + .uppercase_style, + UpperCasingStyle::Capitalize, + ); + + assert_eq!( + create_match( + r#" + trigger: "Hello" + replace: "world" + uppercase_style: "capitalize_words" + "# + ) + .unwrap() + .cause + .into_trigger() + .unwrap() + .uppercase_style, + UpperCasingStyle::CapitalizeWords, + ); + + assert_eq!( + create_match( + r#" + trigger: "Hello" + replace: "world" + uppercase_style: "uppercase" + "# + ) + .unwrap() + .cause + .into_trigger() + .unwrap() + .uppercase_style, + UpperCasingStyle::Uppercase, + ); + + assert_eq!( + create_match( + r#" + trigger: "Hello" + replace: "world" + uppercase_style: "invalid" + "# + ) + .unwrap() + .cause + .into_trigger() + .unwrap() + .uppercase_style, + UpperCasingStyle::Uppercase, + ); + } + #[test] fn vars_maps_correctly() { let mut params = Params::new(); diff --git a/espanso-config/src/matches/group/loader/yaml/parse.rs b/espanso-config/src/matches/group/loader/yaml/parse.rs index 8d41ab2..c2039bd 100644 --- a/espanso-config/src/matches/group/loader/yaml/parse.rs +++ b/espanso-config/src/matches/group/loader/yaml/parse.rs @@ -91,6 +91,9 @@ pub struct YAMLMatch { #[serde(default)] pub propagate_case: Option, + #[serde(default)] + pub uppercase_style: Option, + #[serde(default)] pub force_clipboard: Option, diff --git a/espanso-config/src/matches/mod.rs b/espanso-config/src/matches/mod.rs index fb322f1..a452487 100644 --- a/espanso-config/src/matches/mod.rs +++ b/espanso-config/src/matches/mod.rs @@ -50,7 +50,7 @@ impl Default for Match { // Causes -#[derive(Debug, Clone, Eq, Hash, PartialEq)] +#[derive(Debug, Clone, Eq, Hash, PartialEq, EnumAsInner)] pub enum MatchCause { None, Trigger(TriggerCause), @@ -66,6 +66,7 @@ pub struct TriggerCause { pub right_word: bool, pub propagate_case: bool, + pub uppercase_style: UpperCasingStyle, } impl Default for TriggerCause { @@ -75,13 +76,21 @@ impl Default for TriggerCause { left_word: false, right_word: false, propagate_case: false, + uppercase_style: UpperCasingStyle::Uppercase, } } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum UpperCasingStyle { + Uppercase, + Capitalize, + CapitalizeWords, +} + // Effects -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, EnumAsInner)] pub enum MatchEffect { None, Text(TextEffect),