diff --git a/src/nvim/edit.c b/src/nvim/edit.c index dd2354b14a..091915857e 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2202,11 +2202,15 @@ int stop_arrow(void) new_insert_skip = 2; } else if (ins_need_undo) { if (u_save_cursor() == OK) { - // A command or event may have moved the cursor or edited the - // buffer. Update Insstart so that later edits can properly decide - // whether an extra undo entry is needed. - Insstart = curwin->w_cursor; - Insstart_textlen = (colnr_T)linetabsize_str(get_cursor_line_ptr()); + // A command or event may have moved the cursor before the next + // edit. Pull Insstart back only when the cursor moved above it, + // so that later edits can properly decide whether an extra undo + // entry is needed. Advancing Insstart would mis-place '[ after a + // register paste. + if (lt(curwin->w_cursor, Insstart)) { + Insstart = curwin->w_cursor; + Insstart_textlen = (colnr_T)linetabsize_str(get_cursor_line_ptr()); + } ins_need_undo = false; } } diff --git a/test/old/testdir/test_edit.vim b/test/old/testdir/test_edit.vim index 4530e2116f..3a18266c91 100644 --- a/test/old/testdir/test_edit.vim +++ b/test/old/testdir/test_edit.vim @@ -2498,4 +2498,18 @@ func Test_autoindent_no_strip_after_cursorholdi() bwipe! endfunc +" Issue #20130: '[ must mark the start of the paste after CTRL-R CTRL-P + edit. +func Test_open_square_mark_after_ctrl_r_ctrl_p_paste() + new + call setline(1, ['a', 'b', 'c', 'd']) + call cursor(4, 1) + + call feedkeys("Vggyjo\\\"\\", 'xt') + + call assert_equal(['a', 'b', 'a', 'b', 'c', 'd', 'c', 'd'], + \ getline(1, '$')) + call assert_equal([0, 3, 1, 0], getpos("'[")) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab