From 2d4bc0aec743c6d62344da6fda2c0c84e75a82be Mon Sep 17 00:00:00 2001 From: Omnikar Date: Sun, 12 Dec 2021 10:36:52 -0500 Subject: [PATCH] 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 `<>` --- helix-term/src/commands.rs | 46 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index fdc242fe..4e0f3ef7 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -6015,9 +6015,15 @@ fn record_macro(cx: &mut Context) { keys.pop(); let s = keys .into_iter() - .map(|key| key.to_string()) - .collect::>() - .join(" "); + .map(|key| { + let s = key.to_string(); + if s.chars().count() == 1 { + s + } else { + format!("<{}>", s) + } + }) + .collect::(); 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 = if let Some([keys]) = cx.editor.registers.read(reg) { - match keys.split_whitespace().map(str::parse).collect() { + let keys: Vec = 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));