summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-08-08 22:08:32 +0200
committerBram Moolenaar <Bram@vim.org>2018-08-08 22:08:32 +0200
commit9fa9506853516c82851baec643aa47458cb8b3bc (patch)
tree1540434465ce7d083128d486b80cc10f5b2c1d81
parentf8f88f89e12df516c1fac5851b504238ebc1d2d4 (diff)
patch 8.1.0256: using setline() in TextChangedI splits undov8.1.0256
Problem: Using setline() in TextChangedI splits undo. Solution: Use another solution for undo not working properly.
-rw-r--r--src/edit.c57
-rw-r--r--src/testdir/test_autocmd.vim4
-rw-r--r--src/version.c2
3 files changed, 39 insertions, 24 deletions
diff --git a/src/edit.c b/src/edit.c
index 8ee4643570..ff45bb7ee5 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -279,6 +279,7 @@ static colnr_T get_nolist_virtcol(void);
#if defined(FEAT_EVAL)
static char_u *do_insert_char_pre(int c);
#endif
+static int ins_apply_autocmds(event_T event);
static colnr_T Insstart_textlen; /* length of line when insert started */
static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */
@@ -411,7 +412,7 @@ edit(
set_vim_var_string(VV_INSERTMODE, ptr, 1);
set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */
#endif
- 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
@@ -1061,8 +1062,7 @@ doESCkey:
if (ins_esc(&count, cmdchar, nomove))
{
if (cmdchar != 'r' && cmdchar != 'v')
- apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL,
- FALSE, curbuf);
+ ins_apply_autocmds(EVENT_INSERTLEAVE);
did_cursorhold = FALSE;
return (c == Ctrl_O);
}
@@ -1275,7 +1275,7 @@ doESCkey:
break;
case K_CURSORHOLD: /* Didn't type something for a while. */
- apply_autocmds(EVENT_CURSORHOLDI, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_CURSORHOLDI);
did_cursorhold = TRUE;
break;
@@ -1698,7 +1698,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);
}
# ifdef FEAT_CONCEAL
if (curwin->w_p_cole > 0)
@@ -1721,24 +1721,16 @@ ins_redraw(
)
{
aco_save_T aco;
-
-#ifdef FEAT_EVAL
- // Sync undo when the autocommand calls setline() or append(), so that
- // it can be undone separately.
- u_sync_once = 2;
-#endif
+ varnumber_T tick = 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 = CHANGEDTICK(curbuf);
-
-#ifdef FEAT_EVAL
- if (u_sync_once == 1)
- ins_need_undo = TRUE;
- u_sync_once = 0;
-#endif
+ if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds()
+ u_save(curwin->w_cursor.lnum,
+ (linenr_T)(curwin->w_cursor.lnum + 1));
}
#ifdef FEAT_INS_EXPAND
@@ -1750,12 +1742,16 @@ ins_redraw(
&& pum_visible())
{
aco_save_T aco;
+ varnumber_T tick = 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 = CHANGEDTICK(curbuf);
+ if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds()
+ u_save(curwin->w_cursor.lnum,
+ (linenr_T)(curwin->w_cursor.lnum + 1));
}
#endif
@@ -4124,13 +4120,13 @@ ins_compl_prep(int c)
#endif
/* 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() */
@@ -8944,7 +8940,7 @@ ins_insert(int replaceState)
: replaceState == VREPLACE ? "v"
: "r"), 1);
# endif
- apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_INSERTCHANGE);
if (State & REPLACE_FLAG)
State = INSERT | (State & LANGMAP);
else
@@ -10738,7 +10734,7 @@ do_insert_char_pre(int c)
set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */
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
@@ -10753,3 +10749,22 @@ do_insert_char_pre(int c)
return res;
}
#endif
+
+/*
+ * Trigger "event" and take care of fixing undo.
+ */
+ static int
+ins_apply_autocmds(event_T event)
+{
+ varnumber_T tick = 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 != CHANGEDTICK(curbuf))
+ u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1));
+
+ return r;
+}
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index b52493fcb4..3d650e4736 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -1329,10 +1329,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!
diff --git a/src/version.c b/src/version.c
index 76d47dd63e..8e21e98952 100644
--- a/src/version.c
+++ b/src/version.c
@@ -795,6 +795,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 256,
+/**/
255,
/**/
254,