Skip to content

Commit 91d2e78

Browse files
committed
patch 8.1.0245: calling setline() in TextChangedI autocmd breaks undo
Problem: Calling setline() in TextChangedI autocmd breaks undo. (Jason Felice) Solution: Don't save lines for undo when already saved. (closes #3291)
1 parent 917e32b commit 91d2e78

3 files changed

Lines changed: 36 additions & 1 deletion

File tree

src/edit.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,11 +1722,19 @@ ins_redraw(
17221722
{
17231723
aco_save_T aco;
17241724

1725+
// Sync undo when the autocommand calls setline() or append(), so that
1726+
// it can be undone separately.
1727+
u_sync_once = 2;
1728+
17251729
// save and restore curwin and curbuf, in case the autocmd changes them
17261730
aucmd_prepbuf(&aco, curbuf);
17271731
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
17281732
aucmd_restbuf(&aco);
17291733
curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
1734+
1735+
if (u_sync_once == 1)
1736+
ins_need_undo = TRUE;
1737+
u_sync_once = 0;
17301738
}
17311739

17321740
#ifdef FEAT_INS_EXPAND

src/testdir/test_autocmd.vim

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ func Test_OptionSet()
587587
" Cleanup
588588
au! OptionSet
589589
for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
590-
exe printf(":set %s&vi", opt)
590+
exe printf(":set %s&vim", opt)
591591
endfor
592592
call test_override('starting', 0)
593593
delfunc! AutoCommandOptionSet
@@ -1313,6 +1313,31 @@ func Test_ChangedP()
13131313
bw!
13141314
endfunc
13151315

1316+
let g:setline_handled = v:false
1317+
func! SetLineOne()
1318+
if !g:setline_handled
1319+
call setline(1, "(x)")
1320+
let g:setline_handled = v:true
1321+
endif
1322+
endfunc
1323+
1324+
func Test_TextChangedI_with_setline()
1325+
new
1326+
call test_override('char_avail', 1)
1327+
autocmd TextChangedI <buffer> call SetLineOne()
1328+
call feedkeys("i(\<CR>\<Esc>", 'tx')
1329+
call assert_equal('(', getline(1))
1330+
call assert_equal('x)', getline(2))
1331+
undo
1332+
call assert_equal('(', getline(1))
1333+
call assert_equal('', getline(2))
1334+
undo
1335+
call assert_equal('', getline(1))
1336+
1337+
call test_override('starting', 0)
1338+
bwipe!
1339+
endfunc
1340+
13161341
func Test_Changed_FirstTime()
13171342
if !has('terminal') || has('gui_running')
13181343
return

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,8 @@ static char *(features[]) =
794794

795795
static int included_patches[] =
796796
{ /* Add new patch number below this line */
797+
/**/
798+
245,
797799
/**/
798800
244,
799801
/**/

0 commit comments

Comments
 (0)