# HG changeset patch # User Bram Moolenaar # Date 1652366703 -7200 # Node ID 58d2315b096e1d0262aa9b3d7f74536d38bc1ba7 # Parent 4a4e0b5939b7c2dfc2e743afc26cf13735fa6521 patch 8.2.4941: '[ and '] marks may be wrong after undo Commit: https://github.com/vim/vim/commit/82444cefa3fef87624a078ea86a72af7ef4ef42e Author: LemonBoy Date: Thu May 12 15:39:31 2022 +0100 patch 8.2.4941: '[ and '] marks may be wrong after undo Problem: '[ and '] marks may be wrong after undo. Solution: Adjust the '[ and '] marks if needed. (closes https://github.com/vim/vim/issues/10407, closes https://github.com/vim/vim/issues/1281) diff --git a/src/testdir/test_undo.vim b/src/testdir/test_undo.vim --- a/src/testdir/test_undo.vim +++ b/src/testdir/test_undo.vim @@ -756,4 +756,21 @@ func Test_redo_multibyte_in_insert_mode( bwipe! 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\", 'xt') + call feedkeys("obbbb\", '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/undo.c b/src/undo.c --- a/src/undo.c +++ b/src/undo.c @@ -2831,9 +2831,10 @@ u_undoredo(int undo) if (oldsize > 0 || newsize > 0) changed_lines(top + 1, 0, bot, newsize - oldsize); - // 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) @@ -2853,6 +2854,12 @@ u_undoredo(int undo) 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; + // Set the cursor to the desired position. Check that the line is valid. curwin->w_cursor = new_curpos; check_cursor_lnum(); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4941, +/**/ 4940, /**/ 4939,