aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/edit.c48
-rw-r--r--src/nvim/testdir/test_autocmd.vim4
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!