Improve vim undo (#9317)

The important change here is to ensure that undo never lands you in
visual mode; but we also take care to restore the selection the same way
vim does (visual line goes to beginning of line, visual block to the top
left, etc.).

To help make this behaviour feel right we also group any deletions that
started insert mode with the first text inserted.

Fixes: #7521

Release Notes:

- vim: Improved undo. It will now restore you to normal mode in the same
position as vim, and group deletions caused by `c` or `s` with the
concomitant insert.
([#7521](https://github.com/zed-industries/zed/issues/7521)).
This commit is contained in:
Conrad Irwin 2024-03-13 23:12:12 -06:00 committed by GitHub
parent 6ae5274954
commit bffde43c12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 219 additions and 27 deletions

View file

@ -981,3 +981,55 @@ async fn test_remap(cx: &mut gpui::TestAppContext) {
cx.simulate_keystrokes(["g", "t"]);
cx.assert_state("12ˇ 34", Mode::Normal);
}
#[gpui::test]
async fn test_undo(cx: &mut gpui::TestAppContext) {
let mut cx = NeovimBackedTestContext::new(cx).await;
cx.set_shared_state("hello quˇoel world").await;
cx.simulate_shared_keystrokes(["v", "i", "w", "s", "c", "o", "escape", "u"])
.await;
cx.assert_shared_state("hello ˇquoel world").await;
cx.simulate_shared_keystrokes(["ctrl-r"]).await;
cx.assert_shared_state("hello ˇco world").await;
cx.simulate_shared_keystrokes(["a", "o", "right", "l", "escape"])
.await;
cx.assert_shared_state("hello cooˇl world").await;
cx.simulate_shared_keystrokes(["u"]).await;
cx.assert_shared_state("hello cooˇ world").await;
cx.simulate_shared_keystrokes(["u"]).await;
cx.assert_shared_state("hello cˇo world").await;
cx.simulate_shared_keystrokes(["u"]).await;
cx.assert_shared_state("hello ˇquoel world").await;
cx.set_shared_state("hello quˇoel world").await;
cx.simulate_shared_keystrokes(["v", "i", "w", "~", "u"])
.await;
cx.assert_shared_state("hello ˇquoel world").await;
cx.set_shared_state("\nhello quˇoel world\n").await;
cx.simulate_shared_keystrokes(["shift-v", "s", "c", "escape", "u"])
.await;
cx.assert_shared_state("\nˇhello quoel world\n").await;
cx.set_shared_state(indoc! {"
ˇ1
2
3"})
.await;
cx.simulate_shared_keystrokes(["ctrl-v", "shift-g", "ctrl-a"])
.await;
cx.assert_shared_state(indoc! {"
ˇ2
3
4"})
.await;
cx.simulate_shared_keystrokes(["u"]).await;
cx.assert_shared_state(indoc! {"
ˇ1
2
3"})
.await;
}