diff options
-rw-r--r-- | src/nvim/edit.c | 48 | ||||
-rw-r--r-- | src/nvim/testdir/test_autocmd.vim | 4 |
2 files changed, 34 insertions, 18 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 4d487041b8..8635735df3 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -276,7 +276,7 @@ static void insert_enter(InsertState *s) set_vim_var_string(VV_INSERTMODE, (char *) s->ptr, 1); set_vim_var_string(VV_CHAR, NULL, -1); - apply_autocmds(EVENT_INSERTENTER, NULL, NULL, false, curbuf); + ins_apply_autocmds(EVENT_INSERTENTER); // Make sure the cursor didn't move. Do call check_cursor_col() in // case the text was modified. Since Insert mode was not started yet @@ -469,7 +469,7 @@ static void insert_enter(InsertState *s) foldUpdateAfterInsert(); if (s->cmdchar != 'r' && s->cmdchar != 'v') { - apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL, false, curbuf); + ins_apply_autocmds(EVENT_INSERTLEAVE); } did_cursorhold = false; } @@ -1376,7 +1376,7 @@ ins_redraw ( // Make sure curswant is correct, an autocommand may call // getcurpos() update_curswant(); - apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, false, curbuf); + ins_apply_autocmds(EVENT_CURSORMOVEDI); } if (curwin->w_p_cole > 0) { conceal_old_cursor_line = last_cursormoved.lnum; @@ -1391,21 +1391,17 @@ ins_redraw ( && curbuf->b_last_changedtick != buf_get_changedtick(curbuf) && !pum_visible()) { aco_save_T aco; - - // Sync undo when the autocommand calls setline() or append(), so that - // it can be undone separately. - u_sync_once = 2; + varnumber_T tick = buf_get_changedtick(curbuf); // save and restore curwin and curbuf, in case the autocmd changes them aucmd_prepbuf(&aco, curbuf); apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf); aucmd_restbuf(&aco); curbuf->b_last_changedtick = buf_get_changedtick(curbuf); - - if (u_sync_once == 1) { - ins_need_undo = true; + if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds() + u_save(curwin->w_cursor.lnum, + (linenr_T)(curwin->w_cursor.lnum + 1)); } - u_sync_once = 0; } // Trigger TextChangedP if changedtick differs. When the popupmenu closes @@ -1415,12 +1411,17 @@ ins_redraw ( && curbuf->b_last_changedtick_pum != buf_get_changedtick(curbuf) && pum_visible()) { aco_save_T aco; + varnumber_T tick = buf_get_changedtick(curbuf); // save and restore curwin and curbuf, in case the autocmd changes them aucmd_prepbuf(&aco, curbuf); apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, false, curbuf); aucmd_restbuf(&aco); curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf); + if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds() + u_save(curwin->w_cursor.lnum, + (linenr_T)(curwin->w_cursor.lnum + 1)); + } } if (must_redraw) @@ -3411,12 +3412,12 @@ static bool ins_compl_prep(int c) do_c_expr_indent(); /* Trigger the CompleteDone event to give scripts a chance to act * upon the completion. */ - apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf); + ins_apply_autocmds(EVENT_COMPLETEDONE); } } else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) /* Trigger the CompleteDone event to give scripts a chance to act * upon the (possibly failed) completion. */ - apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf); + ins_apply_autocmds(EVENT_COMPLETEDONE); /* reset continue_* if we left expansion-mode, if we stay they'll be * (re)set properly in ins_complete() */ @@ -7416,7 +7417,7 @@ static void ins_insert(int replaceState) set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" : replaceState == VREPLACE ? "v" : "r"), 1); - apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, false, curbuf); + ins_apply_autocmds(EVENT_INSERTCHANGE); if (State & REPLACE_FLAG) { State = INSERT | (State & LANGMAP); } else { @@ -8678,7 +8679,7 @@ static char_u *do_insert_char_pre(int c) set_vim_var_string(VV_CHAR, buf, -1); char_u *res = NULL; - if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) { + if (ins_apply_autocmds(EVENT_INSERTCHARPRE)) { /* Get the value of v:char. It may be empty or more than one * character. Only use it when changed, otherwise continue with the * original character to avoid breaking autoindent. */ @@ -8692,6 +8693,23 @@ static char_u *do_insert_char_pre(int c) return res; } +/// Trigger "event" and take care of fixing undo. +static int ins_apply_autocmds(event_T event) +{ + varnumber_T tick = buf_get_changedtick(curbuf); + int r; + + r = apply_autocmds(event, NULL, NULL, false, curbuf); + + // If u_savesub() was called then we are not prepared to start + // a new line. Call u_save() with no contents to fix that. + if (tick != buf_get_changedtick(curbuf)) { + u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1)); + } + + return r; +} + static void show_pum(int prev_w_wrow, int prev_w_leftcol) { // RedrawingDisabled may be set when invoked through complete(). diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 547ffe5a46..e4ab3ccea8 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1239,10 +1239,8 @@ func Test_TextChangedI_with_setline() call assert_equal('(', getline(1)) call assert_equal('x)', getline(2)) undo - call assert_equal('(', getline(1)) - call assert_equal('', getline(2)) - undo call assert_equal('', getline(1)) + call assert_equal('', getline(2)) call test_override('starting', 0) bwipe! |