aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Felice <jason.m.felice@gmail.com>2018-08-08 16:11:32 -0700
committerJason Felice <jason.m.felice@gmail.com>2018-08-09 16:46:50 -0700
commit3c41df269173b68aa5572df8c5b7cae408229b88 (patch)
tree6c7473dceec58693dee6923708fc7da929ba106c /src
parentd45efa5793e8b60192cc5b1f80d112d0401b14d3 (diff)
downloadrneovim-3c41df269173b68aa5572df8c5b7cae408229b88.tar.gz
rneovim-3c41df269173b68aa5572df8c5b7cae408229b88.tar.bz2
rneovim-3c41df269173b68aa5572df8c5b7cae408229b88.zip
vim-patch:8.1.0256: using setline() in TextChangedI splits undo
Problem: Using setline() in TextChangedI splits undo. Solution: Use another solution for undo not working properly. https://github.com/vim/vim/commit/9fa9506853516c82851baec643aa47458cb8b3bc This deviates from Vim in the handling of the CursorHoldI event. In Vim, any buffer changes are merged into the insert. In Neovim, CursorHoldI is handled via the multiqueue, and the point at which the cursor hold is implemented (in input.c) doesn't know enough about it. Making all queued events merge into the insert seems more wronger since changes by other asynchronous events really should be separately undoable.
Diffstat (limited to 'src')
-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!