@@ -279,6 +279,7 @@ static colnr_T get_nolist_virtcol(void);
279279#if defined(FEAT_EVAL )
280280static char_u * do_insert_char_pre (int c );
281281#endif
282+ static int ins_apply_autocmds (event_T event );
282283
283284static colnr_T Insstart_textlen ; /* length of line when insert started */
284285static colnr_T Insstart_blank_vcol ; /* vcol for first inserted blank */
@@ -411,7 +412,7 @@ edit(
411412 set_vim_var_string (VV_INSERTMODE , ptr , 1 );
412413 set_vim_var_string (VV_CHAR , NULL , -1 ); /* clear v:char */
413414#endif
414- apply_autocmds (EVENT_INSERTENTER , NULL , NULL , FALSE, curbuf );
415+ ins_apply_autocmds (EVENT_INSERTENTER );
415416
416417 /* Make sure the cursor didn't move. Do call check_cursor_col() in
417418 * case the text was modified. Since Insert mode was not started yet
@@ -1061,8 +1062,7 @@ edit(
10611062 if (ins_esc (& count , cmdchar , nomove ))
10621063 {
10631064 if (cmdchar != 'r' && cmdchar != 'v' )
1064- apply_autocmds (EVENT_INSERTLEAVE , NULL , NULL ,
1065- FALSE, curbuf );
1065+ ins_apply_autocmds (EVENT_INSERTLEAVE );
10661066 did_cursorhold = FALSE;
10671067 return (c == Ctrl_O );
10681068 }
@@ -1275,7 +1275,7 @@ edit(
12751275 break ;
12761276
12771277 case K_CURSORHOLD : /* Didn't type something for a while. */
1278- apply_autocmds (EVENT_CURSORHOLDI , NULL , NULL , FALSE, curbuf );
1278+ ins_apply_autocmds (EVENT_CURSORHOLDI );
12791279 did_cursorhold = TRUE;
12801280 break ;
12811281
@@ -1698,7 +1698,7 @@ ins_redraw(
16981698 /* Make sure curswant is correct, an autocommand may call
16991699 * getcurpos(). */
17001700 update_curswant ();
1701- apply_autocmds (EVENT_CURSORMOVEDI , NULL , NULL , FALSE, curbuf );
1701+ ins_apply_autocmds (EVENT_CURSORMOVEDI );
17021702 }
17031703# ifdef FEAT_CONCEAL
17041704 if (curwin -> w_p_cole > 0 )
@@ -1721,24 +1721,16 @@ ins_redraw(
17211721 )
17221722 {
17231723 aco_save_T aco ;
1724-
1725- #ifdef FEAT_EVAL
1726- // Sync undo when the autocommand calls setline() or append(), so that
1727- // it can be undone separately.
1728- u_sync_once = 2 ;
1729- #endif
1724+ varnumber_T tick = CHANGEDTICK (curbuf );
17301725
17311726 // save and restore curwin and curbuf, in case the autocmd changes them
17321727 aucmd_prepbuf (& aco , curbuf );
17331728 apply_autocmds (EVENT_TEXTCHANGEDI , NULL , NULL , FALSE, curbuf );
17341729 aucmd_restbuf (& aco );
17351730 curbuf -> b_last_changedtick = CHANGEDTICK (curbuf );
1736-
1737- #ifdef FEAT_EVAL
1738- if (u_sync_once == 1 )
1739- ins_need_undo = TRUE;
1740- u_sync_once = 0 ;
1741- #endif
1731+ if (tick != CHANGEDTICK (curbuf )) // see ins_apply_autocmds()
1732+ u_save (curwin -> w_cursor .lnum ,
1733+ (linenr_T )(curwin -> w_cursor .lnum + 1 ));
17421734 }
17431735
17441736#ifdef FEAT_INS_EXPAND
@@ -1750,12 +1742,16 @@ ins_redraw(
17501742 && pum_visible ())
17511743 {
17521744 aco_save_T aco ;
1745+ varnumber_T tick = CHANGEDTICK (curbuf );
17531746
17541747 // save and restore curwin and curbuf, in case the autocmd changes them
17551748 aucmd_prepbuf (& aco , curbuf );
17561749 apply_autocmds (EVENT_TEXTCHANGEDP , NULL , NULL , FALSE, curbuf );
17571750 aucmd_restbuf (& aco );
17581751 curbuf -> b_last_changedtick_pum = CHANGEDTICK (curbuf );
1752+ if (tick != CHANGEDTICK (curbuf )) // see ins_apply_autocmds()
1753+ u_save (curwin -> w_cursor .lnum ,
1754+ (linenr_T )(curwin -> w_cursor .lnum + 1 ));
17591755 }
17601756#endif
17611757
@@ -4124,13 +4120,13 @@ ins_compl_prep(int c)
41244120#endif
41254121 /* Trigger the CompleteDone event to give scripts a chance to act
41264122 * upon the completion. */
4127- apply_autocmds (EVENT_COMPLETEDONE , NULL , NULL , FALSE, curbuf );
4123+ ins_apply_autocmds (EVENT_COMPLETEDONE );
41284124 }
41294125 }
41304126 else if (ctrl_x_mode == CTRL_X_LOCAL_MSG )
41314127 /* Trigger the CompleteDone event to give scripts a chance to act
41324128 * upon the (possibly failed) completion. */
4133- apply_autocmds (EVENT_COMPLETEDONE , NULL , NULL , FALSE, curbuf );
4129+ ins_apply_autocmds (EVENT_COMPLETEDONE );
41344130
41354131 /* reset continue_* if we left expansion-mode, if we stay they'll be
41364132 * (re)set properly in ins_complete() */
@@ -8944,7 +8940,7 @@ ins_insert(int replaceState)
89448940 : replaceState == VREPLACE ? "v"
89458941 : "r" ), 1 );
89468942# endif
8947- apply_autocmds (EVENT_INSERTCHANGE , NULL , NULL , FALSE, curbuf );
8943+ ins_apply_autocmds (EVENT_INSERTCHANGE );
89488944 if (State & REPLACE_FLAG )
89498945 State = INSERT | (State & LANGMAP );
89508946 else
@@ -10738,7 +10734,7 @@ do_insert_char_pre(int c)
1073810734 set_vim_var_string (VV_CHAR , buf , -1 ); /* set v:char */
1073910735
1074010736 res = NULL ;
10741- if (apply_autocmds (EVENT_INSERTCHARPRE , NULL , NULL , FALSE, curbuf ))
10737+ if (ins_apply_autocmds (EVENT_INSERTCHARPRE ))
1074210738 {
1074310739 /* Get the value of v:char. It may be empty or more than one
1074410740 * character. Only use it when changed, otherwise continue with the
@@ -10753,3 +10749,22 @@ do_insert_char_pre(int c)
1075310749 return res ;
1075410750}
1075510751#endif
10752+
10753+ /*
10754+ * Trigger "event" and take care of fixing undo.
10755+ */
10756+ static int
10757+ ins_apply_autocmds (event_T event )
10758+ {
10759+ varnumber_T tick = CHANGEDTICK (curbuf );
10760+ int r ;
10761+
10762+ r = apply_autocmds (event , NULL , NULL , FALSE, curbuf );
10763+
10764+ // If u_savesub() was called then we are not prepared to start
10765+ // a new line. Call u_save() with no contents to fix that.
10766+ if (tick != CHANGEDTICK (curbuf ))
10767+ u_save (curwin -> w_cursor .lnum , (linenr_T )(curwin -> w_cursor .lnum + 1 ));
10768+
10769+ return r ;
10770+ }
0 commit comments