Skip to content

Commit

Permalink
patch 8.1.0256: using setline() in TextChangedI splits undo
Browse files Browse the repository at this point in the history
Problem:    Using setline() in TextChangedI splits undo.
Solution:   Use another solution for undo not working properly.
  • Loading branch information
brammool committed Aug 8, 2018
1 parent f8f88f8 commit 9fa9506
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 24 deletions.
57 changes: 36 additions & 21 deletions src/edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1061,8 +1062,7 @@ edit(
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);
}
Expand Down Expand Up @@ -1275,7 +1275,7 @@ edit(
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;

Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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() */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
4 changes: 1 addition & 3 deletions src/testdir/test_autocmd.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
256,
/**/
255,
/**/
Expand Down

0 comments on commit 9fa9506

Please sign in to comment.