patch 9.1.1419: It is difficult to ignore all but some events
Problem: It is difficult to ignore all but some events.
Solution: Add support for a "-" prefix syntax in '(win)eventignore' that
subtracts an event from the ignored set if present
(Luuk van Baal).
closes: #17392
Signed-off-by: Luuk van Baal <luukvbaal@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 47f56c0..d69c204 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.1. Last change: 2025 May 30
+*options.txt* For Vim version 9.1. Last change: 2025 May 31
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -3377,6 +3377,9 @@
Otherwise this is a comma-separated list of event names. Example: >
:set ei=WinEnter,WinLeave
<
+ To ignore all but some events, a "-" prefix can be used: >
+ :set ei=all,-WinLeave
+<
*'eventignorewin'* *'eiw'*
'eventignorewin' 'eiw' string (default "")
window-local
diff --git a/src/autocmd.c b/src/autocmd.c
index 6a5f035..c8e51b2 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -803,16 +803,26 @@
int
event_ignored(event_T event, char_u *ei)
{
+ int ignored = FALSE;
while (*ei != NUL)
{
- if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ',')
- && (ei == p_ei || (event_tab[event].key <= 0)))
- return TRUE;
- if (event_name2nr(ei, &ei) == event)
- return TRUE;
+ int unignore = *ei == '-';
+ ei += unignore;
+ if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ','))
+ {
+ ignored = ei == p_ei || (event_tab[event].key <= 0);
+ ei += 3 + (ei[3] == ',');
+ }
+ else if (event_name2nr(ei, &ei) == event)
+ {
+ if (unignore)
+ return FALSE;
+ else
+ ignored = TRUE;
+ }
}
- return FALSE;
+ return ignored;
}
/*
@@ -827,13 +837,10 @@
while (*ei)
{
if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ','))
- {
- ei += 3;
- if (*ei == ',')
- ++ei;
- }
+ ei += 3 + (ei[3] == ',');
else
{
+ ei += (*ei == '-');
event_T event = event_name2nr(ei, &ei);
if (event == NUM_EVENTS || (win && event_tab[event].key > 0))
return FAIL;
diff --git a/src/optionstr.c b/src/optionstr.c
index 603d0f4..d667e53 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -2248,11 +2248,18 @@
static char_u *
get_eventignore_name(expand_T *xp, int idx)
{
+ int subtract = *xp->xp_pattern == '-';
// 'eventignore(win)' allows special keyword "all" in addition to
// all event names.
- if (idx == 0)
+ if (!subtract && idx == 0)
return (char_u *)"all";
- return get_event_name_no_group(xp, idx - 1, expand_eiw);
+
+ char_u *name = get_event_name_no_group(xp, idx - 1 + subtract, expand_eiw);
+ if (name == NULL)
+ return NULL;
+
+ sprintf((char *)IObuff, "%s%s", subtract ? "-" : "", name);
+ return IObuff;
}
int
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index 1f15453..5b9616f 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -195,9 +195,9 @@
\ ['xxx']],
\ 'eadirection': [['', 'both', 'ver', 'hor'], ['xxx', 'ver,hor']],
\ 'encoding': [['latin1'], ['xxx', '']],
- \ 'eventignore': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
+ \ 'eventignore': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter', 'all,-WinLeave'],
\ ['xxx']],
- \ 'eventignorewin': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
+ \ 'eventignorewin': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter', 'all,-WinLeave'],
\ ['xxx', 'WinNew']],
\ 'fileencoding': [['', 'latin1', 'xxx'], []],
\ 'fileformat': [['', 'dos', 'unix', 'mac'], ['xxx']],
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index dfeb93f..3dc4960 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -5463,4 +5463,20 @@
%bw!
endfunc
+func Test_eventignore_subtract()
+ set eventignore=all,-WinEnter
+ augroup testing
+ autocmd!
+ autocmd WinEnter * ++once let s:triggered = 1
+ augroup END
+
+ new
+ call assert_equal(1, s:triggered)
+
+ set eventignore&
+ unlet! s:triggered
+ call CleanUpTestAuGroup()
+ %bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 8679198..e85dd6a 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -602,6 +602,7 @@
" Other string options that queries the system rather than fixed enum names
call assert_equal(['all', 'BufAdd'], getcompletion('set eventignore=', 'cmdline')[0:1])
+ call assert_equal(['-BufAdd', '-BufCreate'], getcompletion('set eventignore=all,-', 'cmdline')[0:1])
call assert_equal(['WinLeave', 'WinResized', 'WinScrolled'], getcompletion('set eiw=', 'cmdline')[-3:-1])
call assert_equal('latin1', getcompletion('set fileencodings=', 'cmdline')[1])
call assert_equal('top', getcompletion('set printoptions=', 'cmdline')[0])
diff --git a/src/version.c b/src/version.c
index 8b10cf4..6c7a2ab 100644
--- a/src/version.c
+++ b/src/version.c
@@ -710,6 +710,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1419,
+/**/
1418,
/**/
1417,