mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
vim-patch:9.1.1380: 'eventignorewin' only checked for current buffer
Problem: When an autocommand executes for a non-current buffer,
'eventignorewin' is only checked from the buffer's last
wininfo (overwrites win_ignore in the loop), not from the
value of 'eventignorewin' in all windows showing the buffer as
described (after v9.1.1084)
Solution: Fix the check and don't use wininfo, as that may only contain
windows that recently showed the buffer. Consider all the
buffer's windows in all tabpages (Sean Dewar).
closes: vim/vim#17294
d4110e0695
Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
This commit is contained in:
@ -1635,11 +1635,12 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
// into "buf" are ignoring the event.
|
||||
if (buf == curbuf && event_names[event].event <= 0) {
|
||||
win_ignore = event_ignored(event, curwin->w_p_eiw);
|
||||
} else if (buf != NULL && event_names[event].event <= 0) {
|
||||
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||
WinInfo *wip = kv_A(buf->b_wininfo, i);
|
||||
if (wip->wi_win != NULL && wip->wi_win->w_buffer == buf) {
|
||||
win_ignore = event_ignored(event, wip->wi_win->w_p_eiw);
|
||||
} else if (buf != NULL && event_names[event].event <= 0 && buf->b_nwindows > 0) {
|
||||
win_ignore = true;
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||
if (wp->w_buffer == buf && !event_ignored(event, wp->w_p_eiw)) {
|
||||
win_ignore = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4406,4 +4406,80 @@ func Test_WinScrolled_Resized_eiw()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_eventignorewin_non_current()
|
||||
defer CleanUpTestAuGroup()
|
||||
let s:triggered = ''
|
||||
augroup testing
|
||||
" Will set <abuf> to the buffer of the closing window.
|
||||
autocmd WinClosed * let s:triggered = 'WinClosed'
|
||||
augroup END
|
||||
let initial_win = win_getid()
|
||||
|
||||
new
|
||||
let new_buf = bufnr()
|
||||
" Only set for one of the windows into the new buffer.
|
||||
setlocal eventignorewin=all
|
||||
split
|
||||
setlocal eventignorewin=
|
||||
let close_winnr = winnr()
|
||||
|
||||
" Return to the window where the buffer is non-current. WinClosed should
|
||||
" trigger as not all windows into new_buf have 'eventignorewin' set for it.
|
||||
call win_gotoid(initial_win)
|
||||
call assert_notequal(new_buf, bufnr())
|
||||
execute close_winnr 'close'
|
||||
call assert_equal('WinClosed', s:triggered)
|
||||
|
||||
wincmd w
|
||||
call assert_equal(new_buf, bufnr())
|
||||
tab split
|
||||
setlocal eventignorewin=
|
||||
let close_winnr = win_getid()
|
||||
|
||||
" Ensure that new_buf's window in the other tabpage with 'eventignorewin'
|
||||
" unset allows WinClosed to run when new_buf is non-current.
|
||||
call win_gotoid(initial_win)
|
||||
call assert_notequal(new_buf, bufnr())
|
||||
let s:triggered = ''
|
||||
only!
|
||||
call assert_equal('WinClosed', s:triggered)
|
||||
call assert_equal(1, win_findbuf(new_buf)->len())
|
||||
|
||||
" Create an only window to new_buf with 'eventignorewin' set.
|
||||
tabonly!
|
||||
execute new_buf 'sbuffer'
|
||||
setlocal eventignorewin=all
|
||||
wincmd p
|
||||
call assert_equal(1, win_findbuf(new_buf)->len())
|
||||
call assert_notequal(new_buf, bufnr())
|
||||
|
||||
" Closing a window unrelated to new_buf should not block WinClosed.
|
||||
split
|
||||
let s:triggered = ''
|
||||
close
|
||||
call assert_equal('WinClosed', s:triggered)
|
||||
call assert_equal(1, win_findbuf(new_buf)->len())
|
||||
|
||||
" Check WinClosed is blocked when we close the only window to new_buf (that
|
||||
" has 'eventignorewin' set) while new_buf is non-current.
|
||||
call assert_notequal(new_buf, bufnr())
|
||||
let s:triggered = ''
|
||||
only!
|
||||
call assert_equal('', s:triggered)
|
||||
call assert_equal(0, win_findbuf(new_buf)->len())
|
||||
|
||||
augroup testing
|
||||
autocmd!
|
||||
autocmd BufNew * ++once let s:triggered = 'BufNew'
|
||||
augroup END
|
||||
|
||||
" Buffer not shown in a window, 'eventignorewin' should not block (and
|
||||
" can't even be set for it anyway in this case).
|
||||
badd foo
|
||||
call assert_equal('BufNew', s:triggered)
|
||||
|
||||
unlet! s:triggered
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
Reference in New Issue
Block a user