Fix formatting
This commit is contained in:
parent
161017f024
commit
411078a503
|
@ -282,7 +282,7 @@ pub struct Configs {
|
|||
pub global_vars: Vec<MatchVariable>,
|
||||
|
||||
#[serde(default = "default_modulo_path")]
|
||||
pub modulo_path: Option<String>
|
||||
pub modulo_path: Option<String>,
|
||||
}
|
||||
|
||||
// Macro used to validate config fields
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
use crate::clipboard::ClipboardManager;
|
||||
use crate::config::BackendType;
|
||||
use crate::config::{Configs, ConfigManager};
|
||||
use crate::config::{ConfigManager, Configs};
|
||||
use crate::event::{ActionEventReceiver, ActionType, SystemEvent, SystemEventReceiver};
|
||||
use crate::keyboard::KeyboardManager;
|
||||
use crate::matcher::{Match, MatchReceiver};
|
||||
|
@ -158,9 +158,7 @@ impl<
|
|||
if cfg!(target_os = "linux") {
|
||||
let all_ascii = target_string.chars().all(|c| c.is_ascii());
|
||||
if all_ascii {
|
||||
debug!(
|
||||
"All elements of the replacement are ascii, using Inject backend"
|
||||
);
|
||||
debug!("All elements of the replacement are ascii, using Inject backend");
|
||||
&BackendType::Inject
|
||||
} else {
|
||||
debug!("There are non-ascii characters, using Clipboard backend");
|
||||
|
@ -273,7 +271,10 @@ impl<
|
|||
|
||||
// Disallow undo backspace if cursor positioning is used
|
||||
if cursor_rewind.is_none() {
|
||||
expansion_data = Some((m.triggers[trigger_offset].clone(), target_string.chars().count() as i32));
|
||||
expansion_data = Some((
|
||||
m.triggers[trigger_offset].clone(),
|
||||
target_string.chars().count() as i32,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(moves) = cursor_rewind {
|
||||
|
@ -310,7 +311,9 @@ impl<
|
|||
// giving back the control. Otherwise, the injected actions will be handled back
|
||||
// by espanso itself.
|
||||
if cfg!(target_os = "macos") {
|
||||
std::thread::sleep(std::time::Duration::from_millis(config.mac_post_inject_delay));
|
||||
std::thread::sleep(std::time::Duration::from_millis(
|
||||
config.mac_post_inject_delay,
|
||||
));
|
||||
}
|
||||
|
||||
// Re-allow espanso to interpret actions
|
||||
|
@ -350,7 +353,8 @@ impl<
|
|||
if let Some(ref last_expansion_data) = *last_expansion_data {
|
||||
let (trigger_string, injected_text_len) = last_expansion_data;
|
||||
// Delete the previously injected text, minus one character as it has been consumed by the backspace
|
||||
self.keyboard_manager.delete_string(&config, *injected_text_len - 1);
|
||||
self.keyboard_manager
|
||||
.delete_string(&config, *injected_text_len - 1);
|
||||
// Restore previous text
|
||||
self.inject_text(&config, trigger_string, false);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
*/
|
||||
|
||||
use crate::clipboard::ClipboardManager;
|
||||
use serde_yaml::Mapping;
|
||||
use crate::extension::ExtensionResult;
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct ClipboardExtension {
|
||||
|
@ -37,7 +37,12 @@ impl super::Extension for ClipboardExtension {
|
|||
String::from("clipboard")
|
||||
}
|
||||
|
||||
fn calculate(&self, _: &Mapping, _: &Vec<String>, _: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
_: &Mapping,
|
||||
_: &Vec<String>,
|
||||
_: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
if let Some(clipboard) = self.clipboard_manager.get_clipboard() {
|
||||
Some(ExtensionResult::Single(clipboard))
|
||||
} else {
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use chrono::{DateTime, Local, Duration};
|
||||
use crate::extension::ExtensionResult;
|
||||
use chrono::{DateTime, Duration, Local};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
use crate::extension::ExtensionResult;
|
||||
|
||||
pub struct DateExtension {}
|
||||
|
||||
|
@ -35,13 +35,18 @@ impl super::Extension for DateExtension {
|
|||
String::from("date")
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, _: &Vec<String>, _: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
_: &Vec<String>,
|
||||
_: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let mut now: DateTime<Local> = Local::now();
|
||||
|
||||
// Compute the given offset
|
||||
let offset = params.get(&Value::from("offset"));
|
||||
if let Some(offset) = offset {
|
||||
let seconds = offset.as_i64().unwrap_or_else(|| { 0 });
|
||||
let seconds = offset.as_i64().unwrap_or_else(|| 0);
|
||||
let offset = Duration::seconds(seconds);
|
||||
now = now + offset;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::extension::ExtensionResult;
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
use crate::extension::ExtensionResult;
|
||||
|
||||
pub struct DummyExtension {
|
||||
name: String,
|
||||
|
@ -38,11 +38,18 @@ impl super::Extension for DummyExtension {
|
|||
self.name.clone()
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, _: &Vec<String>, _: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
_: &Vec<String>,
|
||||
_: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let echo = params.get(&Value::from("echo"));
|
||||
|
||||
if let Some(echo) = echo {
|
||||
Some(ExtensionResult::Single(echo.as_str().unwrap_or_default().to_owned()))
|
||||
Some(ExtensionResult::Single(
|
||||
echo.as_str().unwrap_or_default().to_owned(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::{config::Configs, extension::ExtensionResult, ui::modulo::ModuloManager};
|
||||
use log::{error, warn};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
use crate::{ui::modulo::ModuloManager, extension::ExtensionResult, config::Configs};
|
||||
use log::{error, warn};
|
||||
|
||||
pub struct FormExtension {
|
||||
manager: ModuloManager,
|
||||
|
@ -29,9 +29,7 @@ pub struct FormExtension {
|
|||
impl FormExtension {
|
||||
pub fn new(config: &Configs) -> FormExtension {
|
||||
let manager = ModuloManager::new(config);
|
||||
FormExtension {
|
||||
manager,
|
||||
}
|
||||
FormExtension { manager }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +38,12 @@ impl super::Extension for FormExtension {
|
|||
"form".to_owned()
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, _: &Vec<String>, _: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
_: &Vec<String>,
|
||||
_: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let layout = params.get(&Value::from("layout"));
|
||||
let layout = if let Some(value) = layout {
|
||||
value.as_str().unwrap_or_default().to_string()
|
||||
|
@ -56,9 +59,12 @@ impl super::Extension for FormExtension {
|
|||
form_config.insert(Value::from("fields"), fields.clone());
|
||||
}
|
||||
|
||||
let serialized_config: String = serde_yaml::to_string(&form_config).expect("unable to serialize form config");
|
||||
let serialized_config: String =
|
||||
serde_yaml::to_string(&form_config).expect("unable to serialize form config");
|
||||
|
||||
let output = self.manager.invoke(&["form", "-i", "-"], &serialized_config);
|
||||
let output = self
|
||||
.manager
|
||||
.invoke(&["form", "-i", "-"], &serialized_config);
|
||||
|
||||
// On macOS, after the form closes we have to wait until the user releases the modifier keys
|
||||
on_form_close();
|
||||
|
|
|
@ -17,20 +17,20 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::{config::Configs, clipboard::ClipboardManager};
|
||||
use crate::{clipboard::ClipboardManager, config::Configs};
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::HashMap;
|
||||
|
||||
mod clipboard;
|
||||
mod date;
|
||||
pub mod dummy;
|
||||
mod form;
|
||||
pub mod multiecho;
|
||||
mod random;
|
||||
mod script;
|
||||
mod shell;
|
||||
pub mod multiecho;
|
||||
pub mod vardummy;
|
||||
mod utils;
|
||||
mod form;
|
||||
pub mod vardummy;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ExtensionResult {
|
||||
|
@ -40,10 +40,18 @@ pub enum ExtensionResult {
|
|||
|
||||
pub trait Extension {
|
||||
fn name(&self) -> String;
|
||||
fn calculate(&self, params: &Mapping, args: &Vec<String>, current_vars: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult>;
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
args: &Vec<String>,
|
||||
current_vars: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult>;
|
||||
}
|
||||
|
||||
pub fn get_extensions(config: &Configs, clipboard_manager: Box<dyn ClipboardManager>) -> Vec<Box<dyn Extension>> {
|
||||
pub fn get_extensions(
|
||||
config: &Configs,
|
||||
clipboard_manager: Box<dyn ClipboardManager>,
|
||||
) -> Vec<Box<dyn Extension>> {
|
||||
vec![
|
||||
Box::new(date::DateExtension::new()),
|
||||
Box::new(shell::ShellExtension::new()),
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::extension::ExtensionResult;
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
use crate::extension::ExtensionResult;
|
||||
|
||||
pub struct MultiEchoExtension {}
|
||||
|
||||
|
@ -34,7 +34,12 @@ impl super::Extension for MultiEchoExtension {
|
|||
"multiecho".to_owned()
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, _: &Vec<String>, _: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
_: &Vec<String>,
|
||||
_: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let mut output: HashMap<String, String> = HashMap::new();
|
||||
for (key, value) in params.iter() {
|
||||
if let Some(key) = key.as_str() {
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::extension::ExtensionResult;
|
||||
use log::{error, warn};
|
||||
use rand::seq::SliceRandom;
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
use crate::extension::ExtensionResult;
|
||||
|
||||
pub struct RandomExtension {}
|
||||
|
||||
|
@ -36,7 +36,12 @@ impl super::Extension for RandomExtension {
|
|||
String::from("random")
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, args: &Vec<String>, _: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
args: &Vec<String>,
|
||||
_: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let choices = params.get(&Value::from("choices"));
|
||||
if choices.is_none() {
|
||||
warn!("No 'choices' parameter specified for random variable");
|
||||
|
@ -89,7 +94,9 @@ mod tests {
|
|||
|
||||
let output = output.unwrap();
|
||||
|
||||
assert!(choices.into_iter().any(|x| ExtensionResult::Single(x.to_owned()) == output));
|
||||
assert!(choices
|
||||
.into_iter()
|
||||
.any(|x| ExtensionResult::Single(x.to_owned()) == output));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -107,6 +114,8 @@ mod tests {
|
|||
|
||||
let rendered_choices = vec!["first test", "second test", "test third"];
|
||||
|
||||
assert!(rendered_choices.into_iter().any(|x| ExtensionResult::Single(x.to_owned()) == output));
|
||||
assert!(rendered_choices
|
||||
.into_iter()
|
||||
.any(|x| ExtensionResult::Single(x.to_owned()) == output));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::extension::ExtensionResult;
|
||||
use log::{error, warn};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::collections::HashMap;
|
||||
use crate::extension::ExtensionResult;
|
||||
|
||||
pub struct ScriptExtension {}
|
||||
|
||||
|
@ -37,7 +37,12 @@ impl super::Extension for ScriptExtension {
|
|||
String::from("script")
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, user_args: &Vec<String>, vars: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
user_args: &Vec<String>,
|
||||
vars: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let args = params.get(&Value::from("args"));
|
||||
if args.is_none() {
|
||||
warn!("No 'args' parameter specified for script variable");
|
||||
|
@ -69,10 +74,20 @@ impl super::Extension for ScriptExtension {
|
|||
*arg = arg.replace("%HOME%", &home_dir.to_string_lossy().to_string());
|
||||
}
|
||||
if arg.contains("%CONFIG%") {
|
||||
*arg = arg.replace("%CONFIG%", &crate::context::get_config_dir().to_string_lossy().to_string());
|
||||
*arg = arg.replace(
|
||||
"%CONFIG%",
|
||||
&crate::context::get_config_dir()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
if arg.contains("%PACKAGES%") {
|
||||
*arg = arg.replace("%PACKAGES%", &crate::context::get_package_dir().to_string_lossy().to_string());
|
||||
*arg = arg.replace(
|
||||
"%PACKAGES%",
|
||||
&crate::context::get_package_dir()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
// On Windows, correct paths separators
|
||||
|
@ -162,7 +177,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec![], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -179,7 +197,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec![], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world\n".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world\n".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -195,7 +216,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec!["jon".to_owned()], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -212,7 +236,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec!["jon".to_owned()], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world jon".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world jon".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -228,12 +255,18 @@ mod tests {
|
|||
let mut subvars = HashMap::new();
|
||||
subvars.insert("name".to_owned(), "John".to_owned());
|
||||
vars.insert("form1".to_owned(), ExtensionResult::Multiple(subvars));
|
||||
vars.insert("var1".to_owned(), ExtensionResult::Single("hello".to_owned()));
|
||||
vars.insert(
|
||||
"var1".to_owned(),
|
||||
ExtensionResult::Single("hello".to_owned()),
|
||||
);
|
||||
|
||||
let extension = ScriptExtension::new();
|
||||
let output = extension.calculate(¶ms, &vec![], &vars);
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello John".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello John".to_owned())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::extension::ExtensionResult;
|
||||
use log::{error, info, warn};
|
||||
use regex::{Captures, Regex};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::process::{Command, Output};
|
||||
use std::collections::HashMap;
|
||||
use crate::extension::ExtensionResult;
|
||||
use std::process::{Command, Output};
|
||||
|
||||
lazy_static! {
|
||||
static ref POS_ARG_REGEX: Regex = if cfg!(target_os = "windows") {
|
||||
|
@ -150,7 +150,12 @@ impl super::Extension for ShellExtension {
|
|||
String::from("shell")
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, args: &Vec<String>, vars: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
args: &Vec<String>,
|
||||
vars: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let cmd = params.get(&Value::from("cmd"));
|
||||
if cmd.is_none() {
|
||||
warn!("No 'cmd' parameter specified for shell variable");
|
||||
|
@ -260,9 +265,15 @@ mod tests {
|
|||
assert!(output.is_some());
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world\r\n".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world\r\n".to_owned())
|
||||
);
|
||||
} else {
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world\n".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world\n".to_owned())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +286,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec![], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -290,7 +304,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec![], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -303,7 +320,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec![], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -317,7 +337,10 @@ mod tests {
|
|||
let output = extension.calculate(¶ms, &vec![], &HashMap::new());
|
||||
|
||||
assert!(output.is_some());
|
||||
assert_eq!(output.unwrap(), ExtensionResult::Single("hello world".to_owned()));
|
||||
assert_eq!(
|
||||
output.unwrap(),
|
||||
ExtensionResult::Single("hello world".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -360,7 +383,10 @@ mod tests {
|
|||
|
||||
let extension = ShellExtension::new();
|
||||
let mut vars: HashMap<String, ExtensionResult> = HashMap::new();
|
||||
vars.insert("var1".to_owned(), ExtensionResult::Single("hello".to_owned()));
|
||||
vars.insert(
|
||||
"var1".to_owned(),
|
||||
ExtensionResult::Single("hello".to_owned()),
|
||||
);
|
||||
let output = extension.calculate(¶ms, &vec![], &vars);
|
||||
|
||||
assert!(output.is_some());
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use crate::extension::ExtensionResult;
|
||||
use std::collections::HashMap;
|
||||
use std::process::Command;
|
||||
use crate::extension::ExtensionResult;
|
||||
|
||||
pub fn convert_to_env_variables(original_vars: &HashMap<String, ExtensionResult>) -> HashMap<String, String> {
|
||||
pub fn convert_to_env_variables(
|
||||
original_vars: &HashMap<String, ExtensionResult>,
|
||||
) -> HashMap<String, String> {
|
||||
let mut output = HashMap::new();
|
||||
|
||||
for (key, result) in original_vars.iter() {
|
||||
|
@ -10,13 +12,13 @@ pub fn convert_to_env_variables(original_vars: &HashMap<String, ExtensionResult>
|
|||
ExtensionResult::Single(value) => {
|
||||
let name = format!("ESPANSO_{}", key.to_uppercase());
|
||||
output.insert(name, value.clone());
|
||||
},
|
||||
}
|
||||
ExtensionResult::Multiple(values) => {
|
||||
for (sub_key, sub_value) in values.iter() {
|
||||
let name = format!("ESPANSO_{}_{}", key.to_uppercase(), sub_key.to_uppercase());
|
||||
output.insert(name, sub_value.clone());
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +38,6 @@ pub fn set_command_flags(command: &mut Command) {
|
|||
// NOOP on Linux and macOS
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -49,7 +50,10 @@ mod tests {
|
|||
subvars.insert("name".to_owned(), "John".to_owned());
|
||||
subvars.insert("lastname".to_owned(), "Snow".to_owned());
|
||||
vars.insert("form1".to_owned(), ExtensionResult::Multiple(subvars));
|
||||
vars.insert("var1".to_owned(), ExtensionResult::Single("test".to_owned()));
|
||||
vars.insert(
|
||||
"var1".to_owned(),
|
||||
ExtensionResult::Single("test".to_owned()),
|
||||
);
|
||||
|
||||
let output = convert_to_env_variables(&vars);
|
||||
assert_eq!(output.get("ESPANSO_FORM1_NAME").unwrap(), "John");
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::extension::ExtensionResult;
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashMap;
|
||||
use crate::extension::ExtensionResult;
|
||||
|
||||
pub struct VarDummyExtension {}
|
||||
|
||||
|
@ -34,7 +34,12 @@ impl super::Extension for VarDummyExtension {
|
|||
"vardummy".to_owned()
|
||||
}
|
||||
|
||||
fn calculate(&self, params: &Mapping, _: &Vec<String>, vars: &HashMap<String, ExtensionResult>) -> Option<ExtensionResult> {
|
||||
fn calculate(
|
||||
&self,
|
||||
params: &Mapping,
|
||||
_: &Vec<String>,
|
||||
vars: &HashMap<String, ExtensionResult>,
|
||||
) -> Option<ExtensionResult> {
|
||||
let target = params.get(&Value::from("target"));
|
||||
|
||||
if let Some(target) = target {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
use super::PasteShortcut;
|
||||
use crate::bridge::macos::*;
|
||||
use crate::config::Configs;
|
||||
use log::{error};
|
||||
use log::error;
|
||||
use std::ffi::CString;
|
||||
|
||||
pub struct MacKeyboardManager {}
|
||||
|
@ -81,7 +81,7 @@ pub fn wait_for_modifiers_release() -> bool {
|
|||
while start.elapsed().unwrap_or_default().as_millis() < 3000 {
|
||||
let pressed = unsafe { crate::bridge::macos::are_modifiers_pressed() };
|
||||
if pressed == 0 {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -582,8 +582,13 @@ fn watcher_background(sender: Sender<Event>) {
|
|||
};
|
||||
|
||||
if let Some(path) = path {
|
||||
if path.extension().unwrap_or_default() == "yml" &&
|
||||
!path.file_name().unwrap_or_default().to_string_lossy().starts_with("."){
|
||||
if path.extension().unwrap_or_default() == "yml"
|
||||
&& !path
|
||||
.file_name()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.starts_with(".")
|
||||
{
|
||||
// Only load non-hidden yml files
|
||||
true
|
||||
} else {
|
||||
|
@ -688,7 +693,10 @@ fn worker_background(
|
|||
|
||||
let keyboard_manager = keyboard::get_manager();
|
||||
|
||||
let extensions = extension::get_extensions(config_manager.default_config(), Box::new(clipboard::get_manager()));
|
||||
let extensions = extension::get_extensions(
|
||||
config_manager.default_config(),
|
||||
Box::new(clipboard::get_manager()),
|
||||
);
|
||||
|
||||
let renderer =
|
||||
render::default::DefaultRenderer::new(extensions, config_manager.default_config().clone());
|
||||
|
|
|
@ -75,7 +75,8 @@ impl<'de> serde::Deserialize<'de> for Match {
|
|||
impl<'a> From<&'a AutoMatch> for Match {
|
||||
fn from(other: &'a AutoMatch) -> Self {
|
||||
lazy_static! {
|
||||
static ref VAR_REGEX: Regex = Regex::new("\\{\\{\\s*(\\w+)(\\.\\w+)?\\s*\\}\\}").unwrap();
|
||||
static ref VAR_REGEX: Regex =
|
||||
Regex::new("\\{\\{\\s*(\\w+)(\\.\\w+)?\\s*\\}\\}").unwrap();
|
||||
};
|
||||
|
||||
let mut triggers = if !other.triggers.is_empty() {
|
||||
|
@ -145,7 +146,8 @@ impl<'a> From<&'a AutoMatch> for Match {
|
|||
};
|
||||
|
||||
MatchContentType::Text(content)
|
||||
} else if let Some(form) = &other.form { // Form shorthand
|
||||
} else if let Some(form) = &other.form {
|
||||
// Form shorthand
|
||||
// Replace all the form fields with actual variables
|
||||
let new_replace = VAR_REGEX.replace_all(&form, |caps: &Captures| {
|
||||
let var_name = caps.get(1).unwrap().as_str();
|
||||
|
@ -164,13 +166,11 @@ impl<'a> From<&'a AutoMatch> for Match {
|
|||
}
|
||||
params.insert(Value::from("layout"), Value::from(form.to_owned()));
|
||||
|
||||
let vars = vec![
|
||||
MatchVariable {
|
||||
let vars = vec![MatchVariable {
|
||||
name: "form1".to_owned(),
|
||||
var_type: "form".to_owned(),
|
||||
params,
|
||||
}
|
||||
];
|
||||
}];
|
||||
|
||||
let content = TextContent {
|
||||
replace: new_replace,
|
||||
|
@ -603,20 +603,24 @@ mod tests {
|
|||
match _match.content {
|
||||
MatchContentType::Text(content) => {
|
||||
let mut mapping = Mapping::new();
|
||||
mapping.insert(Value::from("layout"), Value::from("Hey {{name}}, how are you? {{greet}}"));
|
||||
assert_eq!(content, TextContent {
|
||||
mapping.insert(
|
||||
Value::from("layout"),
|
||||
Value::from("Hey {{name}}, how are you? {{greet}}"),
|
||||
);
|
||||
assert_eq!(
|
||||
content,
|
||||
TextContent {
|
||||
replace: "Hey {{form1.name}}, how are you? {{form1.greet}}".to_owned(),
|
||||
_has_vars: true,
|
||||
vars: vec![
|
||||
MatchVariable {
|
||||
vars: vec![MatchVariable {
|
||||
name: "form1".to_owned(),
|
||||
var_type: "form".to_owned(),
|
||||
params: mapping,
|
||||
}]
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
_ => panic!("wrong content")
|
||||
);
|
||||
}
|
||||
_ => panic!("wrong content"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,20 +643,24 @@ mod tests {
|
|||
submapping.insert(Value::from("name"), Value::from(name_mapping));
|
||||
let mut mapping = Mapping::new();
|
||||
mapping.insert(Value::from("fields"), Value::from(submapping));
|
||||
mapping.insert(Value::from("layout"), Value::from("Hey {{name}}, how are you? {{greet}}"));
|
||||
assert_eq!(content, TextContent {
|
||||
mapping.insert(
|
||||
Value::from("layout"),
|
||||
Value::from("Hey {{name}}, how are you? {{greet}}"),
|
||||
);
|
||||
assert_eq!(
|
||||
content,
|
||||
TextContent {
|
||||
replace: "Hey {{form1.name}}, how are you? {{form1.greet}}".to_owned(),
|
||||
_has_vars: true,
|
||||
vars: vec![
|
||||
MatchVariable {
|
||||
vars: vec![MatchVariable {
|
||||
name: "form1".to_owned(),
|
||||
var_type: "form".to_owned(),
|
||||
params: mapping,
|
||||
}]
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
_ => panic!("wrong content")
|
||||
);
|
||||
}
|
||||
_ => panic!("wrong content"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,7 +213,6 @@ impl<'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMat
|
|||
self.receiver
|
||||
.on_match(mtc, trailing_separator, entry.trigger_offset);
|
||||
|
||||
|
||||
(*was_previous_char_a_match) = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ use serde_yaml::Value;
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
lazy_static! {
|
||||
static ref VAR_REGEX: Regex = Regex::new(r"\{\{\s*((?P<name>\w+)(\.(?P<subname>(\w+)))?)\s*\}\}").unwrap();
|
||||
static ref VAR_REGEX: Regex =
|
||||
Regex::new(r"\{\{\s*((?P<name>\w+)(\.(?P<subname>(\w+)))?)\s*\}\}").unwrap();
|
||||
static ref UNKNOWN_VARIABLE: String = "".to_string();
|
||||
}
|
||||
|
||||
|
@ -95,9 +96,8 @@ impl super::Renderer for DefaultRenderer {
|
|||
target_vars.insert(var_name.to_owned());
|
||||
}
|
||||
|
||||
let match_variables: HashSet<&String> = content.vars.iter().map(|var| {
|
||||
&var.name
|
||||
}).collect();
|
||||
let match_variables: HashSet<&String> =
|
||||
content.vars.iter().map(|var| &var.name).collect();
|
||||
|
||||
// Find the global variables that are not specified in the var list
|
||||
let mut missing_globals = Vec::new();
|
||||
|
@ -120,14 +120,18 @@ impl super::Renderer for DefaultRenderer {
|
|||
variables.extend(&content.vars);
|
||||
|
||||
// Replace variable type "global" with the actual reference
|
||||
let variables: Vec<&MatchVariable> = variables.into_iter().map(|variable| {
|
||||
let variables: Vec<&MatchVariable> = variables
|
||||
.into_iter()
|
||||
.map(|variable| {
|
||||
if variable.var_type == "global" {
|
||||
if let Some(actual_variable) = specified_globals.get(&variable.name) {
|
||||
if let Some(actual_variable) = specified_globals.get(&variable.name)
|
||||
{
|
||||
return actual_variable.clone();
|
||||
}
|
||||
}
|
||||
variable
|
||||
}).collect();
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut output_map: HashMap<String, ExtensionResult> = HashMap::new();
|
||||
|
||||
|
@ -178,11 +182,15 @@ impl super::Renderer for DefaultRenderer {
|
|||
// Normal extension variables
|
||||
let extension = self.extension_map.get(&variable.var_type);
|
||||
if let Some(extension) = extension {
|
||||
let ext_out = extension.calculate(&variable.params, &args, &output_map);
|
||||
let ext_out =
|
||||
extension.calculate(&variable.params, &args, &output_map);
|
||||
if let Some(output) = ext_out {
|
||||
output_map.insert(variable.name.clone(), output);
|
||||
} else {
|
||||
output_map.insert(variable.name.clone(), ExtensionResult::Single("".to_owned()));
|
||||
output_map.insert(
|
||||
variable.name.clone(),
|
||||
ExtensionResult::Single("".to_owned()),
|
||||
);
|
||||
warn!(
|
||||
"Could not generate output for variable: {}",
|
||||
variable.name
|
||||
|
@ -202,28 +210,23 @@ impl super::Renderer for DefaultRenderer {
|
|||
let var_name = caps.name("name").unwrap().as_str();
|
||||
let var_subname = caps.name("subname");
|
||||
match output_map.get(var_name) {
|
||||
Some(result) => {
|
||||
match result {
|
||||
ExtensionResult::Single(output) => {
|
||||
output
|
||||
},
|
||||
ExtensionResult::Multiple(results) => {
|
||||
match var_subname {
|
||||
Some(result) => match result {
|
||||
ExtensionResult::Single(output) => output,
|
||||
ExtensionResult::Multiple(results) => match var_subname {
|
||||
Some(var_subname) => {
|
||||
let var_subname = var_subname.as_str();
|
||||
results.get(var_subname).unwrap_or(&UNKNOWN_VARIABLE)
|
||||
},
|
||||
}
|
||||
None => {
|
||||
error!("nested name missing from multi-value variable: {}", var_name);
|
||||
error!(
|
||||
"nested name missing from multi-value variable: {}",
|
||||
var_name
|
||||
);
|
||||
&UNKNOWN_VARIABLE
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
None => {
|
||||
&UNKNOWN_VARIABLE
|
||||
},
|
||||
None => &UNKNOWN_VARIABLE,
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -793,8 +796,6 @@ mod tests {
|
|||
verify_render(rendered, "RESULT");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_render_variable_order() {
|
||||
let config = get_config_for(
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::config::Configs;
|
||||
use std::process::{Command, Child, Output};
|
||||
use log::{error, info};
|
||||
use std::io::{Error, Write};
|
||||
use std::process::{Child, Command, Output};
|
||||
|
||||
pub mod form;
|
||||
|
||||
|
@ -15,7 +15,8 @@ impl ModuloManager {
|
|||
// Check if the `MODULO_PATH` env variable is configured
|
||||
if let Some(_modulo_path) = std::env::var_os("MODULO_PATH") {
|
||||
modulo_path = Some(_modulo_path.to_string_lossy().to_string())
|
||||
} else if let Some(ref _modulo_path) = config.modulo_path { // Check the configs
|
||||
} else if let Some(ref _modulo_path) = config.modulo_path {
|
||||
// Check the configs
|
||||
modulo_path = Some(_modulo_path.to_owned());
|
||||
} else {
|
||||
// Check in the same directory of espanso
|
||||
|
@ -46,9 +47,7 @@ impl ModuloManager {
|
|||
info!("Using modulo at {:?}", modulo_path);
|
||||
}
|
||||
|
||||
Self {
|
||||
modulo_path,
|
||||
}
|
||||
Self { modulo_path }
|
||||
}
|
||||
|
||||
pub fn is_valid(&self) -> bool {
|
||||
|
@ -97,23 +96,23 @@ impl ModuloManager {
|
|||
}
|
||||
|
||||
return Some(output.to_string());
|
||||
},
|
||||
}
|
||||
Err(error) => {
|
||||
error!("error while getting output from modulo: {}", error);
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
error!("error while sending body to modulo");
|
||||
},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error!("unable to open stdin to modulo");
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(error) => {
|
||||
error!("error reported when invoking modulo: {}", error);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user