0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 9.1.1084: Unable to persistently ignore events in a window and its buffers

Problem:  Unable to persistently ignore events in a window and its buffers.
Solution: Add 'eventignorewin' option to ignore events in a window and buffer
          (Luuk van Baal)

Add the window-local 'eventignorewin' option that is analogous to
'eventignore', but applies to a certain window and its buffers. Identify
events that should be allowed in 'eventignorewin', adapt "auto_event"
and "event_tab" to encode this information. Window context is not passed
onto apply_autocmds_group(), and when to ignore an event is a bit
ambiguous when "buf" is not "curbuf", rather than a large refactor, only
ignore an event when all windows into "buf" are ignoring the event.

closes: #16530

Signed-off-by: Luuk van Baal <luukvbaal@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Luuk van Baal 2025-02-08 18:52:39 +01:00 committed by Christian Brabandt
parent a35040f795
commit b7147f8236
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
21 changed files with 287 additions and 191 deletions

View File

@ -1,4 +1,4 @@
*autocmd.txt* For Vim version 9.1. Last change: 2024 Dec 04
*autocmd.txt* For Vim version 9.1. Last change: 2025 Feb 08
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1992,6 +1992,9 @@ To disable autocommands for some time use the 'eventignore' option. Note that
this may cause unexpected behavior, make sure you restore 'eventignore'
afterwards, using a |:try| block with |:finally|.
To disable autocmds indefinitely in a specific window use the 'eventignorewin'
option. This can only be used to ignore window and buffer related events.
*:noautocmd* *:noa*
To disable autocommands for just one command use the ":noautocmd" command
modifier. This will set 'eventignore' to "all" for the duration of the

View File

@ -1,4 +1,4 @@
*options.txt* For Vim version 9.1. Last change: 2025 Feb 01
*options.txt* For Vim version 9.1. Last change: 2025 Feb 08
VIM REFERENCE MANUAL by Bram Moolenaar
@ -3283,6 +3283,13 @@ A jump table for the options with a short description can be found at |Q_op|.
Otherwise this is a comma-separated list of event names. Example: >
:set ei=WinEnter,WinLeave
<
*'eventignorewin'* *'eiw'*
'eventignorewin' 'eiw' string (default "")
window-local
Similar to 'eventignore' but applies to a particular window and its
buffers, for which window and buffer related autocommands can be
ignored indefinitely without affecting the global 'eventignore'.
*'expandtab'* *'et'* *'noexpandtab'* *'noet'*
'expandtab' 'et' boolean (default off)
local to buffer

View File

@ -1,4 +1,4 @@
*quickref.txt* For Vim version 9.1. Last change: 2024 Nov 02
*quickref.txt* For Vim version 9.1. Last change: 2025 Feb 08
VIM REFERENCE MANUAL by Bram Moolenaar
@ -698,6 +698,7 @@ Short explanation of each option: *option-list*
'errorformat' 'efm' description of the lines in the error file
'esckeys' 'ek' recognize function keys in Insert mode
'eventignore' 'ei' autocommand events that are ignored
'eventignorewin' 'eiw' autocommand events that are ignored in a window
'expandtab' 'et' use spaces when <Tab> is inserted
'exrc' 'ex' read .vimrc and .exrc in the current directory
'fileencoding' 'fenc' file encoding for multibyte text

View File

