To: vim_dev@googlegroups.com Subject: Patch 8.1.0256 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0256 (after 8.1.0245) Problem: Using setline() in TextChangedI splits undo. Solution: Use another solution for undo not working properly. Files: src/edit.c, src/testdir/test_autocmd.vim *** ../vim-8.1.0255/src/edit.c 2018-08-07 19:32:48.371651690 +0200 --- src/edit.c 2018-08-08 22:07:51.235091964 +0200 *************** *** 279,284 **** --- 279,285 ---- #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,417 **** 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); /* 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 --- 412,418 ---- set_vim_var_string(VV_INSERTMODE, ptr, 1); set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ #endif ! 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,1068 **** if (ins_esc(&count, cmdchar, nomove)) { if (cmdchar != 'r' && cmdchar != 'v') ! apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL, ! FALSE, curbuf); did_cursorhold = FALSE; return (c == Ctrl_O); } --- 1062,1068 ---- if (ins_esc(&count, cmdchar, nomove)) { if (cmdchar != 'r' && cmdchar != 'v') ! ins_apply_autocmds(EVENT_INSERTLEAVE); did_cursorhold = FALSE; return (c == Ctrl_O); } *************** *** 1275,1281 **** break; case K_CURSORHOLD: /* Didn't type something for a while. */ ! apply_autocmds(EVENT_CURSORHOLDI, NULL, NULL, FALSE, curbuf); did_cursorhold = TRUE; break; --- 1275,1281 ---- break; case K_CURSORHOLD: /* Didn't type something for a while. */ ! ins_apply_autocmds(EVENT_CURSORHOLDI); did_cursorhold = TRUE; break; *************** *** 1698,1704 **** /* Make sure curswant is correct, an autocommand may call * getcurpos(). */ update_curswant(); ! apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf); } # ifdef FEAT_CONCEAL if (curwin->w_p_cole > 0) --- 1698,1704 ---- /* Make sure curswant is correct, an autocommand may call * getcurpos(). */ update_curswant(); ! ins_apply_autocmds(EVENT_CURSORMOVEDI); } # ifdef FEAT_CONCEAL if (curwin->w_p_cole > 0) *************** *** 1721,1744 **** ) { 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 // 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 } #ifdef FEAT_INS_EXPAND --- 1721,1736 ---- ) { 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_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf); aucmd_restbuf(&aco); curbuf->b_last_changedtick = CHANGEDTICK(curbuf); ! 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,1761 **** --- 1742,1757 ---- && 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,4136 **** #endif /* Trigger the CompleteDone event to give scripts a chance to act * upon the completion. */ ! apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf); } } 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); /* reset continue_* if we left expansion-mode, if we stay they'll be * (re)set properly in ins_complete() */ --- 4120,4132 ---- #endif /* Trigger the CompleteDone event to give scripts a chance to act * upon the completion. */ ! 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. */ ! 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,8950 **** : replaceState == VREPLACE ? "v" : "r"), 1); # endif ! apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, FALSE, curbuf); if (State & REPLACE_FLAG) State = INSERT | (State & LANGMAP); else --- 8940,8946 ---- : replaceState == VREPLACE ? "v" : "r"), 1); # endif ! ins_apply_autocmds(EVENT_INSERTCHANGE); if (State & REPLACE_FLAG) State = INSERT | (State & LANGMAP); else *************** *** 10738,10744 **** set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */ res = NULL; ! if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) { /* Get the value of v:char. It may be empty or more than one * character. Only use it when changed, otherwise continue with the --- 10734,10740 ---- set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */ res = NULL; ! 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,10755 **** --- 10749,10770 ---- 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; + } *** ../vim-8.1.0255/src/testdir/test_autocmd.vim 2018-08-07 19:04:57.409627129 +0200 --- src/testdir/test_autocmd.vim 2018-08-08 21:43:44.368570016 +0200 *************** *** 1329,1338 **** 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 test_override('starting', 0) bwipe! --- 1329,1336 ---- call assert_equal('(', getline(1)) call assert_equal('x)', getline(2)) undo call assert_equal('', getline(1)) + call assert_equal('', getline(2)) call test_override('starting', 0) bwipe! *** ../vim-8.1.0255/src/version.c 2018-08-08 11:02:26.855415573 +0200 --- src/version.c 2018-08-08 21:43:06.112860972 +0200 *************** *** 796,797 **** --- 796,799 ---- { /* Add new patch number below this line */ + /**/ + 256, /**/ -- If "R" is Reverse, how come "D" is FORWARD? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///