Change how macros separate keypresses

* Keypresses are no longer separated by spaces
* Single-character keypresses are serialized as-is
* Multi-character keypresses are delimited by `<>`
This commit is contained in:
Omnikar 2021-12-12 10:36:52 -05:00 committed by Blaž Hrastnik
parent ee3eb4057a
commit 2d4bc0aec7

View File

@ -6015,9 +6015,15 @@ fn record_macro(cx: &mut Context) {
keys.pop();
let s = keys
.into_iter()
.map(|key| key.to_string())
.collect::<Vec<_>>()
.join(" ");
.map(|key| {
let s = key.to_string();
if s.chars().count() == 1 {
s
} else {
format!("<{}>", s)
}
})
.collect::<String>();
cx.editor.registers.get_mut(reg).write(vec![s]);
cx.editor
.set_status(format!("Recorded to register [{}]", reg));
@ -6032,8 +6038,38 @@ fn record_macro(cx: &mut Context) {
fn replay_macro(cx: &mut Context) {
let reg = cx.register.unwrap_or('@');
// TODO: macro keys should be parsed one by one and not space delimited (see kak)
let keys: Vec<KeyEvent> = if let Some([keys]) = cx.editor.registers.read(reg) {
match keys.split_whitespace().map(str::parse).collect() {
let keys: Vec<KeyEvent> = if let Some([keys_str]) = cx.editor.registers.read(reg) {
let mut keys_res: anyhow::Result<_> = Ok(Vec::new());
let mut i = 0;
while let Ok(keys) = &mut keys_res {
if i >= keys_str.len() {
break;
}
if !keys_str.is_char_boundary(i) {
i += 1;
continue;
}
let s = &keys_str[i..];
let mut end_i = 1;
while !s.is_char_boundary(end_i) {
end_i += 1;
}
let c = &s[..end_i];
if c != "<" {
keys.push(c);
i += end_i;
} else {
match s.find('>').context("'>' expected") {
Ok(end_i) => {
keys.push(&s[1..end_i]);
i += end_i + 1;
}
Err(err) => keys_res = Err(err),
}
}
}
match keys_res.and_then(|keys| keys.into_iter().map(str::parse).collect()) {
Ok(keys) => keys,
Err(err) => {
cx.editor.set_error(format!("Invalid macro: {}", err));