Mercurial > vim
changeset 28835:58d2315b096e v8.2.4941
patch 8.2.4941: '[ and '] marks may be wrong after undo
Commit: https://github.com/vim/vim/commit/82444cefa3fef87624a078ea86a72af7ef4ef42e
Author: LemonBoy <thatlemon@gmail.com>
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 12 May 2022 16:45:03 +0200 |
parents | 4a4e0b5939b7 |
children | 60e7b3a726e7 |
files | src/testdir/test_undo.vim src/undo.c src/version.c |
diffstat | 3 files changed, 27 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- 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\<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
--- 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();