vim: Make each vim repeat its own transaction (#41735)
AidanV
and
Conrad Irwin
created 2 weeks ago
Release Notes:
- Pressing `u` after multiple `.` in rapid succession will now only undo
the latest repeat instead of all repeats.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Change summary
crates/vim/src/normal/repeat.rs | 19 +++++++++++++
crates/vim/src/test.rs | 16 +++++++++++
crates/vim/test_data/test_repeat_grouping_41735.json | 10 +++++++
3 files changed, 44 insertions(+), 1 deletion(-)
Detailed changes
@@ -110,7 +110,24 @@ impl Replayer {
}
lock.running = true;
let this = self.clone();
- window.defer(cx, move |window, cx| this.next(window, cx))
+ window.defer(cx, move |window, cx| {
+ this.next(window, cx);
+ let Some(Some(workspace)) = window.root::<Workspace>() else {
+ return;
+ };
+ let Some(editor) = workspace
+ .read(cx)
+ .active_item(cx)
+ .and_then(|item| item.act_as::<Editor>(cx))
+ else {
+ return;
+ };
+ editor.update(cx, |editor, cx| {
+ editor
+ .buffer()
+ .update(cx, |multi, cx| multi.finalize_last_transaction(cx))
+ });
+ })
}
pub fn stop(self) {
@@ -2365,3 +2365,19 @@ async fn test_wrap_selections_in_tag_line_mode(cx: &mut gpui::TestAppContext) {
Mode::VisualLine,
);
}
+
+#[gpui::test]
+async fn test_repeat_grouping_41735(cx: &mut gpui::TestAppContext) {
+ let mut cx = NeovimBackedTestContext::new(cx).await;
+
+ // typically transaction gropuing is disabled in tests, but here we need to test it.
+ cx.update_buffer(|buffer, _cx| buffer.set_group_interval(Duration::from_millis(300)));
+
+ cx.set_shared_state("ˇ").await;
+
+ cx.simulate_shared_keystrokes("i a escape").await;
+ cx.simulate_shared_keystrokes(". . .").await;
+ cx.shared_state().await.assert_eq("ˇaaaa");
+ cx.simulate_shared_keystrokes("u").await;
+ cx.shared_state().await.assert_eq("ˇaaa");
+}
@@ -0,0 +1,10 @@
+{"Put":{"state":"ˇ"}}
+{"Key":"i"}
+{"Key":"a"}
+{"Key":"escape"}
+{"Key":"."}
+{"Key":"."}
+{"Key":"."}
+{"Get":{"state":"ˇaaaa","mode":"Normal"}}
+{"Key":"u"}
+{"Get":{"state":"ˇaaa","mode":"Normal"}}