aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-05-12 23:38:26 +0800
committerGitHub <noreply@github.com>2022-05-12 23:38:26 +0800
commita200ce0d8580f40a36c313a26db2377c1812abe2 (patch)
tree5f684b1534af60fb3822d4e1082fda74c34fff8f /src
parent8fba428bc6f36ae038a9286517e15b33257a1359 (diff)
downloadrneovim-a200ce0d8580f40a36c313a26db2377c1812abe2.tar.gz
rneovim-a200ce0d8580f40a36c313a26db2377c1812abe2.tar.bz2
rneovim-a200ce0d8580f40a36c313a26db2377c1812abe2.zip
vim-patch:8.2.4941: '[ and '] marks may be wrong after undo (#18539)
Problem: '[ and '] marks may be wrong after undo. Solution: Adjust the '[ and '] marks if needed. (closes vim/vim#10407, closes vim/vim#1281) https://github.com/vim/vim/commit/82444cefa3fef87624a078ea86a72af7ef4ef42e
Diffstat (limited to 'src')
-rw-r--r--src/nvim/testdir/test_undo.vim17
-rw-r--r--src/nvim/undo.c11
2 files changed, 27 insertions, 1 deletions
diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim
index 30e00e7ad4..848860649e 100644
--- a/src/nvim/testdir/test_undo.vim
+++ b/src/nvim/testdir/test_undo.vim
@@ -733,4 +733,21 @@ func Test_undofile_cryptmethod_blowfish2()
set undofile& undolevels& cryptmethod&
endfunc
+func Test_undo_mark()
+ new
+ " The undo is applied to the only line.
+ call setline(1, 'hello')
+ call feedkeys("ggyiw$p", 'xt')
+ undo
+ call assert_equal([0, 1, 1, 0], getpos("'["))
+ call assert_equal([0, 1, 1, 0], getpos("']"))
+ " The undo removes the last line.
+ call feedkeys("Goaaaa\<Esc>", 'xt')
+ call feedkeys("obbbb\<Esc>", 'xt')
+ undo
+ call assert_equal([0, 2, 1, 0], getpos("'["))
+ call assert_equal([0, 2, 1, 0], getpos("']"))
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 937e86b161..671345bb85 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -2418,10 +2418,11 @@ static void u_undoredo(int undo, bool do_buf_event)
changed_lines(top + 1, 0, bot, newsize - oldsize, do_buf_event);
- // set '[ and '] mark
+ // Set the '[ mark.
if (top + 1 < curbuf->b_op_start.lnum) {
curbuf->b_op_start.lnum = top + 1;
}
+ // Set the '] mark.
if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum) {
curbuf->b_op_end.lnum = top + 1;
} else if (top + newsize > curbuf->b_op_end.lnum) {
@@ -2442,6 +2443,14 @@ static void u_undoredo(int undo, bool do_buf_event)
newlist = uep;
}
+ // Ensure the '[ and '] marks are within bounds.
+ if (curbuf->b_op_start.lnum > curbuf->b_ml.ml_line_count) {
+ curbuf->b_op_start.lnum = curbuf->b_ml.ml_line_count;
+ }
+ if (curbuf->b_op_end.lnum > curbuf->b_ml.ml_line_count) {
+ curbuf->b_op_end.lnum = curbuf->b_ml.ml_line_count;
+ }
+
// Adjust Extmarks
ExtmarkUndoObject undo_info;
if (undo) {