diff --git a/espanso-migrate/src/convert.rs b/espanso-migrate/src/convert.rs index 6695daf..84b7870 100644 --- a/espanso-migrate/src/convert.rs +++ b/espanso-migrate/src/convert.rs @@ -55,7 +55,9 @@ pub fn convert(input_files: HashMap) -> HashMap { config_names_to_path.insert(name.to_string(), match_output_path.clone()); } - let output_yaml = output_files.entry(match_output_path.clone()).or_insert(Hash::new()); + let output_yaml = output_files + .entry(match_output_path.clone()) + .or_insert(Hash::new()); if let Some(global_vars) = yaml_global_vars { let output_global_vars = output_yaml @@ -78,7 +80,7 @@ pub fn convert(input_files: HashMap) -> HashMap { eprintln!("unable to transform matches for file: {}", input_path); } } - + if should_underscore { Some(match_output_path) } else { @@ -106,17 +108,55 @@ pub fn convert(input_files: HashMap) -> HashMap { copy_field_if_present(yaml, "filter_class", &mut output_yaml, "filter_class"); copy_field_if_present(yaml, "filter_exec", &mut output_yaml, "filter_exec"); copy_field_if_present(yaml, "enable_active", &mut output_yaml, "enable"); + copy_field_if_present(yaml, "backend", &mut output_yaml, "backend"); + map_field_if_present( + yaml, + "paste_shortcut", + &mut output_yaml, + "paste_shortcut", + |val| match val { + Yaml::String(shortcut) if shortcut == "CtrlV" => Some(Yaml::String("CTRL+V".to_string())), + Yaml::String(shortcut) if shortcut == "CtrlShiftV" => Some(Yaml::String("CTRL+SHIFT+V".to_string())), + Yaml::String(shortcut) if shortcut == "ShiftInsert" => Some(Yaml::String("SHIFT+INSERT".to_string())), + Yaml::String(shortcut) if shortcut == "CtrlAltV" => Some(Yaml::String("CTRL+ALT+V".to_string())), + Yaml::String(shortcut) if shortcut == "MetaV" => Some(Yaml::String("META+V".to_string())), + Yaml::String(_) => None, + _ => None, + }, + ); + copy_field_if_present(yaml, "secure_input_watcher_enabled", &mut output_yaml, "secure_input_watcher_enabled"); + copy_field_if_present(yaml, "secure_input_watcher_interval", &mut output_yaml, "secure_input_watcher_interval"); + copy_field_if_present(yaml, "secure_input_notification", &mut output_yaml, "secure_input_notification"); + copy_field_if_present(yaml, "config_caching_interval", &mut output_yaml, "config_caching_interval"); + copy_field_if_present(yaml, "toggle_interval", &mut output_yaml, "toggle_interval"); + copy_field_if_present(yaml, "toggle_key", &mut output_yaml, "toggle_key"); + copy_field_if_present(yaml, "preserve_clipboard", &mut output_yaml, "preserve_clipboard"); + copy_field_if_present(yaml, "backspace_limit", &mut output_yaml, "backspace_limit"); + copy_field_if_present(yaml, "fast_inject", &mut output_yaml, "x11_fast_inject"); + copy_field_if_present(yaml, "auto_restart", &mut output_yaml, "auto_restart"); + copy_field_if_present(yaml, "undo_backspace", &mut output_yaml, "undo_backspace"); + copy_field_if_present(yaml, "show_icon", &mut output_yaml, "show_icon"); + copy_field_if_present(yaml, "show_notifications", &mut output_yaml, "show_notifications"); + copy_field_if_present(yaml, "inject_delay", &mut output_yaml, "inject_delay"); + copy_field_if_present(yaml, "restore_clipboard_delay", &mut output_yaml, "restore_clipboard_delay"); + copy_field_if_present(yaml, "use_system_agent", &mut output_yaml, "use_system_agent"); + copy_field_if_present(yaml, "word_separators", &mut output_yaml, "word_separators"); // TODO: warn if passive mode parameters are used // TODO: copy other config fields: https://github.com/federico-terzi/espanso/blob/master/src/config/mod.rs#L169 - // Link any unlisted match file (the ones starting with the _ underscore, which are excluded by the + // Link any unlisted match file (the ones starting with the _ underscore, which are excluded by the // default.yml config) explicitly, if present. if let Some(match_file_path) = match_file_path_if_unlisted { - let yaml_exclude_default_entries = yaml_get_bool(yaml, "exclude_default_entries").unwrap_or(false); - let key_name = if yaml_exclude_default_entries { "includes" } else { "extra_includes" }; - + let yaml_exclude_default_entries = + yaml_get_bool(yaml, "exclude_default_entries").unwrap_or(false); + let key_name = if yaml_exclude_default_entries { + "includes" + } else { + "extra_includes" + }; + let includes = vec![Yaml::String(format!("../{}", match_file_path))]; output_yaml.insert(Yaml::String(key_name.to_string()), Yaml::Array(includes)); @@ -222,3 +262,20 @@ fn copy_field_if_present( output_yaml.insert(Yaml::String(output_field_name.to_string()), value.clone()); } } + +fn map_field_if_present( + input_yaml: &Hash, + input_field_name: &str, + output_yaml: &mut Hash, + output_field_name: &str, + transform: impl FnOnce(&Yaml) -> Option, +) { + if let Some(value) = input_yaml.get(&Yaml::String(input_field_name.to_string())) { + let transformed = transform(value); + if let Some(transformed) = transformed { + output_yaml.insert(Yaml::String(output_field_name.to_string()), transformed); + } else { + eprintln!("could not convert value for field: {}", input_field_name); + } + } +} diff --git a/espanso-migrate/src/lib.rs b/espanso-migrate/src/lib.rs index 2d5344c..733f65f 100644 --- a/espanso-migrate/src/lib.rs +++ b/espanso-migrate/src/lib.rs @@ -74,6 +74,7 @@ mod tests { use test_case::test_case; use pretty_assertions::{assert_eq as assert_peq}; +use yaml_rust::{yaml::Hash, Yaml}; fn run_with_temp_dir(test_data: &Dir, action: impl FnOnce(&Path, &Path)) { let tmp_dir = TempDir::new("espanso-migration").unwrap(); @@ -107,11 +108,19 @@ mod tests { tuples } + fn to_sorted_hash(hash: &Hash) -> Vec<(String, &Yaml)> { + let mut tuples: Vec<(String, &Yaml)> = hash.into_iter().map(|(k, v)| (k.as_str().unwrap().to_string(), v)).collect(); + tuples.sort_by_key(|(k, _)| k.clone()); + tuples + } + static SIMPLE_CASE: Dir = include_dir!("test/simple"); static BASE_CASE: Dir = include_dir!("test/base"); + static ALL_PARAMS_CASE: Dir = include_dir!("test/all_params"); #[test_case(&SIMPLE_CASE; "simple case")] #[test_case(&BASE_CASE; "base case")] + #[test_case(&ALL_PARAMS_CASE; "all config parameters case")] fn test_migration(test_data: &Dir) { run_with_temp_dir(test_data, |legacy, expected| { let legacy_files = load::load(legacy).unwrap(); @@ -122,7 +131,7 @@ mod tests { assert_eq!(converted_files.len(), expected_files.len()); for (file, content) in to_sorted_list(converted_files) { - assert_peq!(&content, expected_files.get(&file).unwrap()); + assert_peq!(to_sorted_hash(&content), to_sorted_hash(&expected_files.get(&file).unwrap())); } }); } diff --git a/espanso-migrate/test/all_params/expected/config/default.yml b/espanso-migrate/test/all_params/expected/config/default.yml new file mode 100644 index 0000000..46d6954 --- /dev/null +++ b/espanso-migrate/test/all_params/expected/config/default.yml @@ -0,0 +1,30 @@ +config_caching_interval: 1200 + +toggle_interval: 500 +toggle_key: "RIGHT_CTRL" + +preserve_clipboard: false + +backspace_limit: 5 + +inject_delay: 10 +restore_clipboard_delay: 400 + +secure_input_watcher_enabled: false +secure_input_notification: false +secure_input_watcher_interval: 3000 + +show_notifications: false +show_icon: false + +auto_restart: false +undo_backspace: false + +x11_fast_inject: false + +paste_shortcut: "CTRL+ALT+V" + +backend: Clipboard + +use_system_agent: false +word_separators: ['.'] \ No newline at end of file diff --git a/espanso-migrate/test/all_params/expected/match/base.yml b/espanso-migrate/test/all_params/expected/match/base.yml new file mode 100644 index 0000000..f89c90c --- /dev/null +++ b/espanso-migrate/test/all_params/expected/match/base.yml @@ -0,0 +1,12 @@ +global_vars: + - name: "name" + type: "dummy" + params: + echo: "John" + +matches: + - name: ":hi" + trigger: "Hello" + + - name: ":greet" + trigger: "Hi {{name}}" \ No newline at end of file diff --git a/espanso-migrate/test/all_params/legacy/default.yml b/espanso-migrate/test/all_params/legacy/default.yml index da172fb..04d3256 100644 --- a/espanso-migrate/test/all_params/legacy/default.yml +++ b/espanso-migrate/test/all_params/legacy/default.yml @@ -1,7 +1,7 @@ config_caching_interval: 1200 toggle_interval: 500 -toggle_key: "CTRL" +toggle_key: "RIGHT_CTRL" preserve_clipboard: false @@ -24,10 +24,13 @@ fast_inject: false post_inject_delay: 200 -paste_shortcut: # TODO +paste_shortcut: CtrlAltV backend: Clipboard +use_system_agent: false +word_separators: ['.'] + global_vars: - name: "name" type: "dummy" diff --git a/espanso-migrate/test/base/expected/match/split.yml b/espanso-migrate/test/base/expected/match/split.yml new file mode 100644 index 0000000..c5d3bd3 --- /dev/null +++ b/espanso-migrate/test/base/expected/match/split.yml @@ -0,0 +1,4 @@ +matches: + - trigger: "jon" + replace: "snow" + diff --git a/espanso-migrate/test/base/legacy/user/extended.yml b/espanso-migrate/test/base/legacy/user/extended.yml index e94ffef..08e2fd9 100644 --- a/espanso-migrate/test/base/legacy/user/extended.yml +++ b/espanso-migrate/test/base/legacy/user/extended.yml @@ -1,5 +1,3 @@ -parent: default - filter_exec: "Executable" global_vars: diff --git a/espanso-migrate/test/base/legacy/user/split.yml b/espanso-migrate/test/base/legacy/user/split.yml new file mode 100644 index 0000000..5e1eab4 --- /dev/null +++ b/espanso-migrate/test/base/legacy/user/split.yml @@ -0,0 +1,5 @@ +parent: default + +matches: + - trigger: "jon" + replace: "snow"