0
0
mirror of https://github.com/vim/vim.git synced 2025-08-25 19:53:53 -04:00

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: #17294

Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Sean Dewar 2025-05-11 13:45:21 +02:00 committed by Christian Brabandt
parent 7344024536
commit d4110e0695
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
3 changed files with 91 additions and 5 deletions

View File

@ -2135,16 +2135,24 @@ apply_autocmds_group(
if (event_ignored(event, p_ei)) if (event_ignored(event, p_ei))
goto BYPASS_AU; goto BYPASS_AU;
wininfo_T *wip;
int win_ignore = FALSE; int win_ignore = FALSE;
// If event is allowed in 'eventignorewin', check if curwin or all windows // If event is allowed in 'eventignorewin', check if curwin or all windows
// into "buf" are ignoring the event. // into "buf" are ignoring the event.
if (buf == curbuf && event_tab[event].key <= 0) if (buf == curbuf && event_tab[event].key <= 0)
win_ignore = event_ignored(event, curwin->w_p_eiw); win_ignore = event_ignored(event, curwin->w_p_eiw);
else if (buf != NULL && event_tab[event].key <= 0) else if (buf != NULL && event_tab[event].key <= 0 && buf->b_nwindows > 0)
FOR_ALL_BUF_WININFO(buf, wip) {
if (wip->wi_win != NULL && wip->wi_win->w_buffer == buf) tabpage_T *tp;
win_ignore = event_ignored(event, wip->wi_win->w_p_eiw); win_T *wp;
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;
}
}
if (win_ignore) if (win_ignore)
goto BYPASS_AU; goto BYPASS_AU;

View File

@ -5314,4 +5314,80 @@ func Test_autocmd_tabclosedpre()
bw! bw!
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1380,
/**/ /**/
1379, 1379,
/**/ /**/