diff --git a/src/edit.c b/src/edit.c index f15cc55f32..1db9c13071 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1132,6 +1132,10 @@ doESCkey: case K_COMMAND: // command case K_SCRIPT_COMMAND: // command { + bufref_T save_curbuf; + varnumber_T tick = CHANGEDTICK(curbuf); + + set_bufref(&save_curbuf, curbuf); do_cmdkey_command(c, 0); #ifdef FEAT_TERMINAL @@ -1139,10 +1143,15 @@ doESCkey: // Started a terminal that gets the input, exit Insert mode. goto doESCkey; #endif - if (curbuf->b_u_synced) - // The command caused undo to be synced. Need to save the - // line for undo before inserting the next char. + if (curbuf->b_u_synced + || (bufref_valid(&save_curbuf) + && curbuf == save_curbuf.br_buf + && tick != CHANGEDTICK(curbuf))) + { + // The command synced undo or changed this buffer. + // Save the cursor line before the next typed edit. ins_need_undo = TRUE; + } } break; @@ -2503,7 +2512,9 @@ stop_arrow(void) { if (u_save_cursor() == OK) { - // A command or event may have moved the cursor after syncing undo. + // 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(ml_get_curline()); ins_need_undo = FALSE; diff --git a/src/testdir/test_undo.vim b/src/testdir/test_undo.vim index 97b77f423d..f03d3ef091 100644 --- a/src/testdir/test_undo.vim +++ b/src/testdir/test_undo.vim @@ -939,4 +939,32 @@ func Test_undo_line_backspace_after_insert_cmd_cursor_movement() bwipe! endfunc +func Test_undo_line_backspace_after_insert_func_edit() + new + setlocal backspace=eol undolevels=100 + + let v:errmsg = '' + call feedkeys("i\" + \ .. "\call setline(2, 'abc')\" + \ .. "\\u", 'xt') + + call assert_equal('', v:errmsg) + call assert_equal([''], getline(1, '$')) + bwipe! +endfunc + +func Test_undo_line_backspace_after_insert_cmd_edit() + new + setlocal backspace=eol undolevels=100 + + let v:errmsg = '' + call feedkeys("i\" + \ .. "\s/.*/abc/\" + \ .. "\\u", 'xt') + + call assert_equal('', v:errmsg) + call assert_equal([''], getline(1, '$')) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index b6cbb51aa8..406bccd54d 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 408, /**/ 407, /**/