Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--helix-term/src/compositor.rs7
-rw-r--r--helix-term/tests/test/commands.rs27
2 files changed, 32 insertions, 2 deletions
diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs
index a57fd617..28c8651a 100644
--- a/helix-term/src/compositor.rs
+++ b/helix-term/src/compositor.rs
@@ -137,9 +137,12 @@ impl Compositor {
}
pub fn handle_event(&mut self, event: &Event, cx: &mut Context) -> bool {
- // If it is a key event and a macro is being recorded, push the key event to the recording.
+ // If it is a key event, a macro is being recorded, and a macro isn't being replayed,
+ // push the key event to the recording.
if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) {
- keys.push(*key);
+ if cx.editor.macro_replaying.is_empty() {
+ keys.push(*key);
+ }
}
let mut callbacks = Vec::new();
diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs
index baa2835c..2af1a054 100644
--- a/helix-term/tests/test/commands.rs
+++ b/helix-term/tests/test/commands.rs
@@ -793,3 +793,30 @@ fn foo() {
Ok(())
}
+
+#[tokio::test(flavor = "multi_thread")]
+async fn macro_play_within_macro_record() -> anyhow::Result<()> {
+ // <https://github.com/helix-editor/helix/issues/12697>
+ //
+ // * `"aQihello<esc>Q` record a macro to register 'a' which inserts "hello"
+ // * `Q"aq<space>world<esc>Q` record a macro to the default macro register which plays the
+ // macro in register 'a' and then inserts " world"
+ // * `%d` clear the buffer
+ // * `q` replay the macro in the default macro register
+ // * `i<ret>` add a newline at the end
+ //
+ // The inner macro in register 'a' should replay within the outer macro exactly once to insert
+ // "hello world".
+ test((
+ indoc! {"\
+ #[|]#
+ "},
+ r#""aQihello<esc>QQ"aqi<space>world<esc>Q%dqi<ret>"#,
+ indoc! {"\
+ hello world
+ #[|]#"},
+ ))
+ .await?;
+
+ Ok(())
+}