]> granicus.if.org Git - vim/commitdiff
patch 8.1.0256: using setline() in TextChangedI splits undo v8.1.0256
authorBram Moolenaar <Bram@vim.org>
Wed, 8 Aug 2018 20:08:32 +0000 (22:08 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 8 Aug 2018 20:08:32 +0000 (22:08 +0200)
Problem:    Using setline() in TextChangedI splits undo.
Solution:   Use another solution for undo not working properly.

src/edit.c
src/testdir/test_autocmd.vim
src/version.c

index 8ee4643570bad4a8fdcb466af4d142a3010e4db7..ff45bb7ee5eaf650cb8c0c41a662565c58932369 100644 (file)
@@ -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;
+}
index b52493fcb49cc6e779740fb27a14ad5d80f191c0..3d650e47366ca3876e43718cb69941b6d9de48bd 100644 (file)
@@ -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!
index 76d47dd63ee33ecb1357e1eef072d0ccb5051f51..8e21e9895279382619667f327d1043c8bd86a755 100644 (file)
@@ -794,6 +794,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    256,
 /**/
     255,
 /**/