@ -230,6 +230,7 @@ $quote eval.txt /*$quote*
'ef' options.txt /*'ef'*
'efm' options.txt /*'efm'*
'ei' options.txt /*'ei'*
'eiw' options.txt /*'eiw'*
'ek' options.txt /*'ek'*
'emo' options.txt /*'emo'*
'emoji' options.txt /*'emoji'*
@ -248,6 +249,7 @@ $quote eval.txt /*$quote*
'esckeys' options.txt /*'esckeys'*
'et' options.txt /*'et'*
'eventignore' options.txt /*'eventignore'*
'eventignorewin' options.txt /*'eventignorewin'*
'ex' options.txt /*'ex'*
'expandtab' options.txt /*'expandtab'*
'exrc' options.txt /*'exrc'*

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2025 Feb 01
*version9.txt* For Vim version 9.1. Last change: 2025 Feb 08
VIM REFERENCE MANUAL by Bram Moolenaar
@ -41696,6 +41696,7 @@ Options: ~
'completeitemalign' Order of |complete-items| in Insert mode completion
popup
'eventignorewin' autocommand events that are ignored in a window
'findfunc' Vim function to obtain the results for a |:find|
command
'messagesopt' configure |:messages| and |hit-enter| prompt

View File

@ -1,7 +1,7 @@
" These commands create the option window.
"
" Maintainer: The Vim Project <https://github.com/vim/vim>
" Last Change: 2024 Dec 07
" Last Change: 2025 Feb 08
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" If there already is an option window, jump to that one.
@ -1343,6 +1343,8 @@ call <SID>AddOption("virtualedit", gettext("when to use virtual editing: \"block
call <SID>OptionG("ve", &ve)
call <SID>AddOption("eventignore", gettext("list of autocommand events which are to be ignored"))
call <SID>OptionG("ei", &ei)
call <SID>AddOption("eventignorewin", gettext("list of autocommand events which are to be ignored in a window"))
call <SID>OptionG("eiw", &eiw)
call <SID>AddOption("loadplugins", gettext("load plugin scripts when starting up"))
call <SID>BinOptionG("lpl", &lpl)
call <SID>AddOption("exrc", gettext("enable reading .vimrc/.exrc/.gvimrc in the current directory"))

View File

@ -1,7 +1,7 @@
" Vim syntax file generator
" Language: Vim script
" Maintainer: Hirohito Higashi (h_east)
" Last Change: 2024 Feb 03
" Last Change: 2025 Feb 08
let s:keepcpo= &cpo
set cpo&vim
@ -378,14 +378,14 @@ function s:parse_vim_event(li)
new
exec 'read ' . file_name
norm! gg
exec '/^static keyvalue_T event_tab\[] = {$/+1;/^};$/-1yank'
exec '/^static keyvalue_T event_tab\[NUM_EVENTS] = {$/+1;/^};$/-1yank'
%delete _
put
g!/^\s*KEYVALUE_ENTRY(/d
for line in getline(1, line('$'))
let list = matchlist(line, '^\s*KEYVALUE_ENTRY(EVENT_\w\+,\s*"\(\w\+\)"')
let list = matchlist(line, '^\s*KEYVALUE_ENTRY(-\?EVENT_\w\+,\s*"\(\w\+\)"')
let item.name = list[1]
call add(a:li, copy(item))
endfor

View File

@ -2,7 +2,7 @@
" Language: Vim script
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
" Doug Kearns <dougkearns@gmail.com>
" Last Change: 2025 Feb 03
" Last Change: 2025 Feb 08
" Former Maintainer: Charles E. Campbell
" DO NOT CHANGE DIRECTLY.
@ -42,12 +42,12 @@ syn keyword vimStdPlugin contained Arguments Asm Break Cfilter Clear Continue Di
" vimOptions are caught only when contained in a vimSet {{{2
" GEN_SYN_VIM: vimOption normal, START_STR='syn keyword vimOption contained', END_STR='skipwhite nextgroup=vimSetEqual,vimSetMod'
syn keyword vimOption contained al aleph ari allowrevins ambw ambiwidth arab arabic arshape arabicshape acd autochdir ai autoindent ar autoread asd autoshelldir aw autowrite awa autowriteall bg background bs backspace bk backup bkc backupcopy bdir backupdir bex backupext bsk backupskip bdlay balloondelay beval ballooneval bevalterm balloonevalterm bexpr balloonexpr bo belloff bin binary bomb brk breakat bri breakindent briopt breakindentopt bsdir browsedir bh bufhidden bl buflisted bt buftype cmp casemap cdh cdhome cd cdpath cedit ccv charconvert cin cindent cink cinkeys cino cinoptions cinsd cinscopedecls cinw cinwords cb clipboard ch cmdheight cwh cmdwinheight cc colorcolumn co columns com comments cms commentstring cp compatible cpt complete cfu completefunc skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained cia completeitemalign cot completeopt cpp completepopup csl completeslash cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile efm errorformat ek esckeys ei eventignore et expandtab ex exrc fenc fileencoding fencs fileencodings ff fileformat ffs fileformats skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained cia completeitemalign cot completeopt cpp completepopup csl completeslash cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile efm errorformat ek esckeys ei eventignore eiw eventignorewin et expandtab ex exrc fenc fileencoding fencs fileencodings ff fileformat skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained ffs fileformats fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained imi iminsert ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained ma modifiable mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained re regexpengine rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained spell spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin skipwhite nextgroup=vimSetEqual,vimSetMod
syn keyword vimOption contained tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth winptydll wiw winwidth wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod
" vimOptions: These are the turn-off setting variants {{{2

View File

@ -82,30 +82,31 @@ typedef struct AutoPat
#define BUFNEWFILE_INDEX 9
#define BUFREAD_INDEX 10
// must be sorted by the 'value' field because it is used by bsearch()!
static keyvalue_T event_tab[] = {
KEYVALUE_ENTRY(EVENT_BUFADD, "BufAdd"),
KEYVALUE_ENTRY(EVENT_BUFADD, "BufCreate"),
KEYVALUE_ENTRY(EVENT_BUFDELETE, "BufDelete"),
KEYVALUE_ENTRY(EVENT_BUFENTER, "BufEnter"),
KEYVALUE_ENTRY(EVENT_BUFFILEPOST, "BufFilePost"),
KEYVALUE_ENTRY(EVENT_BUFFILEPRE, "BufFilePre"),
KEYVALUE_ENTRY(EVENT_BUFHIDDEN, "BufHidden"),
KEYVALUE_ENTRY(EVENT_BUFLEAVE, "BufLeave"),
KEYVALUE_ENTRY(EVENT_BUFNEW, "BufNew"),
KEYVALUE_ENTRY(EVENT_BUFNEWFILE, "BufNewFile"), // BUFNEWFILE_INDEX
KEYVALUE_ENTRY(EVENT_BUFREADPOST, "BufRead"), // BUFREAD_INDEX
KEYVALUE_ENTRY(EVENT_BUFREADCMD, "BufReadCmd"),
KEYVALUE_ENTRY(EVENT_BUFREADPOST, "BufReadPost"),
KEYVALUE_ENTRY(EVENT_BUFREADPRE, "BufReadPre"),
KEYVALUE_ENTRY(EVENT_BUFUNLOAD, "BufUnload"),
KEYVALUE_ENTRY(EVENT_BUFWINENTER, "BufWinEnter"),
KEYVALUE_ENTRY(EVENT_BUFWINLEAVE, "BufWinLeave"),
KEYVALUE_ENTRY(EVENT_BUFWIPEOUT, "BufWipeout"),
KEYVALUE_ENTRY(EVENT_BUFWRITEPRE, "BufWrite"),
KEYVALUE_ENTRY(EVENT_BUFWRITECMD, "BufWriteCmd"),
KEYVALUE_ENTRY(EVENT_BUFWRITEPOST, "BufWritePost"),
KEYVALUE_ENTRY(EVENT_BUFWRITEPRE, "BufWritePre"),
// Must be sorted by the 'value' field because it is used by bsearch()!
// Events with positive keys aren't allowed in 'eventignorewin'.
static keyvalue_T event_tab[NUM_EVENTS] = {
KEYVALUE_ENTRY(-EVENT_BUFADD, "BufAdd"),
KEYVALUE_ENTRY(-EVENT_BUFADD, "BufCreate"),
KEYVALUE_ENTRY(-EVENT_BUFDELETE, "BufDelete"),
KEYVALUE_ENTRY(-EVENT_BUFENTER, "BufEnter"),
KEYVALUE_ENTRY(-EVENT_BUFFILEPOST, "BufFilePost"),
KEYVALUE_ENTRY(-EVENT_BUFFILEPRE, "BufFilePre"),
KEYVALUE_ENTRY(-EVENT_BUFHIDDEN, "BufHidden"),
KEYVALUE_ENTRY(-EVENT_BUFLEAVE, "BufLeave"),
KEYVALUE_ENTRY(-EVENT_BUFNEW, "BufNew"),
KEYVALUE_ENTRY(-EVENT_BUFNEWFILE, "BufNewFile"), // BUFNEWFILE_INDEX
KEYVALUE_ENTRY(-EVENT_BUFREADPOST, "BufRead"), // BUFREAD_INDEX
KEYVALUE_ENTRY(-EVENT_BUFREADCMD, "BufReadCmd"),
KEYVALUE_ENTRY(-EVENT_BUFREADPOST, "BufReadPost"),
KEYVALUE_ENTRY(-EVENT_BUFREADPRE, "BufReadPre"),
KEYVALUE_ENTRY(-EVENT_BUFUNLOAD, "BufUnload"),
KEYVALUE_ENTRY(-EVENT_BUFWINENTER, "BufWinEnter"),
KEYVALUE_ENTRY(-EVENT_BUFWINLEAVE, "BufWinLeave"),
KEYVALUE_ENTRY(-EVENT_BUFWIPEOUT, "BufWipeout"),
KEYVALUE_ENTRY(-EVENT_BUFWRITEPRE, "BufWrite"),
KEYVALUE_ENTRY(-EVENT_BUFWRITECMD, "BufWriteCmd"),
KEYVALUE_ENTRY(-EVENT_BUFWRITEPOST, "BufWritePost"),
KEYVALUE_ENTRY(-EVENT_BUFWRITEPRE, "BufWritePre"),
KEYVALUE_ENTRY(EVENT_CMDLINECHANGED, "CmdlineChanged"),
KEYVALUE_ENTRY(EVENT_CMDLINEENTER, "CmdlineEnter"),
KEYVALUE_ENTRY(EVENT_CMDLINELEAVE, "CmdlineLeave"),
@ -117,44 +118,44 @@ static keyvalue_T event_tab[] = {
KEYVALUE_ENTRY(EVENT_COMPLETECHANGED, "CompleteChanged"),
KEYVALUE_ENTRY(EVENT_COMPLETEDONE, "CompleteDone"),
KEYVALUE_ENTRY(EVENT_COMPLETEDONEPRE, "CompleteDonePre"),
KEYVALUE_ENTRY(EVENT_CURSORHOLD, "CursorHold"),
KEYVALUE_ENTRY(EVENT_CURSORHOLDI, "CursorHoldI"),
KEYVALUE_ENTRY(EVENT_CURSORMOVED, "CursorMoved"),
KEYVALUE_ENTRY(EVENT_CURSORMOVEDC, "CursorMovedC"),
KEYVALUE_ENTRY(EVENT_CURSORMOVEDI, "CursorMovedI"),
KEYVALUE_ENTRY(-EVENT_CURSORHOLD, "CursorHold"),
KEYVALUE_ENTRY(-EVENT_CURSORHOLDI, "CursorHoldI"),
KEYVALUE_ENTRY(-EVENT_CURSORMOVED, "CursorMoved"),
KEYVALUE_ENTRY(-EVENT_CURSORMOVEDC, "CursorMovedC"),
KEYVALUE_ENTRY(-EVENT_CURSORMOVEDI, "CursorMovedI"),
KEYVALUE_ENTRY(EVENT_DIFFUPDATED, "DiffUpdated"),
KEYVALUE_ENTRY(EVENT_DIRCHANGED, "DirChanged"),
KEYVALUE_ENTRY(EVENT_DIRCHANGEDPRE, "DirChangedPre"),
KEYVALUE_ENTRY(EVENT_ENCODINGCHANGED, "EncodingChanged"),
KEYVALUE_ENTRY(EVENT_EXITPRE, "ExitPre"),
KEYVALUE_ENTRY(EVENT_FILEAPPENDCMD, "FileAppendCmd"),
KEYVALUE_ENTRY(EVENT_FILEAPPENDPOST, "FileAppendPost"),
KEYVALUE_ENTRY(EVENT_FILEAPPENDPRE, "FileAppendPre"),
KEYVALUE_ENTRY(EVENT_FILECHANGEDRO, "FileChangedRO"),
KEYVALUE_ENTRY(EVENT_FILECHANGEDSHELL, "FileChangedShell"),
KEYVALUE_ENTRY(EVENT_FILECHANGEDSHELLPOST, "FileChangedShellPost"),
KEYVALUE_ENTRY(-EVENT_FILEAPPENDCMD, "FileAppendCmd"),
KEYVALUE_ENTRY(-EVENT_FILEAPPENDPOST, "FileAppendPost"),
KEYVALUE_ENTRY(-EVENT_FILEAPPENDPRE, "FileAppendPre"),
KEYVALUE_ENTRY(-EVENT_FILECHANGEDRO, "FileChangedRO"),
KEYVALUE_ENTRY(-EVENT_FILECHANGEDSHELL, "FileChangedShell"),
KEYVALUE_ENTRY(-EVENT_FILECHANGEDSHELLPOST, "FileChangedShellPost"),
KEYVALUE_ENTRY(EVENT_ENCODINGCHANGED, "FileEncoding"),
KEYVALUE_ENTRY(EVENT_FILEREADCMD, "FileReadCmd"),
KEYVALUE_ENTRY(EVENT_FILEREADPOST, "FileReadPost"),
KEYVALUE_ENTRY(EVENT_FILEREADPRE, "FileReadPre"),
KEYVALUE_ENTRY(EVENT_FILETYPE, "FileType"),
KEYVALUE_ENTRY(EVENT_FILEWRITECMD, "FileWriteCmd"),
KEYVALUE_ENTRY(EVENT_FILEWRITEPOST, "FileWritePost"),
KEYVALUE_ENTRY(EVENT_FILEWRITEPRE, "FileWritePre"),
KEYVALUE_ENTRY(EVENT_FILTERREADPOST, "FilterReadPost"),
KEYVALUE_ENTRY(EVENT_FILTERREADPRE, "FilterReadPre"),
KEYVALUE_ENTRY(EVENT_FILTERWRITEPOST, "FilterWritePost"),
KEYVALUE_ENTRY(EVENT_FILTERWRITEPRE, "FilterWritePre"),
KEYVALUE_ENTRY(-EVENT_FILEREADCMD, "FileReadCmd"),
KEYVALUE_ENTRY(-EVENT_FILEREADPOST, "FileReadPost"),
KEYVALUE_ENTRY(-EVENT_FILEREADPRE, "FileReadPre"),
KEYVALUE_ENTRY(-EVENT_FILETYPE, "FileType"),
KEYVALUE_ENTRY(-EVENT_FILEWRITECMD, "FileWriteCmd"),
KEYVALUE_ENTRY(-EVENT_FILEWRITEPOST, "FileWritePost"),
KEYVALUE_ENTRY(-EVENT_FILEWRITEPRE, "FileWritePre"),
KEYVALUE_ENTRY(-EVENT_FILTERREADPOST, "FilterReadPost"),
KEYVALUE_ENTRY(-EVENT_FILTERREADPRE, "FilterReadPre"),
KEYVALUE_ENTRY(-EVENT_FILTERWRITEPOST, "FilterWritePost"),
KEYVALUE_ENTRY(-EVENT_FILTERWRITEPRE, "FilterWritePre"),
KEYVALUE_ENTRY(EVENT_FOCUSGAINED, "FocusGained"),
KEYVALUE_ENTRY(EVENT_FOCUSLOST, "FocusLost"),
KEYVALUE_ENTRY(EVENT_FUNCUNDEFINED, "FuncUndefined"),
KEYVALUE_ENTRY(EVENT_GUIENTER, "GUIEnter"),
KEYVALUE_ENTRY(EVENT_GUIFAILED, "GUIFailed"),
KEYVALUE_ENTRY(EVENT_INSERTCHANGE, "InsertChange"),
KEYVALUE_ENTRY(EVENT_INSERTCHARPRE, "InsertCharPre"),
KEYVALUE_ENTRY(EVENT_INSERTENTER, "InsertEnter"),
KEYVALUE_ENTRY(EVENT_INSERTLEAVE, "InsertLeave"),
KEYVALUE_ENTRY(EVENT_INSERTLEAVEPRE, "InsertLeavePre"),
KEYVALUE_ENTRY(-EVENT_INSERTCHANGE, "InsertChange"),
KEYVALUE_ENTRY(-EVENT_INSERTCHARPRE, "InsertCharPre"),
KEYVALUE_ENTRY(-EVENT_INSERTENTER, "InsertEnter"),
KEYVALUE_ENTRY(-EVENT_INSERTLEAVE, "InsertLeave"),
KEYVALUE_ENTRY(-EVENT_INSERTLEAVEPRE, "InsertLeavePre"),
KEYVALUE_ENTRY(EVENT_KEYINPUTPRE, "KeyInputPre"),
KEYVALUE_ENTRY(EVENT_MENUPOPUP, "MenuPopup"),
KEYVALUE_ENTRY(EVENT_MODECHANGED, "ModeChanged"),
@ -168,7 +169,7 @@ static keyvalue_T event_tab[] = {
KEYVALUE_ENTRY(EVENT_SESSIONLOADPOST, "SessionLoadPost"),
KEYVALUE_ENTRY(EVENT_SESSIONWRITEPOST, "SessionWritePost"),
KEYVALUE_ENTRY(EVENT_SHELLCMDPOST, "ShellCmdPost"),
KEYVALUE_ENTRY(EVENT_SHELLFILTERPOST, "ShellFilterPost"),
KEYVALUE_ENTRY(-EVENT_SHELLFILTERPOST, "ShellFilterPost"),
KEYVALUE_ENTRY(EVENT_SIGUSR1, "SigUSR1"),
KEYVALUE_ENTRY(EVENT_SOURCECMD, "SourceCmd"),
KEYVALUE_ENTRY(EVENT_SOURCEPOST, "SourcePost"),
@ -187,11 +188,11 @@ static keyvalue_T event_tab[] = {
KEYVALUE_ENTRY(EVENT_TERMINALWINOPEN, "TerminalWinOpen"),
KEYVALUE_ENTRY(EVENT_TERMRESPONSE, "TermResponse"),
KEYVALUE_ENTRY(EVENT_TERMRESPONSEALL, "TermResponseAll"),
KEYVALUE_ENTRY(EVENT_TEXTCHANGED, "TextChanged"),
KEYVALUE_ENTRY(EVENT_TEXTCHANGEDI, "TextChangedI"),
KEYVALUE_ENTRY(EVENT_TEXTCHANGEDP, "TextChangedP"),
KEYVALUE_ENTRY(EVENT_TEXTCHANGEDT, "TextChangedT"),
KEYVALUE_ENTRY(EVENT_TEXTYANKPOST, "TextYankPost"),
KEYVALUE_ENTRY(-EVENT_TEXTCHANGED, "TextChanged"),
KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDI, "TextChangedI"),
KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDP, "TextChangedP"),
KEYVALUE_ENTRY(-EVENT_TEXTCHANGEDT, "TextChangedT"),
KEYVALUE_ENTRY(-EVENT_TEXTYANKPOST, "TextYankPost"),
KEYVALUE_ENTRY(EVENT_USER, "User"),
KEYVALUE_ENTRY(EVENT_VIMENTER, "VimEnter"),
KEYVALUE_ENTRY(EVENT_VIMLEAVE, "VimLeave"),
@ -199,44 +200,17 @@ static keyvalue_T event_tab[] = {
KEYVALUE_ENTRY(EVENT_VIMRESIZED, "VimResized"),
KEYVALUE_ENTRY(EVENT_VIMRESUME, "VimResume"),
KEYVALUE_ENTRY(EVENT_VIMSUSPEND, "VimSuspend"),
KEYVALUE_ENTRY(EVENT_WINCLOSED, "WinClosed"),
KEYVALUE_ENTRY(EVENT_WINENTER, "WinEnter"),
KEYVALUE_ENTRY(EVENT_WINLEAVE, "WinLeave"),
KEYVALUE_ENTRY(-EVENT_WINCLOSED, "WinClosed"),
KEYVALUE_ENTRY(-EVENT_WINENTER, "WinEnter"),
KEYVALUE_ENTRY(-EVENT_WINLEAVE, "WinLeave"),
KEYVALUE_ENTRY(EVENT_WINNEW, "WinNew"),
KEYVALUE_ENTRY(EVENT_WINNEWPRE, "WinNewPre"),
KEYVALUE_ENTRY(EVENT_WINRESIZED, "WinResized"),
KEYVALUE_ENTRY(EVENT_WINSCROLLED, "WinScrolled")
KEYVALUE_ENTRY(-EVENT_WINRESIZED, "WinResized"),
KEYVALUE_ENTRY(-EVENT_WINSCROLLED, "WinScrolled"),
};
static AutoPat *first_autopat[NUM_EVENTS] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL
};
static AutoPat *last_autopat[NUM_EVENTS] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL
};
static AutoPat *first_autopat[NUM_EVENTS] = { NULL };
static AutoPat *last_autopat[NUM_EVENTS] = { NULL };
#define AUGROUP_DEFAULT (-1) // default autocmd group
#define AUGROUP_ERROR (-2) // erroneous autocmd group
@ -715,17 +689,17 @@ event_name2nr(char_u *start, char_u **end)
// so we check for them first.
if (cmp_keyvalue_value_ni(&target, bufnewfile) == 0)
entry = bufnewfile;
else
if (cmp_keyvalue_value_ni(&target, bufread) == 0)
else if (cmp_keyvalue_value_ni(&target, bufread) == 0)
entry = bufread;
else
entry = (keyvalue_T *)bsearch(&target, &event_tab, ARRAY_LENGTH(event_tab), sizeof(event_tab[0]), cmp_keyvalue_value_ni);
entry = (keyvalue_T *)bsearch(&target, &event_tab, NUM_EVENTS,
sizeof(event_tab[0]), cmp_keyvalue_value_ni);
if (*p == ',')
++p;
*end = p;
return (entry == NULL) ? NUM_EVENTS : (event_T)entry->key;
return (entry == NULL) ? NUM_EVENTS : (event_T)abs(entry->key);
}
/*
@ -741,9 +715,9 @@ event_nr2name(event_T event)
if (cache_last_index < 0)
{
for (i = 0; i < (int)ARRAY_LENGTH(cache_tab); ++i)
for (i = 0; i < CACHE_SIZE; ++i)
cache_tab[i] = -1;
cache_last_index = ARRAY_LENGTH(cache_tab) - 1;
cache_last_index = CACHE_SIZE - 1;
}
// first look in the cache
@ -751,11 +725,11 @@ event_nr2name(event_T event)
// and go backwards wrapping around when we get to index 0.
for (i = cache_last_index; cache_tab[i] >= 0; )
{
if ((event_T)event_tab[cache_tab[i]].key == event)
if ((event_T)abs(event_tab[cache_tab[i]].key) == event)
return event_tab[cache_tab[i]].value.string;
if (i == 0)
i = ARRAY_LENGTH(cache_tab) - 1;
i = CACHE_SIZE - 1;
else
--i;
@ -765,13 +739,13 @@ event_nr2name(event_T event)
}
// look in the event table itself
for (i = 0; i < (int)ARRAY_LENGTH(event_tab); ++i)
for (i = 0; i < NUM_EVENTS; ++i)
{
if ((event_T)event_tab[i].key == event)
if ((event_T)abs(event_tab[i].key) == event)
{
// store the found entry in the next position in the cache,
// wrapping around when we get to the maximum index.
if (cache_last_index == ARRAY_LENGTH(cache_tab) - 1)
if (cache_last_index == CACHE_SIZE - 1)
cache_last_index = 0;
else
++cache_last_index;
@ -780,8 +754,8 @@ event_nr2name(event_T event)
}
}
return (i == (int)ARRAY_LENGTH(event_tab)) ? (char_u *)"Unknown" :
event_tab[i].value.string;
return (i == NUM_EVENTS) ? (char_u *)"Unknown" :
event_tab[i].value.string;
}
/*
@ -822,18 +796,17 @@ find_end_event(
}
/*
* Return TRUE if "event" is included in 'eventignore'.
* Return TRUE if "event" is included in 'eventignore(win)'.
*/
static int
event_ignored(event_T event)
int
event_ignored(event_T event, char_u *ei)
{
char_u *p = p_ei;
while (*p != NUL)
while (*ei != NUL)
{
if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ',')
&& (ei == p_ei || (event_tab[event].key <= 0)))
return TRUE;
if (event_name2nr(p, &p) == event)
if (event_name2nr(ei, &ei) == event)
return TRUE;
}
@ -841,23 +814,28 @@ event_ignored(event_T event)
}
/*
* Return OK when the contents of p_ei is valid, FAIL otherwise.
* Return OK when the contents of 'eventignore' or 'eventignorewin' is valid,
* FAIL otherwise.
*/
int
check_ei(void)
check_ei(char_u *ei)
{
char_u *p = p_ei;
int win = ei != p_ei;
while (*p)
while (*ei)
{
if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ','))
{
p += 3;
if (*p == ',')
++p;
ei += 3;
if (*ei == ',')
++ei;
}
else
{
event_T event = event_name2nr(ei, &ei);
if (event == NUM_EVENTS || (win && event_tab[event].key > 0))
return FAIL;
}
else if (event_name2nr(p, &p) == NUM_EVENTS)
return FAIL;
}
return OK;
@ -2152,7 +2130,20 @@ apply_autocmds_group(
/*
* Ignore events in 'eventignore'.
*/
if (event_ignored(event))
if (event_ignored(event, p_ei))
goto BYPASS_AU;
wininfo_T *wip;
int win_ignore = FALSE;
// If event is allowed in 'eventignorewin', check if curwin or all windows
// into "buf" are ignoring the event.
if (buf == curbuf && event_tab[event].key <= 0)
win_ignore = event_ignored(event, curwin->w_p_eiw);
else if (buf != NULL && event_tab[event].key <= 0)
FOR_ALL_BUF_WININFO(buf, wip)
if (wip->wi_win != NULL && wip->wi_win->w_buffer == buf)
win_ignore = event_ignored(event, wip->wi_win->w_p_eiw);
if (win_ignore)
goto BYPASS_AU;
/*
@ -2878,7 +2869,7 @@ get_event_name(expand_T *xp UNUSED, int idx)
}
i = idx - augroups.ga_len;
if (i < 0 || i >= (int)ARRAY_LENGTH(event_tab))
if (i < 0 || i >= NUM_EVENTS)
return NULL;
return event_tab[i].value.string;
@ -2889,12 +2880,24 @@ get_event_name(expand_T *xp UNUSED, int idx)
* include groups.
*/
char_u *
get_event_name_no_group(expand_T *xp UNUSED, int idx)
get_event_name_no_group(expand_T *xp UNUSED, int idx, int win)
{
if (idx < 0 || idx >= (int)ARRAY_LENGTH(event_tab))
if (idx < 0 || idx >= NUM_EVENTS)
return NULL;
return event_tab[idx].value.string;
if (!win)
return event_tab[idx].value.string;
// Need to check subset of allowed values for 'eventignorewin'.
int j = 0;
for (int i = 0; i < NUM_EVENTS; ++i)
{
j += event_tab[i].key <= 0;
if (j == idx + 1)
return event_tab[i].value.string;
}
return NULL;
}
@ -3369,15 +3372,14 @@ f_autocmd_get(typval_T *argvars, typval_T *rettv)
target.value.string = name;
target.value.length = STRLEN(target.value.string);
entry = (keyvalue_T *)bsearch(&target, &event_tab,
ARRAY_LENGTH(event_tab), sizeof(event_tab[0]),
cmp_keyvalue_value_ni);
NUM_EVENTS, sizeof(event_tab[0]), cmp_keyvalue_value_ni);
if (entry == NULL)
{
semsg(_(e_no_such_event_str), name);
vim_free(name);
return;
}
event_arg = (event_T)entry->key;
event_arg = (event_T)abs(entry->key);
}
vim_free(name);
}

