comparison src/edit.c @ 14485:c71d65c3672f v8.1.0256

patch 8.1.0256: using setline() in TextChangedI splits undo commit https://github.com/vim/vim/commit/9fa9506853516c82851baec643aa47458cb8b3bc Author: Bram Moolenaar <Bram@vim.org> Date: Wed Aug 8 22:08:32 2018 +0200 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.
author Christian Brabandt <cb@256bit.org>
date Wed, 08 Aug 2018 22:15:05 +0200
parents 78d4375b6bb2
children a9665096074b
comparison
equal deleted inserted replaced
14484:c7016941d02a 14485:c71d65c3672f
277 #endif 277 #endif
278 static colnr_T get_nolist_virtcol(void); 278 static colnr_T get_nolist_virtcol(void);
279 #if defined(FEAT_EVAL) 279 #if defined(FEAT_EVAL)
280 static char_u *do_insert_char_pre(int c); 280 static char_u *do_insert_char_pre(int c);
281 #endif 281 #endif
282 static int ins_apply_autocmds(event_T event);
282 283
283 static colnr_T Insstart_textlen; /* length of line when insert started */ 284 static colnr_T Insstart_textlen; /* length of line when insert started */
284 static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */ 285 static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */
285 static int update_Insstart_orig = TRUE; /* set Insstart_orig to Insstart */ 286 static int update_Insstart_orig = TRUE; /* set Insstart_orig to Insstart */
286 287
409 else 410 else
410 ptr = (char_u *)"i"; 411 ptr = (char_u *)"i";
411 set_vim_var_string(VV_INSERTMODE, ptr, 1); 412 set_vim_var_string(VV_INSERTMODE, ptr, 1);
412 set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ 413 set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */
413 #endif 414 #endif
414 apply_autocmds(EVENT_INSERTENTER, NULL, NULL, FALSE, curbuf); 415 ins_apply_autocmds(EVENT_INSERTENTER);
415 416
416 /* Make sure the cursor didn't move. Do call check_cursor_col() in 417 /* Make sure the cursor didn't move. Do call check_cursor_col() in
417 * case the text was modified. Since Insert mode was not started yet 418 * case the text was modified. Since Insert mode was not started yet
418 * a call to check_cursor_col() may move the cursor, especially with 419 * a call to check_cursor_col() may move the cursor, especially with
419 * the "A" command, thus set State to avoid that. Also check that the 420 * the "A" command, thus set State to avoid that. Also check that the
1059 o_lnum = curwin->w_cursor.lnum; 1060 o_lnum = curwin->w_cursor.lnum;
1060 1061
1061 if (ins_esc(&count, cmdchar, nomove)) 1062 if (ins_esc(&count, cmdchar, nomove))
1062 { 1063 {
1063 if (cmdchar != 'r' && cmdchar != 'v') 1064 if (cmdchar != 'r' && cmdchar != 'v')
1064 apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL, 1065 ins_apply_autocmds(EVENT_INSERTLEAVE);
1065 FALSE, curbuf);
1066 did_cursorhold = FALSE; 1066 did_cursorhold = FALSE;
1067 return (c == Ctrl_O); 1067 return (c == Ctrl_O);
1068 } 1068 }
1069 continue; 1069 continue;
1070 1070
1273 1273
1274 case K_IGNORE: /* Something mapped to nothing */ 1274 case K_IGNORE: /* Something mapped to nothing */
1275 break; 1275 break;
1276 1276
1277 case K_CURSORHOLD: /* Didn't type something for a while. */ 1277 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);
1279 did_cursorhold = TRUE; 1279 did_cursorhold = TRUE;
1280 break; 1280 break;
1281 1281
1282 #ifdef FEAT_GUI_W32 1282 #ifdef FEAT_GUI_W32
1283 /* On Win32 ignore <M-F4>, we get it when closing the window was 1283 /* On Win32 ignore <M-F4>, we get it when closing the window was
1696 if (has_cursormovedI()) 1696 if (has_cursormovedI())
1697 { 1697 {
1698 /* Make sure curswant is correct, an autocommand may call 1698 /* Make sure curswant is correct, an autocommand may call
1699 * getcurpos(). */ 1699 * getcurpos(). */
1700 update_curswant(); 1700 update_curswant();
1701 apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf); 1701 ins_apply_autocmds(EVENT_CURSORMOVEDI);
1702 } 1702 }
1703 # ifdef FEAT_CONCEAL 1703 # ifdef FEAT_CONCEAL
1704 if (curwin->w_p_cole > 0) 1704 if (curwin->w_p_cole > 0)
1705 { 1705 {
1706 conceal_old_cursor_line = last_cursormoved.lnum; 1706 conceal_old_cursor_line = last_cursormoved.lnum;
1719 && !pum_visible() 1719 && !pum_visible()
1720 #endif 1720 #endif
1721 ) 1721 )
1722 { 1722 {
1723 aco_save_T aco; 1723 aco_save_T aco;
1724 1724 varnumber_T tick = CHANGEDTICK(curbuf);
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
1730 1725
1731 // save and restore curwin and curbuf, in case the autocmd changes them 1726 // save and restore curwin and curbuf, in case the autocmd changes them
1732 aucmd_prepbuf(&aco, curbuf); 1727 aucmd_prepbuf(&aco, curbuf);
1733 apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf); 1728 apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
1734 aucmd_restbuf(&aco); 1729 aucmd_restbuf(&aco);
1735 curbuf->b_last_changedtick = CHANGEDTICK(curbuf); 1730 curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
1736 1731 if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds()
1737 #ifdef FEAT_EVAL 1732 u_save(curwin->w_cursor.lnum,
1738 if (u_sync_once == 1) 1733 (linenr_T)(curwin->w_cursor.lnum + 1));
1739 ins_need_undo = TRUE;
1740 u_sync_once = 0;
1741 #endif
1742 } 1734 }
1743 1735
1744 #ifdef FEAT_INS_EXPAND 1736 #ifdef FEAT_INS_EXPAND
1745 /* Trigger TextChangedP if b_changedtick differs. When the popupmenu closes 1737 /* Trigger TextChangedP if b_changedtick differs. When the popupmenu closes
1746 * TextChangedI will need to trigger for backwards compatibility, thus use 1738 * TextChangedI will need to trigger for backwards compatibility, thus use
1748 if (ready && has_textchangedP() 1740 if (ready && has_textchangedP()
1749 && curbuf->b_last_changedtick_pum != CHANGEDTICK(curbuf) 1741 && curbuf->b_last_changedtick_pum != CHANGEDTICK(curbuf)
1750 && pum_visible()) 1742 && pum_visible())
1751 { 1743 {
1752 aco_save_T aco; 1744 aco_save_T aco;
1745 varnumber_T tick = CHANGEDTICK(curbuf);
1753 1746
1754 // save and restore curwin and curbuf, in case the autocmd changes them 1747 // save and restore curwin and curbuf, in case the autocmd changes them
1755 aucmd_prepbuf(&aco, curbuf); 1748 aucmd_prepbuf(&aco, curbuf);
1756 apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf); 1749 apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
1757 aucmd_restbuf(&aco); 1750 aucmd_restbuf(&aco);
1758 curbuf->b_last_changedtick_pum = CHANGEDTICK(curbuf); 1751 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));
1759 } 1755 }
1760 #endif 1756 #endif
1761 1757
1762 if (must_redraw) 1758 if (must_redraw)
1763 update_screen(0); 1759 update_screen(0);
4122 if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0))) 4118 if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0)))
4123 do_c_expr_indent(); 4119 do_c_expr_indent();
4124 #endif 4120 #endif
4125 /* Trigger the CompleteDone event to give scripts a chance to act 4121 /* Trigger the CompleteDone event to give scripts a chance to act
4126 * upon the completion. */ 4122 * upon the completion. */
4127 apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf); 4123 ins_apply_autocmds(EVENT_COMPLETEDONE);
4128 } 4124 }
4129 } 4125 }
4130 else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) 4126 else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
4131 /* Trigger the CompleteDone event to give scripts a chance to act 4127 /* Trigger the CompleteDone event to give scripts a chance to act
4132 * upon the (possibly failed) completion. */ 4128 * upon the (possibly failed) completion. */
4133 apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf); 4129 ins_apply_autocmds(EVENT_COMPLETEDONE);
4134 4130
4135 /* reset continue_* if we left expansion-mode, if we stay they'll be 4131 /* reset continue_* if we left expansion-mode, if we stay they'll be
4136 * (re)set properly in ins_complete() */ 4132 * (re)set properly in ins_complete() */
4137 if (!vim_is_ctrl_x_key(c)) 4133 if (!vim_is_ctrl_x_key(c))
4138 { 4134 {
8942 set_vim_var_string(VV_INSERTMODE, 8938 set_vim_var_string(VV_INSERTMODE,
8943 (char_u *)((State & REPLACE_FLAG) ? "i" 8939 (char_u *)((State & REPLACE_FLAG) ? "i"
8944 : replaceState == VREPLACE ? "v" 8940 : replaceState == VREPLACE ? "v"
8945 : "r"), 1); 8941 : "r"), 1);
8946 # endif 8942 # endif
8947 apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, FALSE, curbuf); 8943 ins_apply_autocmds(EVENT_INSERTCHANGE);
8948 if (State & REPLACE_FLAG) 8944 if (State & REPLACE_FLAG)
8949 State = INSERT | (State & LANGMAP); 8945 State = INSERT | (State & LANGMAP);
8950 else 8946 else
8951 State = replaceState | (State & LANGMAP); 8947 State = replaceState | (State & LANGMAP);
8952 AppendCharToRedobuff(K_INS); 8948 AppendCharToRedobuff(K_INS);
10736 /* Lock the text to avoid weird things from happening. */ 10732 /* Lock the text to avoid weird things from happening. */
10737 ++textlock; 10733 ++textlock;
10738 set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */ 10734 set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */
10739 10735
10740 res = NULL; 10736 res = NULL;
10741 if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) 10737 if (ins_apply_autocmds(EVENT_INSERTCHARPRE))
10742 { 10738 {
10743 /* Get the value of v:char. It may be empty or more than one 10739 /* Get the value of v:char. It may be empty or more than one
10744 * character. Only use it when changed, otherwise continue with the 10740 * character. Only use it when changed, otherwise continue with the
10745 * original character to avoid breaking autoindent. */ 10741 * original character to avoid breaking autoindent. */
10746 if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) 10742 if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0)
10751 --textlock; 10747 --textlock;
10752 10748
10753 return res; 10749 return res;
10754 } 10750 }
10755 #endif 10751 #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 }