vim-patch:8.1.1795: no syntax HL after splitting windows with :bufdo

Problem:    No syntax HL after splitting windows with :bufdo. (Yasuhiro
            Matsumoto)
Solution:   Trigger Syntax autocommands in buffers that are active.
            (closes vim/vim#4761)
c7f1e40021
This commit is contained in:
Jan Edmund Lazo
2020-10-17 12:34:25 -04:00
parent e1ec2b0729
commit 242af4dc99
4 changed files with 97 additions and 30 deletions

View File

@@ -91,6 +91,7 @@ typedef struct {
#define BF_READERR 0x40 // got errors while reading the file #define BF_READERR 0x40 // got errors while reading the file
#define BF_DUMMY 0x80 // dummy buffer, only used internally #define BF_DUMMY 0x80 // dummy buffer, only used internally
#define BF_PRESERVED 0x100 // ":preserve" was used #define BF_PRESERVED 0x100 // ":preserve" was used
#define BF_SYN_SET 0x200 // 'syntax' option was set
// Mask to check for flags that prevent normal writing // Mask to check for flags that prevent normal writing
#define BF_WRITE_MASK (BF_NOTEDITED + BF_NEW + BF_READERR) #define BF_WRITE_MASK (BF_NOTEDITED + BF_NEW + BF_READERR)

View File

@@ -2058,6 +2058,10 @@ void ex_listdo(exarg_T *eap)
// Don't do syntax HL autocommands. Skipping the syntax file is a // Don't do syntax HL autocommands. Skipping the syntax file is a
// great speed improvement. // great speed improvement.
save_ei = au_event_disable(",Syntax"); save_ei = au_event_disable(",Syntax");
FOR_ALL_BUFFERS(buf) {
buf->b_flags &= ~BF_SYN_SET;
}
} }
if (eap->cmdidx == CMD_windo if (eap->cmdidx == CMD_windo
@@ -2252,9 +2256,32 @@ void ex_listdo(exarg_T *eap)
} }
if (save_ei != NULL) { if (save_ei != NULL) {
buf_T *bnext;
aco_save_T aco;
au_event_restore(save_ei); au_event_restore(save_ei);
apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
curbuf->b_fname, true, curbuf); for (buf_T *buf = firstbuf; buf != NULL; buf = bnext) {
bnext = buf->b_next;
if (buf->b_nwindows > 0 && (buf->b_flags & BF_SYN_SET)) {
buf->b_flags &= ~BF_SYN_SET;
// buffer was opened while Syntax autocommands were disabled,
// need to trigger them now.
if (buf == curbuf) {
apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
curbuf->b_fname, true, curbuf);
} else {
aucmd_prepbuf(&aco, buf);
apply_autocmds(EVENT_SYNTAX, buf->b_p_syn,
buf->b_fname, true, buf);
aucmd_restbuf(&aco);
}
// start over, in case autocommands messed things up.
bnext = firstbuf;
}
}
} }
} }

View File

@@ -3438,6 +3438,7 @@ ambw_end:
// recursively, to avoid endless recurrence. // recursively, to avoid endless recurrence.
apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, curbuf->b_fname, apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, curbuf->b_fname,
value_changed || syn_recursive == 1, curbuf); value_changed || syn_recursive == 1, curbuf);
curbuf->b_flags |= BF_SYN_SET;
syn_recursive--; syn_recursive--;
} else if (varp == &(curbuf->b_p_ft)) { } else if (varp == &(curbuf->b_p_ft)) {
// 'filetype' is set, trigger the FileType autocommand // 'filetype' is set, trigger the FileType autocommand

View File

@@ -475,6 +475,40 @@ func Test_bg_detection()
hi Normal ctermbg=NONE hi Normal ctermbg=NONE
endfunc endfunc
func Test_syntax_hangs()
if !has('reltime') || !has('float') || !has('syntax')
return
endif
" This pattern takes a long time to match, it should timeout.
new
call setline(1, ['aaa', repeat('abc ', 1000), 'ccc'])
let start = reltime()
set nolazyredraw redrawtime=101
syn match Error /\%#=1a*.*X\@<=b*/
redraw
let elapsed = reltimefloat(reltime(start))
call assert_true(elapsed > 0.1)
call assert_true(elapsed < 1.0)
" second time syntax HL is disabled
let start = reltime()
redraw
let elapsed = reltimefloat(reltime(start))
call assert_true(elapsed < 0.1)
" after CTRL-L the timeout flag is reset
let start = reltime()
exe "normal \<C-L>"
redraw
let elapsed = reltimefloat(reltime(start))
call assert_true(elapsed > 0.1)
call assert_true(elapsed < 1.0)
set redrawtime&
bwipe!
endfunc
func Test_synstack_synIDtrans() func Test_synstack_synIDtrans()
new new
setfiletype c setfiletype c
@@ -550,38 +584,42 @@ func Test_syn_wrong_z_one()
bwipe! bwipe!
endfunc endfunc
func Test_syntax_hangs() func Test_syntax_after_bufdo()
if !has('reltime') || !has('float') || !has('syntax') call writefile(['/* aaa comment */'], 'Xaaa.c')
return call writefile(['/* bbb comment */'], 'Xbbb.c')
endif call writefile(['/* ccc comment */'], 'Xccc.c')
call writefile(['/* ddd comment */'], 'Xddd.c')
" This pattern takes a long time to match, it should timeout. let bnr = bufnr('%')
new new Xaaa.c
call setline(1, ['aaa', repeat('abc ', 1000), 'ccc']) badd Xbbb.c
let start = reltime() badd Xccc.c
set nolazyredraw redrawtime=101 badd Xddd.c
syn match Error /\%#=1a*.*X\@<=b*/ exe "bwipe " . bnr
redraw let l = []
let elapsed = reltimefloat(reltime(start)) bufdo call add(l, bufnr('%'))
call assert_true(elapsed > 0.1) call assert_equal(4, len(l))
call assert_true(elapsed < 1.0)
" second time syntax HL is disabled syntax on
let start = reltime()
redraw
let elapsed = reltimefloat(reltime(start))
call assert_true(elapsed < 0.1)
" after CTRL-L the timeout flag is reset " This used to only enable syntax HL in the last buffer.
let start = reltime() bufdo tab split
exe "normal \<C-L>" tabrewind
redraw for tab in range(1, 4)
let elapsed = reltimefloat(reltime(start)) norm fm
call assert_true(elapsed > 0.1) call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
call assert_true(elapsed < 1.0) tabnext
endfor
set redrawtime& bwipe! Xaaa.c
bwipe! bwipe! Xbbb.c
bwipe! Xccc.c
bwipe! Xddd.c
syntax off
call delete('Xaaa.c')
call delete('Xbbb.c')
call delete('Xccc.c')
call delete('Xddd.c')
endfunc endfunc
func Test_syntax_foldlevel() func Test_syntax_foldlevel()