Refactor cursor hint to support dynamic matches

This commit is contained in:
Federico Terzi 2019-10-24 18:48:55 +02:00
parent 4f9be699ac
commit 8afacf4efb
2 changed files with 22 additions and 82 deletions

View File

@ -160,6 +160,25 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa
// Convert Windows style newlines into unix styles
target_string = target_string.replace("\r\n", "\n");
// Calculate cursor rewind moves if a Cursor Hint is present
let index = target_string.find("$|$");
let cursor_rewind = if let Some(index) = index {
// Convert the byte index to a char index
let char_str = &target_string[0..index];
let char_index = char_str.chars().count();
let total_size = target_string.chars().count();
// Remove the $|$ placeholder
target_string = target_string.replace("$|$", "");
// Calculate the amount of rewind moves needed (LEFT ARROW).
// Subtract also 3, equal to the number of chars of the placeholder "$|$"
let moves = (total_size - char_index - 3) as i32;
Some(moves)
}else{
None
};
match config.backend {
BackendType::Inject => {
// Send the expected string. On linux, newlines are managed automatically
@ -186,11 +205,9 @@ impl <'a, S: KeyboardManager, C: ClipboardManager, M: ConfigManager<'a>, U: UIMa
},
}
// Cursor Hint
if let Some(cursor_rewind) = m._cursor_rewind {
if let Some(moves) = cursor_rewind {
// Simulate left arrow key presses to bring the cursor into the desired position
self.keyboard_manager.move_cursor_left(cursor_rewind);
self.keyboard_manager.move_cursor_left(moves);
}
}

View File

@ -38,11 +38,6 @@ pub struct Match {
// Automatically calculated from the trigger, used by the matcher to check for correspondences.
#[serde(skip_serializing)]
pub _trigger_sequence: Vec<TriggerEntry>,
// If a cursor position hint is present, this value contains the amount of "left" moves necessary
// to arrive to the target point
#[serde(skip_serializing)]
pub _cursor_rewind: Option<i32>,
}
impl <'de> serde::Deserialize<'de> for Match {
@ -62,30 +57,7 @@ impl<'a> From<&'a AutoMatch> for Match{
// TODO: may need to replace windows newline (\r\n) with newline only (\n)
let mut new_replace = other.replace.clone();
// Check if the replace result contains a Cursor Hint
let cursor_rewind = if other.replace.contains("{{|}}") {
let index = other.replace.find("{{|}}");
if let Some(index) = index {
// Convert the byte index to a char index
let char_str = &other.replace[0..index];
let char_index = char_str.chars().count();
let total_size = other.replace.chars().count();
// Remove the {{|}} placeholder
new_replace = other.replace.replace("{{|}}", "");
// Calculate the amount of rewind moves needed (LEFT ARROW).
// Subtract also 5, equal to the number of chars of the placeholder "{{|}}"
let moves = (total_size - char_index - 5) as i32;
Some(moves)
}else{
None
}
}else{
None
};
let new_replace = other.replace.clone();
// Check if the match contains variables
let has_vars = VAR_REGEX.is_match(&other.replace);
@ -107,7 +79,6 @@ impl<'a> From<&'a AutoMatch> for Match{
word: other.word.clone(),
_has_vars: has_vars,
_trigger_sequence: trigger_sequence,
_cursor_rewind: cursor_rewind,
}
}
}
@ -241,52 +212,4 @@ mod tests {
assert_eq!(_match._trigger_sequence[3], TriggerEntry::Char('t'));
assert_eq!(_match._trigger_sequence[4], TriggerEntry::WordSeparator);
}
#[test]
fn test_match_cursor_hint_not_present() {
let match_str = r###"
trigger: "test"
replace: "This is a test"
"###;
let _match : Match = serde_yaml::from_str(match_str).unwrap();
assert!(_match._cursor_rewind.is_none());
}
#[test]
fn test_match_cursor_hint_should_be_removed() {
let match_str = r###"
trigger: "test"
replace: "Testing the {{|}} cursor position"
"###;
let _match : Match = serde_yaml::from_str(match_str).unwrap();
assert_eq!(_match.replace, "Testing the cursor position");
}
#[test]
fn test_match_cursor_rewind_single_line() {
let match_str = r###"
trigger: "test"
replace: "Testing the {{|}} cursor position"
"###;
let _match : Match = serde_yaml::from_str(match_str).unwrap();
assert_eq!(_match._cursor_rewind.unwrap(), 16);
}
#[test]
fn test_match_cursor_rewind_multiple_line() {
let match_str = r###"
trigger: "test"
replace: "Testing the \n{{|}}\n cursor position"
"###;
let _match : Match = serde_yaml::from_str(match_str).unwrap();
assert_eq!(_match._cursor_rewind.unwrap(), 17);
}
}