aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs46
1 files 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::<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));