View File

@ -6628,6 +6628,7 @@ get_varp(struct vimoption *p)
#ifdef FEAT_DIFF
case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
#endif
case PV_EIW: return (char_u *)&(curwin->w_p_eiw);
#ifdef FEAT_FOLDING
case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
case PV_FEN: return (char_u *)&(curwin->w_p_fen);
@ -6941,6 +6942,7 @@ copy_winopt(winopt_T *from, winopt_T *to)
to->wo_diff = from->wo_diff;
to->wo_diff_saved = from->wo_diff_saved;
#endif
to->wo_eiw = copy_option_val(from->wo_eiw);
#ifdef FEAT_CONCEAL
to->wo_cocu = copy_option_val(from->wo_cocu);
to->wo_cole = from->wo_cole;
@ -7006,6 +7008,7 @@ check_winopt(winopt_T *wop UNUSED)
# endif
check_string_option(&wop->wo_fmr);
#endif
check_string_option(&wop->wo_eiw);
#ifdef FEAT_SIGNS
check_string_option(&wop->wo_scl);
#endif
@ -7054,6 +7057,7 @@ clear_winopt(winopt_T *wop UNUSED)
# endif
clear_string_option(&wop->wo_fmr);
#endif
clear_string_option(&wop->wo_eiw);
#ifdef FEAT_SIGNS
clear_string_option(&wop->wo_scl);
#endif

