neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit a200ce0d8580f40a36c313a26db2377c1812abe2
parent 8fba428bc6f36ae038a9286517e15b33257a1359
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Thu, 12 May 2022 23:38:26 +0800

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:
Msrc/nvim/testdir/test_undo.vim | 17+++++++++++++++++
Msrc/nvim/undo.c | 11++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)

diff --git 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 @@ -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) {