aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorPabloMansanet2022-06-28 12:30:27 +0000
committerGitHub2022-06-28 12:30:27 +0000
commit030de46e6b9568f27fd89b1543d978b21da7464e (patch)
tree15ece7838c6a32f06f4acc5f2a7b3be3d2711561 /helix-term
parentac1d8fa505e926d981682317e4e3d289bec4eb49 (diff)
Fix recursive macro crash and empty macro lockout (#2902)
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs12
1 files changed, 8 insertions, 4 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 0a28444b..d1bec0ce 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -4655,8 +4655,6 @@ fn replay_macro(cx: &mut Context) {
return;
}
- cx.editor.macro_replaying.push(reg);
-
let keys: Vec<KeyEvent> = if let Some([keys_str]) = cx.editor.registers.read(reg) {
match helix_view::input::parse_macro(keys_str) {
Ok(keys) => keys,
@@ -4670,6 +4668,10 @@ fn replay_macro(cx: &mut Context) {
return;
};
+ // Once the macro has been fully validated, it's marked as being under replay
+ // to ensure we don't fall into infinite recursion.
+ cx.editor.macro_replaying.push(reg);
+
let count = cx.count();
cx.callback = Some(Box::new(move |compositor, cx| {
for _ in 0..count {
@@ -4677,7 +4679,9 @@ fn replay_macro(cx: &mut Context) {
compositor.handle_event(crossterm::event::Event::Key(key.into()), cx);
}
}
+ // The macro under replay is cleared at the end of the callback, not in the
+ // macro replay context, or it will not correctly protect the user from
+ // replaying recursively.
+ cx.editor.macro_replaying.pop();
}));
-
- cx.editor.macro_replaying.pop();
}