View File

@ -1288,6 +1288,7 @@ enum
#ifdef FEAT_DIFF
, WV_DIFF
#endif
, WV_EIW
#ifdef FEAT_FOLDING
, WV_FDC
, WV_FEN

View File

@ -164,6 +164,7 @@
#ifdef FEAT_DIFF
# define PV_DIFF OPT_WIN(WV_DIFF)
#endif
# define PV_EIW OPT_WIN(WV_EIW)
#ifdef FEAT_FOLDING
# define PV_FDC OPT_WIN(WV_FDC)
# define PV_FEN OPT_WIN(WV_FEN)
@ -917,6 +918,9 @@ static struct vimoption options[] =
{"eventignore", "ei", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
(char_u *)&p_ei, PV_NONE, did_set_eventignore, expand_set_eventignore,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
{"eventignorewin", "eiw", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
(char_u *)VAR_WIN, PV_EIW, did_set_eventignore, expand_set_eventignore,
{(char_u *)"", (char_u *)0L} SCTX_INIT},
{"expandtab", "et", P_BOOL|P_VI_DEF|P_VIM,
(char_u *)&p_et, PV_ET, NULL, NULL,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},

View File

@ -2150,29 +2150,34 @@ expand_set_encoding(optexpand_T *args, int *numMatches, char_u ***matches)
}
/*
* The 'eventignore' option is changed.
* The 'eventignore(win)' option is changed.
*/
char *
did_set_eventignore(optset_T *args UNUSED)
did_set_eventignore(optset_T *args)
{
if (check_ei() == FAIL)
char_u **varp = (char_u **)args->os_varp;
if (check_ei(*varp) == FAIL)
return e_invalid_argument;
return NULL;
}
static int expand_eiw = FALSE;
static char_u *
get_eventignore_name(expand_T *xp, int idx)
{
// 'eventignore' allows special keyword "all" in addition to
// 'eventignore(win)' allows special keyword "all" in addition to
// all event names.
if (idx == 0)
return (char_u *)"all";
return get_event_name_no_group(xp, idx - 1);
return get_event_name_no_group(xp, idx - 1, expand_eiw);
}
int
expand_set_eventignore(optexpand_T *args, int *numMatches, char_u ***matches)
{
expand_eiw = args->oe_varp != (char_u *)&p_ei;
return expand_set_opt_generic(
args,
get_eventignore_name,

View File

@ -5,7 +5,8 @@ void do_augroup(char_u *arg, int del_group);
void autocmd_init(void);
void free_all_autocmds(void);
int is_aucmd_win(win_T *win);
int check_ei(void);
int check_ei(char_u *ei);
int event_ignored(event_T event, char_u *ei);
char_u *au_event_disable(char *what);
void au_event_restore(char_u *old_ei);
void do_autocmd(exarg_T *eap, char_u *arg_in, int forceit);
@ -40,7 +41,7 @@ int has_autocmd(event_T event, char_u *sfname, buf_T *buf);
char_u *get_augroup_name(expand_T *xp, int idx);
char_u *set_context_in_autocmd(expand_T *xp, char_u *arg, int doautocmd);
char_u *get_event_name(expand_T *xp, int idx);
char_u *get_event_name_no_group(expand_T *xp, int idx);
char_u *get_event_name_no_group(expand_T *xp, int idx, int eiw);
int autocmd_supported(char_u *name);
int au_exists(char_u *arg);
void f_autocmd_add(typval_T *argvars, typval_T *rettv);

View File

@ -210,6 +210,8 @@ typedef struct
int wo_diff;
# define w_p_diff w_onebuf_opt.wo_diff // 'diff'
#endif
char_u *wo_eiw;
# define w_p_eiw w_onebuf_opt.wo_eiw // 'eventignorewin'
#ifdef FEAT_FOLDING
long wo_fdc;
# define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn'

View File

@ -189,6 +189,8 @@ let test_values = {
\ 'encoding': [['latin1'], ['xxx', '']],
\ 'eventignore': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
\ ['xxx']],
\ 'eventignorewin': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
\ ['xxx', 'WinNew']],
\ 'fileencoding': [['', 'latin1', 'xxx'], []],
\ 'fileformat': [['', 'dos', 'unix', 'mac'], ['xxx']],
\ 'fileformats': [['', 'dos', 'dos,unix'], ['xxx']],

View File

@ -4103,10 +4103,10 @@ func Test_autocmd_get()
augroup END
let expected = [
\ {'cmd': 'echo "suspend"', 'group': 'TestAutoCmdFns', 'pattern': '*',
\ 'nested': v:true, 'once': v:false, 'event': 'VimSuspend'},
\ {'cmd': 'echo "resume"', 'group': 'TestAutoCmdFns', 'pattern': '*',
\ 'nested': v:false, 'once': v:true, 'event': 'VimResume'}]
\ 'nested': v:false, 'once': v:true, 'event': 'VimResume'},
\ {'cmd': 'echo "suspend"', 'group': 'TestAutoCmdFns', 'pattern': '*',
\ 'nested': v:true, 'once': v:false, 'event': 'VimSuspend'}]
call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'}))
" Test for buffer-local autocmd
@ -4926,4 +4926,64 @@ func Test_OptionSet_cmdheight()
set cmdheight& mouse& laststatus&
endfunc
func Test_eventignorewin()
defer CleanUpTestAuGroup()
augroup testing
au WinEnter * :call add(g:evs, ["WinEnter", expand("<afile>")])
au WinLeave * :call add(g:evs, ["WinLeave", expand("<afile>")])
au BufWinEnter * :call add(g:evs, ["BufWinEnter", expand("<afile>")])
augroup END
let g:evs = []
set eventignorewin=WinLeave,WinEnter
split foo
call assert_equal([['BufWinEnter', 'foo']], g:evs)
set eventignorewin=all
edit bar
call assert_equal([['BufWinEnter', 'foo']], g:evs)
set eventignorewin=
wincmd w
call assert_equal([['BufWinEnter', 'foo'], ['WinLeave', 'bar']], g:evs)
only!
%bwipe!
set eventignorewin&
unlet g:evs
endfunc
func Test_WinScrolled_Resized_eiw()
CheckRunVimInTerminal
let lines =<< trim END
call setline(1, ['foo']->repeat(32))
set eventignorewin=WinScrolled,WinResized
split
let [g:afile,g:resized,g:scrolled] = ['none',0,0]
au WinScrolled * let [g:afile,g:scrolled] = [expand('<afile>'),g:scrolled+1]
au WinResized * let [g:afile,g:resized] = [expand('<afile>'),g:resized+1]
END
call writefile(lines, 'Xtest_winscrolled_mouse', 'D')
let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10})
" Both windows are ignoring resize events
call term_sendkeys(buf, "\<C-W>-")
call TermWait(buf)
call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
" And scroll events
call term_sendkeys(buf, "Ggg")
call TermWait(buf)
call term_sendkeys(buf, ":echo g:afile g:resized g:scrolled\<CR>")
call WaitForAssert({-> assert_equal('none 0 0', term_getline(buf, 10))}, 1000)
" Un-ignore events in second window, make first window current and resize
call term_sendkeys(buf, ":set eventignorewin=\<CR>\<C-W>w\<C-W>+")
call TermWait(buf)
call term_sendkeys(buf, ":echo win_getid() g:afile g:resized g:scrolled\<CR>")
call WaitForAssert({-> assert_equal('1000 1001 1 1', term_getline(buf, 10))}, 1000)
call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -577,6 +577,7 @@ func Test_set_completion_string_values()
" 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(['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])
call assert_equal('SpecialKey', getcompletion('set wincolor=', 'cmdline')[0])
@ -2499,6 +2500,7 @@ func Test_string_option_revert_on_failure()
\ ['eadirection', 'hor', 'a123'],
\ ['encoding', 'utf-8', 'a123'],
\ ['eventignore', 'TextYankPost', 'a123'],
\ ['eventignorewin', 'WinScrolled', 'a123'],
\ ['fileencoding', 'utf-8', 'a123,'],
\ ['fileformat', 'mac', 'a123'],
\ ['fileformats', 'mac', 'a123'],

