Fix crash due to cycles when replaying macros (#2647)

In certain circumstances it was possible to get into an infinite loop
when replaying macros such as when different macros attempt to replay
each other.

This commit adds changes to track which macros are currently being
replayed and prevent getting into infinite loops.
pull/2681/head
gavynriebau 3 years ago committed by GitHub
parent 1c2aaf3baf
commit b2bd87df81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4617,6 +4617,17 @@ fn record_macro(cx: &mut Context) {
fn replay_macro(cx: &mut Context) { fn replay_macro(cx: &mut Context) {
let reg = cx.register.unwrap_or('@'); let reg = cx.register.unwrap_or('@');
if cx.editor.macro_replaying.contains(&reg) {
cx.editor.set_error(format!(
"Cannot replay from register [{}] because already replaying from same register",
reg
));
return;
}
cx.editor.macro_replaying.push(reg);
let keys: Vec<KeyEvent> = if let Some([keys_str]) = cx.editor.registers.read(reg) { let keys: Vec<KeyEvent> = if let Some([keys_str]) = cx.editor.registers.read(reg) {
match helix_view::input::parse_macro(keys_str) { match helix_view::input::parse_macro(keys_str) {
Ok(keys) => keys, Ok(keys) => keys,
@ -4638,4 +4649,6 @@ fn replay_macro(cx: &mut Context) {
} }
} }
})); }));
cx.editor.macro_replaying.pop();
} }

@ -433,6 +433,7 @@ pub struct Editor {
pub selected_register: Option<char>, pub selected_register: Option<char>,
pub registers: Registers, pub registers: Registers,
pub macro_recording: Option<(char, Vec<KeyEvent>)>, pub macro_recording: Option<(char, Vec<KeyEvent>)>,
pub macro_replaying: Vec<char>,
pub theme: Theme, pub theme: Theme,
pub language_servers: helix_lsp::Registry, pub language_servers: helix_lsp::Registry,
@ -503,6 +504,7 @@ impl Editor {
count: None, count: None,
selected_register: None, selected_register: None,
macro_recording: None, macro_recording: None,
macro_replaying: Vec::new(),
theme: theme_loader.default(), theme: theme_loader.default(),
language_servers, language_servers,
debugger: None, debugger: None,

Loading…
Cancel
Save