View File

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

View File

@ -1333,11 +1333,12 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define SID_WINLAYOUT (-7) // changing window size
/*
* Events for autocommands.
* Events for autocommands. Must be kept in sync with "event_tab".
*/
enum auto_event
{
EVENT_BUFADD = 0, // after adding a buffer to the buffer list
EVENT_BUFCREATE, // UNUSED: BufCreate == BufAdd
EVENT_BUFDELETE, // deleting a buffer from the buffer list
EVENT_BUFENTER, // after entering a buffer
EVENT_BUFFILEPOST, // after renaming a buffer
@ -1346,6 +1347,7 @@ enum auto_event
EVENT_BUFLEAVE, // before leaving a buffer
EVENT_BUFNEW, // after creating any buffer
EVENT_BUFNEWFILE, // when creating a buffer for a new file
EVENT_BUFREAD, // UNUSED: BufRead == BufReadPost
EVENT_BUFREADCMD, // read buffer using command
EVENT_BUFREADPOST, // after reading a buffer
EVENT_BUFREADPRE, // before reading a buffer
@ -1353,6 +1355,7 @@ enum auto_event
EVENT_BUFWINENTER, // after showing a buffer in a window
EVENT_BUFWINLEAVE, // just after buffer removed from window
EVENT_BUFWIPEOUT, // just before really deleting a buffer
EVENT_BUFWRITE, // UNUSED: BufWrite == BufWritePost
EVENT_BUFWRITECMD, // write buffer using command
EVENT_BUFWRITEPOST, // after writing a buffer
EVENT_BUFWRITEPRE, // before writing a buffer
@ -1383,6 +1386,7 @@ enum auto_event
EVENT_FILECHANGEDRO, // before first change to read-only file
EVENT_FILECHANGEDSHELL, // after shell command that changed file
EVENT_FILECHANGEDSHELLPOST, // after (not) reloading changed file
EVENT_FILEENCODING, // UNUSED: FileEncoding == EncodingChanged
EVENT_FILEREADCMD, // read from a file using command
EVENT_FILEREADPOST, // after reading a file
EVENT_FILEREADPRE, // before reading a file
@ -1402,8 +1406,8 @@ enum auto_event
EVENT_INSERTCHANGE, // when changing Insert/Replace mode
EVENT_INSERTCHARPRE, // before inserting a char
EVENT_INSERTENTER, // when entering Insert mode
EVENT_INSERTLEAVEPRE, // just before leaving Insert mode
EVENT_INSERTLEAVE, // just after leaving Insert mode
EVENT_INSERTLEAVEPRE, // just before leaving Insert mode
EVENT_KEYINPUTPRE, // before key input
EVENT_MENUPOPUP, // just before popup menu is displayed
EVENT_MODECHANGED, // after changing the mode
@ -1420,8 +1424,8 @@ enum auto_event
EVENT_SHELLFILTERPOST, // after ":1,2!cmd", ":w !cmd", ":r !cmd".
EVENT_SIGUSR1, // after the SIGUSR1 signal
EVENT_SOURCECMD, // sourcing a Vim script using command
EVENT_SOURCEPRE, // before sourcing a Vim script
EVENT_SOURCEPOST, // after sourcing a Vim script
EVENT_SOURCEPRE, // before sourcing a Vim script
EVENT_SPELLFILEMISSING, // spell file missing
EVENT_STDINREADPOST, // after reading from stdin
EVENT_STDINREADPRE, // before reading from stdin
@ -1447,17 +1451,17 @@ enum auto_event
EVENT_VIMLEAVE, // before exiting Vim
EVENT_VIMLEAVEPRE, // before exiting Vim and writing .viminfo
EVENT_VIMRESIZED, // after Vim window was resized
EVENT_VIMRESUME, // after Vim is resumed
EVENT_VIMSUSPEND, // before Vim is suspended
EVENT_WINCLOSED, // after closing a window
EVENT_WINENTER, // after entering a window
EVENT_WINLEAVE, // before leaving a window
EVENT_WINNEWPRE, // before creating a new window
EVENT_WINNEW, // after creating a new window
EVENT_WINCLOSED, // after closing a window
EVENT_VIMSUSPEND, // before Vim is suspended
EVENT_VIMRESUME, // after Vim is resumed
EVENT_WINNEWPRE, // before creating a new window
EVENT_WINRESIZED, // after a window was resized
EVENT_WINSCROLLED, // after a window was scrolled or resized
NUM_EVENTS // MUST be the last one
NUM_EVENTS, // MUST be the last one
};
typedef enum auto_event event_T;

View File

@ -3076,14 +3076,10 @@ make_win_info_dict(
/*
* This function is used for three purposes:
* 1. Goes over all windows in the current tab page and returns:
* 0 no scrolling and no size changes found
* CWSR_SCROLLED at least one window scrolled
* CWSR_RESIZED at least one window changed size
* CWSR_SCROLLED + CWSR_RESIZED both
* "size_count" is set to the nr of windows with size changes.
* "first_scroll_win" is set to the first window with any relevant changes.
* "first_size_win" is set to the first window with size changes.
* 1. Goes over all windows in the current tab page and sets:
* "size_count" to the nr of windows with size changes.
* "first_scroll_win" to the first window with any relevant changes.
* "first_size_win" to the first window with size changes.
*
* 2. When the first three arguments are NULL and "winlist" is not NULL,
* "winlist" is set to the list of window IDs with size changes.
@ -3091,7 +3087,7 @@ make_win_info_dict(
* 3. When the first three arguments are NULL and "v_event" is not NULL,
* information about changed windows is added to "v_event".
*/
static int
static void
check_window_scroll_resize(
int *size_count,
win_T **first_scroll_win,
@ -3099,7 +3095,6 @@ check_window_scroll_resize(
list_T *winlist UNUSED,
dict_T *v_event UNUSED)
{
int result = 0;
#ifdef FEAT_EVAL
int listidx = 0;
int tot_width = 0;
@ -3115,11 +3110,12 @@ check_window_scroll_resize(
win_T *wp;
FOR_ALL_WINDOWS(wp)
{
int size_changed = wp->w_last_width != wp->w_width
|| wp->w_last_height != wp->w_height;
int ignore_scroll = event_ignored(EVENT_WINSCROLLED, wp->w_p_eiw);
int size_changed = !event_ignored(EVENT_WINRESIZED, wp->w_p_eiw)
&& (wp->w_last_width != wp->w_width
|| wp->w_last_height != wp->w_height);
if (size_changed)
{
result |= CWSR_RESIZED;
#ifdef FEAT_EVAL
if (winlist != NULL)
{
@ -3139,23 +3135,21 @@ check_window_scroll_resize(
*first_size_win = wp;
// For WinScrolled the first window with a size change is used
// even when it didn't scroll.
if (*first_scroll_win == NULL)
if (*first_scroll_win == NULL && !ignore_scroll)
*first_scroll_win = wp;
}
}
int scroll_changed = wp->w_last_topline != wp->w_topline
int scroll_changed = !ignore_scroll
&& (wp->w_last_topline != wp->w_topline
#ifdef FEAT_DIFF
|| wp->w_last_topfill != wp->w_topfill
#endif
|| wp->w_last_leftcol != wp->w_leftcol
|| wp->w_last_skipcol != wp->w_skipcol;
if (scroll_changed)
{
result |= CWSR_SCROLLED;
if (first_scroll_win != NULL && *first_scroll_win == NULL)
*first_scroll_win = wp;
}
|| wp->w_last_skipcol != wp->w_skipcol);
if (scroll_changed
&& first_scroll_win != NULL && *first_scroll_win == NULL)
*first_scroll_win = wp;
#ifdef FEAT_EVAL
if ((size_changed || scroll_changed) && v_event != NULL)
@ -3214,8 +3208,6 @@ check_window_scroll_resize(
}
}
#endif
return result;
}
/*
@ -3238,11 +3230,10 @@ may_trigger_win_scrolled_resized(void)
int size_count = 0;
win_T *first_scroll_win = NULL, *first_size_win = NULL;
int cwsr = check_window_scroll_resize(&size_count,
&first_scroll_win, &first_size_win,
NULL, NULL);
check_window_scroll_resize(&size_count, &first_scroll_win, &first_size_win,
NULL, NULL);
int trigger_resize = do_resize && size_count > 0;
int trigger_scroll = do_scroll && cwsr != 0;
int trigger_scroll = do_scroll && first_scroll_win != NULL;
if (!trigger_resize && !trigger_scroll)
return; // no relevant changes
#ifdef FEAT_EVAL