mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 11:58:17 +00:00
feat(options): add 'eventignorewin' (#32152)
vim-patch:partial: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.b7147f8236
vim-patch:9.1.1102: tests: Test_WinScrolled_Resized_eiw() uses wrong filename Problem: tests: Test_WinScrolled_Resized_eiw() uses wrong filename (Luuk van Baal, after v9.1.1084) Solution: Rename the filename to something more uniquebfc7719e48
This commit is contained in:
@@ -1676,6 +1676,9 @@ To disable autocommands for some time use the 'eventignore' option. Note that
|
|||||||
this may cause unexpected behavior, make sure you restore 'eventignore'
|
this may cause unexpected behavior, make sure you restore 'eventignore'
|
||||||
afterwards, using a |:try| block with |:finally|.
|
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*
|
*:noautocmd* *:noa*
|
||||||
To disable autocommands for just one command use the ":noautocmd" command
|
To disable autocommands for just one command use the ":noautocmd" command
|
||||||
modifier. This will set 'eventignore' to "all" for the duration of the
|
modifier. This will set 'eventignore' to "all" for the duration of the
|
||||||
|
@@ -319,6 +319,7 @@ OPTIONS
|
|||||||
• 'completeopt' flag "preinsert" highlights text to be inserted.
|
• 'completeopt' flag "preinsert" highlights text to be inserted.
|
||||||
• 'messagesopt' configures |:messages| and |hit-enter| prompt.
|
• 'messagesopt' configures |:messages| and |hit-enter| prompt.
|
||||||
• 'tabclose' controls which tab page to focus when closing a tab page.
|
• 'tabclose' controls which tab page to focus when closing a tab page.
|
||||||
|
• 'eventignorewin' to persistently ignore events in a window.
|
||||||
|
|
||||||
PERFORMANCE
|
PERFORMANCE
|
||||||
|
|
||||||
|
@@ -2334,6 +2334,13 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
set ei=WinEnter,WinLeave
|
set ei=WinEnter,WinLeave
|
||||||
<
|
<
|
||||||
|
|
||||||
|
*'eventignorewin'* *'eiw'*
|
||||||
|
'eventignorewin' 'eiw' string (default "")
|
||||||
|
local to window
|
||||||
|
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'* *'noexpandtab'* *'noet'*
|
||||||
'expandtab' 'et' boolean (default off)
|
'expandtab' 'et' boolean (default off)
|
||||||
local to buffer
|
local to buffer
|
||||||
|
@@ -696,6 +696,7 @@ Short explanation of each option: *option-list*
|
|||||||
'errorfile' 'ef' name of the errorfile for the QuickFix mode
|
'errorfile' 'ef' name of the errorfile for the QuickFix mode
|
||||||
'errorformat' 'efm' description of the lines in the error file
|
'errorformat' 'efm' description of the lines in the error file
|
||||||
'eventignore' 'ei' autocommand events that are ignored
|
'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
|
'expandtab' 'et' use spaces when <Tab> is inserted
|
||||||
'exrc' 'ex' read init files in the current directory
|
'exrc' 'ex' read init files in the current directory
|
||||||
'fileencoding' 'fenc' file encoding for multibyte text
|
'fileencoding' 'fenc' file encoding for multibyte text
|
||||||
|
10
runtime/lua/vim/_meta/options.lua
generated
10
runtime/lua/vim/_meta/options.lua
generated
@@ -1989,6 +1989,16 @@ vim.o.ei = vim.o.eventignore
|
|||||||
vim.go.eventignore = vim.o.eventignore
|
vim.go.eventignore = vim.o.eventignore
|
||||||
vim.go.ei = vim.go.eventignore
|
vim.go.ei = vim.go.eventignore
|
||||||
|
|
||||||
|
--- 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'.
|
||||||
|
---
|
||||||
|
--- @type string
|
||||||
|
vim.o.eventignorewin = ""
|
||||||
|
vim.o.eiw = vim.o.eventignorewin
|
||||||
|
vim.wo.eventignorewin = vim.o.eventignorewin
|
||||||
|
vim.wo.eiw = vim.wo.eventignorewin
|
||||||
|
|
||||||
--- In Insert mode: Use the appropriate number of spaces to insert a
|
--- In Insert mode: Use the appropriate number of spaces to insert a
|
||||||
--- <Tab>. Spaces are used in indents with the '>' and '<' commands and
|
--- <Tab>. Spaces are used in indents with the '>' and '<' commands and
|
||||||
--- when 'autoindent' is on. To insert a real tab when 'expandtab' is
|
--- when 'autoindent' is on. To insert a real tab when 'expandtab' is
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
" These commands create the option window.
|
" These commands create the option window.
|
||||||
"
|
"
|
||||||
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
" 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>
|
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||||
|
|
||||||
" If there already is an option window, jump to that one.
|
" If there already is an option window, jump to that one.
|
||||||
@@ -1187,6 +1187,8 @@ call <SID>AddOption("virtualedit", gettext("when to use virtual editing: \"block
|
|||||||
call <SID>OptionG("ve", &ve)
|
call <SID>OptionG("ve", &ve)
|
||||||
call <SID>AddOption("eventignore", gettext("list of autocommand events which are to be ignored"))
|
call <SID>AddOption("eventignore", gettext("list of autocommand events which are to be ignored"))
|
||||||
call <SID>OptionG("ei", &ei)
|
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>AddOption("loadplugins", gettext("load plugin scripts when starting up"))
|
||||||
call <SID>BinOptionG("lpl", &lpl)
|
call <SID>BinOptionG("lpl", &lpl)
|
||||||
call <SID>AddOption("exrc", gettext("enable reading .vimrc/.exrc/.gvimrc in the current directory"))
|
call <SID>AddOption("exrc", gettext("enable reading .vimrc/.exrc/.gvimrc in the current directory"))
|
||||||
|
@@ -1,156 +1,139 @@
|
|||||||
return {
|
return {
|
||||||
|
--- @type [string, string[], boolean][] List of [eventname, aliases, window-local event] tuples.
|
||||||
events = {
|
events = {
|
||||||
'BufAdd', -- after adding a buffer to the buffer list
|
{ 'BufAdd', { 'BufCreate' }, true }, -- after adding a buffer to the buffer list
|
||||||
'BufDelete', -- deleting a buffer from the buffer list
|
{ 'BufDelete', {}, true }, -- deleting a buffer from the buffer list
|
||||||
'BufEnter', -- after entering a buffer
|
{ 'BufEnter', {}, true }, -- after entering a buffer
|
||||||
'BufFilePost', -- after renaming a buffer
|
{ 'BufFilePost', {}, true }, -- after renaming a buffer
|
||||||
'BufFilePre', -- before renaming a buffer
|
{ 'BufFilePre', {}, true }, -- before renaming a buffer
|
||||||
'BufHidden', -- just after buffer becomes hidden
|
{ 'BufHidden', {}, true }, -- just after buffer becomes hidden
|
||||||
'BufLeave', -- before leaving a buffer
|
{ 'BufLeave', {}, true }, -- before leaving a buffer
|
||||||
'BufModifiedSet', -- after the 'modified' state of a buffer changes
|
{ 'BufModifiedSet', {}, true }, -- after the 'modified' state of a buffer changes
|
||||||
'BufNew', -- after creating any buffer
|
{ 'BufNew', {}, true }, -- after creating any buffer
|
||||||
'BufNewFile', -- when creating a buffer for a new file
|
{ 'BufNewFile', {}, true }, -- when creating a buffer for a new file
|
||||||
'BufReadCmd', -- read buffer using command
|
{ 'BufReadCmd', {}, true }, -- read buffer using command
|
||||||
'BufReadPost', -- after reading a buffer
|
{ 'BufReadPost', { 'BufRead' }, true }, -- after reading a buffer
|
||||||
'BufReadPre', -- before reading a buffer
|
{ 'BufReadPre', {}, true }, -- before reading a buffer
|
||||||
'BufUnload', -- just before unloading a buffer
|
{ 'BufUnload', {}, true }, -- just before unloading a buffer
|
||||||
'BufWinEnter', -- after showing a buffer in a window
|
{ 'BufWinEnter', {}, true }, -- after showing a buffer in a window
|
||||||
'BufWinLeave', -- just after buffer removed from window
|
{ 'BufWinLeave', {}, true }, -- just after buffer removed from window
|
||||||
'BufWipeout', -- just before really deleting a buffer
|
{ 'BufWipeout', {}, true }, -- just before really deleting a buffer
|
||||||
'BufWriteCmd', -- write buffer using command
|
{ 'BufWriteCmd', {}, true }, -- write buffer using command
|
||||||
'BufWritePost', -- after writing a buffer
|
{ 'BufWritePost', {}, true }, -- after writing a buffer
|
||||||
'BufWritePre', -- before writing a buffer
|
{ 'BufWritePre', { 'BufWrite' }, true }, -- before writing a buffer
|
||||||
'ChanInfo', -- info was received about channel
|
{ 'ChanInfo', {}, false }, -- info was received about channel
|
||||||
'ChanOpen', -- channel was opened
|
{ 'ChanOpen', {}, false }, -- channel was opened
|
||||||
'CmdUndefined', -- command undefined
|
{ 'CmdUndefined', {}, false }, -- command undefined
|
||||||
'CmdWinEnter', -- after entering the cmdline window
|
{ 'CmdWinEnter', {}, false }, -- after entering the cmdline window
|
||||||
'CmdWinLeave', -- before leaving the cmdline window
|
{ 'CmdWinLeave', {}, false }, -- before leaving the cmdline window
|
||||||
'CmdlineChanged', -- command line was modified
|
{ 'CmdlineChanged', {}, false }, -- command line was modified
|
||||||
'CmdlineEnter', -- after entering cmdline mode
|
{ 'CmdlineEnter', {}, false }, -- after entering cmdline mode
|
||||||
'CmdlineLeave', -- before leaving cmdline mode
|
{ 'CmdlineLeave', {}, false }, -- before leaving cmdline mode
|
||||||
'ColorScheme', -- after loading a colorscheme
|
{ 'ColorScheme', {}, false }, -- after loading a colorscheme
|
||||||
'ColorSchemePre', -- before loading a colorscheme
|
{ 'ColorSchemePre', {}, false }, -- before loading a colorscheme
|
||||||
'CompleteChanged', -- after popup menu changed
|
{ 'CompleteChanged', {}, false }, -- after popup menu changed
|
||||||
'CompleteDone', -- after finishing insert complete
|
{ 'CompleteDone', {}, false }, -- after finishing insert complete
|
||||||
'CompleteDonePre', -- idem, before clearing info
|
{ 'CompleteDonePre', {}, false }, -- idem, before clearing info
|
||||||
'CursorHold', -- cursor in same position for a while
|
{ 'CursorHold', {}, true }, -- cursor in same position for a while
|
||||||
'CursorHoldI', -- idem, in Insert mode
|
{ 'CursorHoldI', {}, true }, -- idem, in Insert mode
|
||||||
'CursorMoved', -- cursor was moved
|
{ 'CursorMoved', {}, true }, -- cursor was moved
|
||||||
'CursorMovedC', -- cursor was moved in Cmdline mode
|
{ 'CursorMovedC', {}, true }, -- cursor was moved in Cmdline mode
|
||||||
'CursorMovedI', -- cursor was moved in Insert mode
|
{ 'CursorMovedI', {}, true }, -- cursor was moved in Insert mode
|
||||||
'DiagnosticChanged', -- diagnostics in a buffer were modified
|
{ 'DiagnosticChanged', {}, false }, -- diagnostics in a buffer were modified
|
||||||
'DiffUpdated', -- diffs have been updated
|
{ 'DiffUpdated', {}, false }, -- diffs have been updated
|
||||||
'DirChanged', -- directory changed
|
{ 'DirChanged', {}, false }, -- directory changed
|
||||||
'DirChangedPre', -- directory is going to change
|
{ 'DirChangedPre', {}, false }, -- directory is going to change
|
||||||
'EncodingChanged', -- after changing the 'encoding' option
|
{ 'EncodingChanged', { 'FileEncoding' }, false }, -- after changing the 'encoding' option
|
||||||
'ExitPre', -- before exiting
|
{ 'ExitPre', {}, false }, -- before exiting
|
||||||
'FileAppendCmd', -- append to a file using command
|
{ 'FileAppendCmd', {}, true }, -- append to a file using command
|
||||||
'FileAppendPost', -- after appending to a file
|
{ 'FileAppendPost', {}, true }, -- after appending to a file
|
||||||
'FileAppendPre', -- before appending to a file
|
{ 'FileAppendPre', {}, true }, -- before appending to a file
|
||||||
'FileChangedRO', -- before first change to read-only file
|
{ 'FileChangedRO', {}, true }, -- before first change to read-only file
|
||||||
'FileChangedShell', -- after shell command that changed file
|
{ 'FileChangedShell', {}, true }, -- after shell command that changed file
|
||||||
'FileChangedShellPost', -- after (not) reloading changed file
|
{ 'FileChangedShellPost', {}, true }, -- after (not) reloading changed file
|
||||||
'FileReadCmd', -- read from a file using command
|
{ 'FileReadCmd', {}, true }, -- read from a file using command
|
||||||
'FileReadPost', -- after reading a file
|
{ 'FileReadPost', {}, true }, -- after reading a file
|
||||||
'FileReadPre', -- before reading a file
|
{ 'FileReadPre', {}, true }, -- before reading a file
|
||||||
'FileType', -- new file type detected (user defined)
|
{ 'FileType', {}, true }, -- new file type detected (user defined)
|
||||||
'FileWriteCmd', -- write to a file using command
|
{ 'FileWriteCmd', {}, true }, -- write to a file using command
|
||||||
'FileWritePost', -- after writing a file
|
{ 'FileWritePost', {}, true }, -- after writing a file
|
||||||
'FileWritePre', -- before writing a file
|
{ 'FileWritePre', {}, true }, -- before writing a file
|
||||||
'FilterReadPost', -- after reading from a filter
|
{ 'FilterReadPost', {}, true }, -- after reading from a filter
|
||||||
'FilterReadPre', -- before reading from a filter
|
{ 'FilterReadPre', {}, true }, -- before reading from a filter
|
||||||
'FilterWritePost', -- after writing to a filter
|
{ 'FilterWritePost', {}, true }, -- after writing to a filter
|
||||||
'FilterWritePre', -- before writing to a filter
|
{ 'FilterWritePre', {}, true }, -- before writing to a filter
|
||||||
'FocusGained', -- got the focus
|
{ 'FocusGained', {}, false }, -- got the focus
|
||||||
'FocusLost', -- lost the focus to another app
|
{ 'FocusLost', {}, false }, -- lost the focus to another app
|
||||||
'FuncUndefined', -- if calling a function which doesn't exist
|
{ 'FuncUndefined', {}, false }, -- if calling a function which doesn't exist
|
||||||
'GUIEnter', -- after starting the GUI
|
{ 'GUIEnter', {}, false }, -- after starting the GUI
|
||||||
'GUIFailed', -- after starting the GUI failed
|
{ 'GUIFailed', {}, false }, -- after starting the GUI failed
|
||||||
'InsertChange', -- when changing Insert/Replace mode
|
{ 'InsertChange', {}, true }, -- when changing Insert/Replace mode
|
||||||
'InsertCharPre', -- before inserting a char
|
{ 'InsertCharPre', {}, true }, -- before inserting a char
|
||||||
'InsertEnter', -- when entering Insert mode
|
{ 'InsertEnter', {}, true }, -- when entering Insert mode
|
||||||
'InsertLeave', -- just after leaving Insert mode
|
{ 'InsertLeave', {}, true }, -- just after leaving Insert mode
|
||||||
'InsertLeavePre', -- just before leaving Insert mode
|
{ 'InsertLeavePre', {}, true }, -- just before leaving Insert mode
|
||||||
'LspAttach', -- after an LSP client attaches to a buffer
|
{ 'LspAttach', {}, false }, -- after an LSP client attaches to a buffer
|
||||||
'LspDetach', -- after an LSP client detaches from a buffer
|
{ 'LspDetach', {}, false }, -- after an LSP client detaches from a buffer
|
||||||
'LspNotify', -- after an LSP notice has been sent to the server
|
{ 'LspNotify', {}, false }, -- after an LSP notice has been sent to the server
|
||||||
'LspProgress', -- after a LSP progress update
|
{ 'LspProgress', {}, false }, -- after a LSP progress update
|
||||||
'LspRequest', -- after an LSP request is started, canceled, or completed
|
{ 'LspRequest', {}, false }, -- after an LSP request is started, canceled, or completed
|
||||||
'LspTokenUpdate', -- after a visible LSP token is updated
|
{ 'LspTokenUpdate', {}, false }, -- after a visible LSP token is updated
|
||||||
'MenuPopup', -- just before popup menu is displayed
|
{ 'MenuPopup', {}, false }, -- just before popup menu is displayed
|
||||||
'ModeChanged', -- after changing the mode
|
{ 'ModeChanged', {}, false }, -- after changing the mode
|
||||||
'OptionSet', -- after setting any option
|
{ 'OptionSet', {}, false }, -- after setting any option
|
||||||
'QuickFixCmdPost', -- after :make, :grep etc.
|
{ 'QuickFixCmdPost', {}, false }, -- after :make, :grep etc.
|
||||||
'QuickFixCmdPre', -- before :make, :grep etc.
|
{ 'QuickFixCmdPre', {}, false }, -- before :make, :grep etc.
|
||||||
'QuitPre', -- before :quit
|
{ 'QuitPre', {}, false }, -- before :quit
|
||||||
'RecordingEnter', -- when starting to record a macro
|
{ 'RecordingEnter', {}, true }, -- when starting to record a macro
|
||||||
'RecordingLeave', -- just before a macro stops recording
|
{ 'RecordingLeave', {}, true }, -- just before a macro stops recording
|
||||||
'RemoteReply', -- upon string reception from a remote vim
|
{ 'RemoteReply', {}, false }, -- upon string reception from a remote vim
|
||||||
'SafeState', -- going to wait for a character
|
{ 'SafeState', {}, false }, -- going to wait for a character
|
||||||
'SearchWrapped', -- after the search wrapped around
|
{ 'SearchWrapped', {}, true }, -- after the search wrapped around
|
||||||
'SessionLoadPost', -- after loading a session file
|
{ 'SessionLoadPost', {}, false }, -- after loading a session file
|
||||||
'SessionWritePost', -- after writing a session file
|
{ 'SessionWritePost', {}, false }, -- after writing a session file
|
||||||
'ShellCmdPost', -- after ":!cmd"
|
{ 'ShellCmdPost', {}, false }, -- after ":!cmd"
|
||||||
'ShellFilterPost', -- after ":1,2!cmd", ":w !cmd", ":r !cmd".
|
{ 'ShellFilterPost', {}, true }, -- after ":1,2!cmd", ":w !cmd", ":r !cmd".
|
||||||
'Signal', -- after nvim process received a signal
|
{ 'Signal', {}, false }, -- after nvim process received a signal
|
||||||
'SourceCmd', -- sourcing a Vim script using command
|
{ 'SourceCmd', {}, false }, -- sourcing a Vim script using command
|
||||||
'SourcePost', -- after sourcing a Vim script
|
{ 'SourcePost', {}, false }, -- after sourcing a Vim script
|
||||||
'SourcePre', -- before sourcing a Vim script
|
{ 'SourcePre', {}, false }, -- before sourcing a Vim script
|
||||||
'SpellFileMissing', -- spell file missing
|
{ 'SpellFileMissing', {}, false }, -- spell file missing
|
||||||
'StdinReadPost', -- after reading from stdin
|
{ 'StdinReadPost', {}, false }, -- after reading from stdin
|
||||||
'StdinReadPre', -- before reading from stdin
|
{ 'StdinReadPre', {}, false }, -- before reading from stdin
|
||||||
'SwapExists', -- found existing swap file
|
{ 'SwapExists', {}, false }, -- found existing swap file
|
||||||
'Syntax', -- syntax selected
|
{ 'Syntax', {}, false }, -- syntax selected
|
||||||
'TabClosed', -- a tab has closed
|
{ 'TabClosed', {}, false }, -- a tab has closed
|
||||||
'TabEnter', -- after entering a tab page
|
{ 'TabEnter', {}, false }, -- after entering a tab page
|
||||||
'TabLeave', -- before leaving a tab page
|
{ 'TabLeave', {}, false }, -- before leaving a tab page
|
||||||
'TabNew', -- when creating a new tab
|
{ 'TabNew', {}, false }, -- when creating a new tab
|
||||||
'TabNewEntered', -- after entering a new tab
|
{ 'TabNewEntered', {}, false }, -- after entering a new tab
|
||||||
'TermChanged', -- after changing 'term'
|
{ 'TermChanged', {}, false }, -- after changing 'term'
|
||||||
'TermClose', -- after the process exits
|
{ 'TermClose', {}, false }, -- after the process exits
|
||||||
'TermEnter', -- after entering Terminal mode
|
{ 'TermEnter', {}, false }, -- after entering Terminal mode
|
||||||
'TermLeave', -- after leaving Terminal mode
|
{ 'TermLeave', {}, false }, -- after leaving Terminal mode
|
||||||
'TermOpen', -- after opening a terminal buffer
|
{ 'TermOpen', {}, false }, -- after opening a terminal buffer
|
||||||
'TermRequest', -- after an unhandled OSC sequence is emitted
|
{ 'TermRequest', {}, false }, -- after an unhandled OSC sequence is emitted
|
||||||
'TermResponse', -- after setting "v:termresponse"
|
{ 'TermResponse', {}, false }, -- after setting "v:termresponse"
|
||||||
'TextChanged', -- text was modified
|
{ 'TextChanged', {}, true }, -- text was modified
|
||||||
'TextChangedI', -- text was modified in Insert mode(no popup)
|
{ 'TextChangedI', {}, true }, -- text was modified in Insert mode(no popup)
|
||||||
'TextChangedP', -- text was modified in Insert mode(popup)
|
{ 'TextChangedP', {}, true }, -- text was modified in Insert mode(popup)
|
||||||
'TextChangedT', -- text was modified in Terminal mode
|
{ 'TextChangedT', {}, true }, -- text was modified in Terminal mode
|
||||||
'TextYankPost', -- after a yank or delete was done (y, d, c)
|
{ 'TextYankPost', {}, true }, -- after a yank or delete was done (y, d, c)
|
||||||
'UIEnter', -- after UI attaches
|
{ 'UIEnter', {}, false }, -- after UI attaches
|
||||||
'UILeave', -- after UI detaches
|
{ 'UILeave', {}, false }, -- after UI detaches
|
||||||
'User', -- user defined autocommand
|
{ 'User', {}, false }, -- user defined autocommand
|
||||||
'VimEnter', -- after starting Vim
|
{ 'VimEnter', {}, false }, -- after starting Vim
|
||||||
'VimLeave', -- before exiting Vim
|
{ 'VimLeave', {}, false }, -- before exiting Vim
|
||||||
'VimLeavePre', -- before exiting Vim and writing ShaDa file
|
{ 'VimLeavePre', {}, false }, -- before exiting Vim and writing ShaDa file
|
||||||
'VimResized', -- after Vim window was resized
|
{ 'VimResized', {}, false }, -- after Vim window was resized
|
||||||
'VimResume', -- after Nvim is resumed
|
{ 'VimResume', {}, false }, -- after Nvim is resumed
|
||||||
'VimSuspend', -- before Nvim is suspended
|
{ 'VimSuspend', {}, false }, -- before Nvim is suspended
|
||||||
'WinClosed', -- after closing a window
|
{ 'WinClosed', {}, true }, -- after closing a window
|
||||||
'WinEnter', -- after entering a window
|
{ 'WinEnter', {}, true }, -- after entering a window
|
||||||
'WinLeave', -- before leaving a window
|
{ 'WinLeave', {}, true }, -- before leaving a window
|
||||||
'WinNew', -- when entering a new window
|
{ 'WinNew', {}, false }, -- when entering a new window
|
||||||
'WinResized', -- after a window was resized
|
{ 'WinResized', {}, true }, -- after a window was resized
|
||||||
'WinScrolled', -- after a window was scrolled or resized
|
{ 'WinScrolled', {}, true }, -- after a window was scrolled or resized
|
||||||
},
|
|
||||||
aliases = {
|
|
||||||
{
|
|
||||||
'BufCreate',
|
|
||||||
'BufAdd',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'BufRead',
|
|
||||||
'BufReadPost',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'BufWrite',
|
|
||||||
'BufWritePre',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'FileEncoding',
|
|
||||||
'EncodingChanged',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
-- List of nvim-specific events or aliases for the purpose of generating
|
-- List of nvim-specific events or aliases for the purpose of generating
|
||||||
-- syntax file
|
-- syntax file
|
||||||
|
@@ -634,7 +634,7 @@ event_T event_name2nr(const char *start, char **end)
|
|||||||
if (event_names[i].name == NULL) {
|
if (event_names[i].name == NULL) {
|
||||||
return NUM_EVENTS;
|
return NUM_EVENTS;
|
||||||
}
|
}
|
||||||
return event_names[i].event;
|
return (event_T)abs(event_names[i].event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the event number for event name "str".
|
/// Return the event number for event name "str".
|
||||||
@@ -643,7 +643,7 @@ event_T event_name2nr_str(String str)
|
|||||||
{
|
{
|
||||||
for (int i = 0; event_names[i].name != NULL; i++) {
|
for (int i = 0; event_names[i].name != NULL; i++) {
|
||||||
if (str.size == event_names[i].len && STRNICMP(str.data, event_names[i].name, str.size) == 0) {
|
if (str.size == event_names[i].len && STRNICMP(str.data, event_names[i].name, str.size) == 0) {
|
||||||
return event_names[i].event;
|
return (event_T)abs(event_names[i].event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NUM_EVENTS;
|
return NUM_EVENTS;
|
||||||
@@ -658,25 +658,23 @@ const char *event_nr2name(event_T event)
|
|||||||
FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST
|
FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST
|
||||||
{
|
{
|
||||||
for (int i = 0; event_names[i].name != NULL; i++) {
|
for (int i = 0; event_names[i].name != NULL; i++) {
|
||||||
if (event_names[i].event == event) {
|
if ((event_T)abs(event_names[i].event) == event) {
|
||||||
return event_names[i].name;
|
return event_names[i].name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if "event" is included in 'eventignore'.
|
/// Return true if "event" is included in 'eventignore(win)'.
|
||||||
///
|
///
|
||||||
/// @param event event to check
|
/// @param event event to check
|
||||||
static bool event_ignored(event_T event)
|
bool event_ignored(event_T event, char *ei)
|
||||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
char *p = p_ei;
|
while (*ei != NUL) {
|
||||||
|
if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ',')) {
|
||||||
while (*p != NUL) {
|
|
||||||
if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) {
|
|
||||||
return true;
|
return true;
|
||||||
} else if (event_name2nr(p, &p) == event) {
|
} else if (event_name2nr(ei, &ei) == event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -684,21 +682,25 @@ static bool event_ignored(event_T event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return OK when the contents of p_ei is valid, FAIL otherwise.
|
/// Return OK when the contents of 'eventignore' or 'eventignorewin' is valid,
|
||||||
int check_ei(void)
|
/// FAIL otherwise.
|
||||||
|
int check_ei(char *ei)
|
||||||
{
|
{
|
||||||
char *p = p_ei;
|
bool 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;
|
ei += 3;
|
||||||
if (*p == ',') {
|
if (*ei == ',') {
|
||||||
p++;
|
ei++;
|
||||||
}
|
}
|
||||||
} else if (event_name2nr(p, &p) == NUM_EVENTS) {
|
} else {
|
||||||
|
event_T event = event_name2nr(ei, &ei);
|
||||||
|
if (event == NUM_EVENTS || (win && event_names[event].event > 0)) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -1631,7 +1633,24 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ignore events in 'eventignore'.
|
// Ignore events in 'eventignore'.
|
||||||
if (event_ignored(event)) {
|
if (event_ignored(event, p_ei)) {
|
||||||
|
goto BYPASS_AU;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool 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_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (win_ignore) {
|
||||||
goto BYPASS_AU;
|
goto BYPASS_AU;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2279,11 +2298,23 @@ char *expand_get_event_name(expand_T *xp, int idx)
|
|||||||
|
|
||||||
/// Function given to ExpandGeneric() to obtain the list of event names. Don't
|
/// Function given to ExpandGeneric() to obtain the list of event names. Don't
|
||||||
/// include groups.
|
/// include groups.
|
||||||
char *get_event_name_no_group(expand_T *xp FUNC_ATTR_UNUSED, int idx)
|
char *get_event_name_no_group(expand_T *xp FUNC_ATTR_UNUSED, int idx, bool win)
|
||||||
{
|
{
|
||||||
|
if (!win) {
|
||||||
return event_names[idx].name;
|
return event_names[idx].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Need to check subset of allowed values for 'eventignorewin'.
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < NUM_EVENTS; i++) {
|
||||||
|
j += event_names[i].event <= 0;
|
||||||
|
if (j == idx + 1) {
|
||||||
|
return event_names[i].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/// Check whether given autocommand is supported
|
/// Check whether given autocommand is supported
|
||||||
///
|
///
|
||||||
/// @param[in] event Event to check.
|
/// @param[in] event Event to check.
|
||||||
|
@@ -96,6 +96,8 @@ typedef struct {
|
|||||||
int wo_diff;
|
int wo_diff;
|
||||||
#define w_p_diff w_onebuf_opt.wo_diff // 'diff'
|
#define w_p_diff w_onebuf_opt.wo_diff // 'diff'
|
||||||
char *wo_fdc;
|
char *wo_fdc;
|
||||||
|
#define w_p_eiw w_onebuf_opt.wo_eiw // 'eventignorewin'
|
||||||
|
char *wo_eiw;
|
||||||
#define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn'
|
#define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn'
|
||||||
char *wo_fdc_save;
|
char *wo_fdc_save;
|
||||||
#define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode
|
#define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode
|
||||||
|
@@ -3,7 +3,6 @@ local names_file = arg[2]
|
|||||||
|
|
||||||
local auevents = require('auevents')
|
local auevents = require('auevents')
|
||||||
local events = auevents.events
|
local events = auevents.events
|
||||||
local aliases = auevents.aliases
|
|
||||||
|
|
||||||
local enum_tgt = io.open(fileio_enum_file, 'w')
|
local enum_tgt = io.open(fileio_enum_file, 'w')
|
||||||
local names_tgt = io.open(names_file, 'w')
|
local names_tgt = io.open(names_file, 'w')
|
||||||
@@ -16,46 +15,28 @@ names_tgt:write([[
|
|||||||
static const struct event_name {
|
static const struct event_name {
|
||||||
size_t len;
|
size_t len;
|
||||||
char *name;
|
char *name;
|
||||||
event_T event;
|
int event;
|
||||||
} event_names[] = {]])
|
} event_names[] = {]])
|
||||||
|
|
||||||
|
local aliases = 0
|
||||||
for i, event in ipairs(events) do
|
for i, event in ipairs(events) do
|
||||||
enum_tgt:write(('\n EVENT_%s = %u,'):format(event:upper(), i - 1))
|
enum_tgt:write(('\n EVENT_%s = %u,'):format(event[1]:upper(), i + aliases - 1))
|
||||||
names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#event, event, event:upper()))
|
-- Events with positive keys aren't allowed in 'eventignorewin'.
|
||||||
|
local event_int = ('%sEVENT_%s'):format(event[3] and '-' or '', event[1]:upper())
|
||||||
|
names_tgt:write(('\n {%u, "%s", %s},'):format(#event[1], event[1], event_int))
|
||||||
|
for _, alias in ipairs(event[2]) do
|
||||||
|
aliases = aliases + 1
|
||||||
|
names_tgt:write(('\n {%u, "%s", %s},'):format(#alias, alias, event_int))
|
||||||
|
enum_tgt:write(('\n EVENT_%s = %u,'):format(alias:upper(), i + aliases - 1))
|
||||||
|
end
|
||||||
if i == #events then -- Last item.
|
if i == #events then -- Last item.
|
||||||
enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i))
|
enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i + aliases))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, v in ipairs(aliases) do
|
names_tgt:write('\n {0, NULL, (event_T)0},\n};\n')
|
||||||
local alias = v[1]
|
names_tgt:write('\nstatic AutoCmdVec autocmds[NUM_EVENTS] = { 0 };\n')
|
||||||
local event = v[2]
|
names_tgt:close()
|
||||||
names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#alias, alias, event:upper()))
|
|
||||||
end
|
|
||||||
|
|
||||||
names_tgt:write('\n {0, NULL, (event_T)0},')
|
|
||||||
|
|
||||||
enum_tgt:write('\n} event_T;\n')
|
enum_tgt:write('\n} event_T;\n')
|
||||||
names_tgt:write('\n};\n')
|
|
||||||
|
|
||||||
do
|
|
||||||
names_tgt:write('\nstatic AutoCmdVec autocmds[NUM_EVENTS] = {\n ')
|
|
||||||
local line_len = 1
|
|
||||||
for _ = 1, (#events - 1) do
|
|
||||||
line_len = line_len + #' KV_INITIAL_VALUE,'
|
|
||||||
if line_len > 80 then
|
|
||||||
names_tgt:write('\n ')
|
|
||||||
line_len = 1 + #' KV_INITIAL_VALUE,'
|
|
||||||
end
|
|
||||||
names_tgt:write(' KV_INITIAL_VALUE,')
|
|
||||||
end
|
|
||||||
if line_len + #' KV_INITIAL_VALUE' > 80 then
|
|
||||||
names_tgt:write('\n KV_INITIAL_VALUE')
|
|
||||||
else
|
|
||||||
names_tgt:write(' KV_INITIAL_VALUE')
|
|
||||||
end
|
|
||||||
names_tgt:write('\n};\n')
|
|
||||||
end
|
|
||||||
|
|
||||||
enum_tgt:close()
|
enum_tgt:close()
|
||||||
names_tgt:close()
|
|
||||||
|
@@ -114,19 +114,19 @@ local vimau_start = 'syn keyword vimAutoEvent contained '
|
|||||||
w('\n\n' .. vimau_start)
|
w('\n\n' .. vimau_start)
|
||||||
|
|
||||||
for _, au in ipairs(auevents.events) do
|
for _, au in ipairs(auevents.events) do
|
||||||
if not auevents.nvim_specific[au] then
|
if not auevents.nvim_specific[au[1]] then
|
||||||
if lld.line_length > 850 then
|
if lld.line_length > 850 then
|
||||||
w('\n' .. vimau_start)
|
w('\n' .. vimau_start)
|
||||||
end
|
end
|
||||||
w(' ' .. au)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for _, au in pairs(auevents.aliases) do
|
|
||||||
if lld.line_length > 850 then
|
|
||||||
w('\n' .. vimau_start)
|
|
||||||
end
|
|
||||||
-- au[1] is aliased to au[2]
|
|
||||||
w(' ' .. au[1])
|
w(' ' .. au[1])
|
||||||
|
for _, alias in ipairs(au[2]) do
|
||||||
|
if lld.line_length > 850 then
|
||||||
|
w('\n' .. vimau_start)
|
||||||
|
end
|
||||||
|
-- au[1] is aliased to alias
|
||||||
|
w(' ' .. alias)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local nvimau_start = 'syn keyword nvimAutoEvent contained '
|
local nvimau_start = 'syn keyword nvimAutoEvent contained '
|
||||||
|
@@ -4580,6 +4580,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win)
|
|||||||
return &(win->w_p_cc);
|
return &(win->w_p_cc);
|
||||||
case kOptDiff:
|
case kOptDiff:
|
||||||
return &(win->w_p_diff);
|
return &(win->w_p_diff);
|
||||||
|
case kOptEventignorewin:
|
||||||
|
return &(win->w_p_eiw);
|
||||||
case kOptFoldcolumn:
|
case kOptFoldcolumn:
|
||||||
return &(win->w_p_fdc);
|
return &(win->w_p_fdc);
|
||||||
case kOptFoldenable:
|
case kOptFoldenable:
|
||||||
@@ -4875,6 +4877,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
|
|||||||
to->wo_cc = copy_option_val(from->wo_cc);
|
to->wo_cc = copy_option_val(from->wo_cc);
|
||||||
to->wo_diff = from->wo_diff;
|
to->wo_diff = from->wo_diff;
|
||||||
to->wo_diff_saved = from->wo_diff_saved;
|
to->wo_diff_saved = from->wo_diff_saved;
|
||||||
|
to->wo_eiw = copy_option_val(from->wo_eiw);
|
||||||
to->wo_cocu = copy_option_val(from->wo_cocu);
|
to->wo_cocu = copy_option_val(from->wo_cocu);
|
||||||
to->wo_cole = from->wo_cole;
|
to->wo_cole = from->wo_cole;
|
||||||
to->wo_fdc = copy_option_val(from->wo_fdc);
|
to->wo_fdc = copy_option_val(from->wo_fdc);
|
||||||
@@ -4919,6 +4922,7 @@ static void check_winopt(winopt_T *wop)
|
|||||||
check_string_option(&wop->wo_fde);
|
check_string_option(&wop->wo_fde);
|
||||||
check_string_option(&wop->wo_fdt);
|
check_string_option(&wop->wo_fdt);
|
||||||
check_string_option(&wop->wo_fmr);
|
check_string_option(&wop->wo_fmr);
|
||||||
|
check_string_option(&wop->wo_eiw);
|
||||||
check_string_option(&wop->wo_scl);
|
check_string_option(&wop->wo_scl);
|
||||||
check_string_option(&wop->wo_rlc);
|
check_string_option(&wop->wo_rlc);
|
||||||
check_string_option(&wop->wo_sbr);
|
check_string_option(&wop->wo_sbr);
|
||||||
@@ -4946,6 +4950,7 @@ void clear_winopt(winopt_T *wop)
|
|||||||
clear_string_option(&wop->wo_fde);
|
clear_string_option(&wop->wo_fde);
|
||||||
clear_string_option(&wop->wo_fdt);
|
clear_string_option(&wop->wo_fdt);
|
||||||
clear_string_option(&wop->wo_fmr);
|
clear_string_option(&wop->wo_fmr);
|
||||||
|
clear_string_option(&wop->wo_eiw);
|
||||||
clear_string_option(&wop->wo_scl);
|
clear_string_option(&wop->wo_scl);
|
||||||
clear_string_option(&wop->wo_rlc);
|
clear_string_option(&wop->wo_rlc);
|
||||||
clear_string_option(&wop->wo_sbr);
|
clear_string_option(&wop->wo_sbr);
|
||||||
|
@@ -2627,6 +2627,23 @@ local options = {
|
|||||||
type = 'string',
|
type = 'string',
|
||||||
varname = 'p_ei',
|
varname = 'p_ei',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
abbreviation = 'eiw',
|
||||||
|
cb = 'did_set_eventignore',
|
||||||
|
defaults = '',
|
||||||
|
deny_duplicates = true,
|
||||||
|
desc = [=[
|
||||||
|
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'.
|
||||||
|
]=],
|
||||||
|
expand_cb = 'expand_set_eventignore',
|
||||||
|
full_name = 'eventignorewin',
|
||||||
|
list = 'onecomma',
|
||||||
|
scope = { 'win' },
|
||||||
|
short_desc = N_('autocommand events that are ignored in a window'),
|
||||||
|
type = 'string',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
abbreviation = 'et',
|
abbreviation = 'et',
|
||||||
defaults = false,
|
defaults = false,
|
||||||
|
@@ -1082,27 +1082,32 @@ int expand_set_encoding(optexpand_T *args, int *numMatches, char ***matches)
|
|||||||
return expand_set_opt_generic(args, get_encoding_name, numMatches, matches);
|
return expand_set_opt_generic(args, get_encoding_name, numMatches, matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The 'eventignore' option is changed.
|
/// The 'eventignore(win)' option is changed.
|
||||||
const char *did_set_eventignore(optset_T *args FUNC_ATTR_UNUSED)
|
const char *did_set_eventignore(optset_T *args)
|
||||||
{
|
{
|
||||||
if (check_ei() == FAIL) {
|
char **varp = (char **)args->os_varp;
|
||||||
|
|
||||||
|
if (check_ei(*varp) == FAIL) {
|
||||||
return e_invarg;
|
return e_invarg;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool expand_eiw = false;
|
||||||
|
|
||||||
static char *get_eventignore_name(expand_T *xp, int idx)
|
static char *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.
|
// all event names.
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
return "all";
|
return "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 ***matches)
|
int expand_set_eventignore(optexpand_T *args, int *numMatches, char ***matches)
|
||||||
{
|
{
|
||||||
|
expand_eiw = args->oe_varp != (char *)&p_ei;
|
||||||
return expand_set_opt_generic(args, get_eventignore_name, numMatches, matches);
|
return expand_set_opt_generic(args, get_eventignore_name, numMatches, matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5530,31 +5530,20 @@ static dict_T *make_win_info_dict(int width, int height, int topline, int topfil
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return values of check_window_scroll_resize():
|
|
||||||
enum {
|
|
||||||
CWSR_SCROLLED = 1, ///< at least one window scrolled
|
|
||||||
CWSR_RESIZED = 2, ///< at least one window size changed
|
|
||||||
};
|
|
||||||
|
|
||||||
/// This function is used for three purposes:
|
/// This function is used for three purposes:
|
||||||
/// 1. Goes over all windows in the current tab page and returns:
|
/// 1. Goes over all windows in the current tab page and sets:
|
||||||
/// 0 no scrolling and no size changes found
|
/// "size_count" to the nr of windows with size changes.
|
||||||
/// CWSR_SCROLLED at least one window scrolled
|
/// "first_scroll_win" to the first window with any relevant changes.
|
||||||
/// CWSR_RESIZED at least one window changed size
|
/// "first_size_win" to the first window with size changes.
|
||||||
/// 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.
|
|
||||||
///
|
///
|
||||||
/// 2. When the first three arguments are NULL and "winlist" is not NULL,
|
/// 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.
|
/// "winlist" is set to the list of window IDs with size changes.
|
||||||
///
|
///
|
||||||
/// 3. When the first three arguments are NULL and "v_event" is not NULL,
|
/// 3. When the first three arguments are NULL and "v_event" is not NULL,
|
||||||
/// information about changed windows is added to "v_event".
|
/// information about changed windows is added to "v_event".
|
||||||
static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win,
|
static void check_window_scroll_resize(int *size_count, win_T **first_scroll_win,
|
||||||
win_T **first_size_win, list_T *winlist, dict_T *v_event)
|
win_T **first_size_win, list_T *winlist, dict_T *v_event)
|
||||||
{
|
{
|
||||||
int result = 0;
|
|
||||||
// int listidx = 0;
|
// int listidx = 0;
|
||||||
int tot_width = 0;
|
int tot_width = 0;
|
||||||
int tot_height = 0;
|
int tot_height = 0;
|
||||||
@@ -5576,10 +5565,11 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool size_changed = wp->w_last_width != wp->w_width
|
const bool ignore_scroll = event_ignored(EVENT_WINSCROLLED, wp->w_p_eiw);
|
||||||
|| wp->w_last_height != wp->w_height;
|
const bool 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) {
|
if (size_changed) {
|
||||||
result |= CWSR_RESIZED;
|
|
||||||
if (winlist != NULL) {
|
if (winlist != NULL) {
|
||||||
// Add this window to the list of changed windows.
|
// Add this window to the list of changed windows.
|
||||||
typval_T tv = {
|
typval_T tv = {
|
||||||
@@ -5597,22 +5587,20 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win,
|
|||||||
}
|
}
|
||||||
// For WinScrolled the first window with a size change is used
|
// For WinScrolled the first window with a size change is used
|
||||||
// even when it didn't scroll.
|
// even when it didn't scroll.
|
||||||
if (*first_scroll_win == NULL) {
|
if (*first_scroll_win == NULL && !ignore_scroll) {
|
||||||
*first_scroll_win = wp;
|
*first_scroll_win = wp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool scroll_changed = wp->w_last_topline != wp->w_topline
|
const bool scroll_changed = !ignore_scroll
|
||||||
|
&& (wp->w_last_topline != wp->w_topline
|
||||||
|| wp->w_last_topfill != wp->w_topfill
|
|| wp->w_last_topfill != wp->w_topfill
|
||||||
|| wp->w_last_leftcol != wp->w_leftcol
|
|| wp->w_last_leftcol != wp->w_leftcol
|
||||||
|| wp->w_last_skipcol != wp->w_skipcol;
|
|| wp->w_last_skipcol != wp->w_skipcol);
|
||||||
if (scroll_changed) {
|
if (scroll_changed && first_scroll_win != NULL && *first_scroll_win == NULL) {
|
||||||
result |= CWSR_SCROLLED;
|
|
||||||
if (first_scroll_win != NULL && *first_scroll_win == NULL) {
|
|
||||||
*first_scroll_win = wp;
|
*first_scroll_win = wp;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_changed || scroll_changed) && v_event != NULL) {
|
if ((size_changed || scroll_changed) && v_event != NULL) {
|
||||||
// Add info about this window to the v:event dictionary.
|
// Add info about this window to the v:event dictionary.
|
||||||
@@ -5655,8 +5643,6 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trigger WinScrolled and/or WinResized if any window in the current tab page
|
/// Trigger WinScrolled and/or WinResized if any window in the current tab page
|
||||||
@@ -5676,11 +5662,9 @@ void may_trigger_win_scrolled_resized(void)
|
|||||||
int size_count = 0;
|
int size_count = 0;
|
||||||
win_T *first_scroll_win = NULL;
|
win_T *first_scroll_win = NULL;
|
||||||
win_T *first_size_win = NULL;
|
win_T *first_size_win = NULL;
|
||||||
int cwsr = check_window_scroll_resize(&size_count,
|
check_window_scroll_resize(&size_count, &first_scroll_win, &first_size_win, NULL, NULL);
|
||||||
&first_scroll_win, &first_size_win,
|
|
||||||
NULL, NULL);
|
|
||||||
bool trigger_resize = do_resize && size_count > 0;
|
bool trigger_resize = do_resize && size_count > 0;
|
||||||
bool trigger_scroll = do_scroll && cwsr != 0;
|
bool trigger_scroll = do_scroll && first_scroll_win != NULL;
|
||||||
if (!trigger_resize && !trigger_scroll) {
|
if (!trigger_resize && !trigger_scroll) {
|
||||||
return; // no relevant changes
|
return; // no relevant changes
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
local t = require('test.testutil')
|
local t = require('test.testutil')
|
||||||
local n = require('test.functional.testnvim')()
|
local n = require('test.functional.testnvim')()
|
||||||
|
local Screen = require('test.functional.ui.screen')
|
||||||
|
|
||||||
local clear = n.clear
|
local clear = n.clear
|
||||||
local write_file = t.write_file
|
local write_file = t.write_file
|
||||||
@@ -40,3 +41,53 @@ it('no E440 in quickfix window when autocommand invalidates undo', function()
|
|||||||
feed('G')
|
feed('G')
|
||||||
eq('', api.nvim_get_vvar('errmsg'))
|
eq('', api.nvim_get_vvar('errmsg'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- oldtest: Test_WinScrolled_Resized_eiw()
|
||||||
|
it('WinScrolled and WinResized events can be ignored in a window', function()
|
||||||
|
local screen = Screen.new()
|
||||||
|
n.exec([[
|
||||||
|
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]
|
||||||
|
]])
|
||||||
|
feed('<C-W>-')
|
||||||
|
screen:expect([[
|
||||||
|
^foo |
|
||||||
|
foo |*4
|
||||||
|
{3:[No Name] [+] }|
|
||||||
|
foo |*6
|
||||||
|
{2:[No Name] [+] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
feed(':echo g:afile g:resized g:scrolled<CR>')
|
||||||
|
screen:expect({ any = 'none 0 0.*' })
|
||||||
|
feed('G')
|
||||||
|
screen:expect([[
|
||||||
|
foo |*4
|
||||||
|
^foo |
|
||||||
|
{3:[No Name] [+] }|
|
||||||
|
foo |*6
|
||||||
|
{2:[No Name] [+] }|
|
||||||
|
none 0 0 |
|
||||||
|
]])
|
||||||
|
feed('gg')
|
||||||
|
screen:expect([[
|
||||||
|
^foo |
|
||||||
|
foo |*4
|
||||||
|
{3:[No Name] [+] }|
|
||||||
|
foo |*6
|
||||||
|
{2:[No Name] [+] }|
|
||||||
|
none 0 0 |
|
||||||
|
]])
|
||||||
|
feed(':echo g:afile g:resized g:scrolled')
|
||||||
|
screen:expect({ any = ':echo g:afile g:resized g:scrolled.*' })
|
||||||
|
feed('<CR>')
|
||||||
|
screen:expect({ any = 'none 0 0.*' })
|
||||||
|
feed(':set eventignorewin=<CR><C-W>w<C-W>+')
|
||||||
|
screen:expect({ any = ':set eventignorewin=.*' })
|
||||||
|
feed(':echo win_getid() g:afile g:resized g:scrolled<CR>')
|
||||||
|
screen:expect({ any = '1000 1001 1 1.*' })
|
||||||
|
end)
|
||||||
|
@@ -220,6 +220,8 @@ let test_values = {
|
|||||||
"\ 'encoding': [['latin1'], ['xxx', '']],
|
"\ 'encoding': [['latin1'], ['xxx', '']],
|
||||||
\ 'eventignore': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
|
\ 'eventignore': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
|
||||||
\ ['xxx']],
|
\ ['xxx']],
|
||||||
|
\ 'eventignorewin': [['', 'WinEnter', 'WinLeave,winenter', 'all,WinEnter'],
|
||||||
|
\ ['xxx', 'WinNew']],
|
||||||
\ 'fileencoding': [['', 'latin1', 'xxx'], []],
|
\ 'fileencoding': [['', 'latin1', 'xxx'], []],
|
||||||
\ 'fileformat': [['dos', 'unix', 'mac'], ['xxx']],
|
\ 'fileformat': [['dos', 'unix', 'mac'], ['xxx']],
|
||||||
\ 'fileformats': [['', 'dos', 'dos,unix'], ['xxx']],
|
\ 'fileformats': [['', 'dos', 'dos,unix'], ['xxx']],
|
||||||
|
@@ -4205,4 +4205,64 @@ func Test_OptionSet_cmdheight()
|
|||||||
set cmdheight& mouse& laststatus&
|
set cmdheight& mouse& laststatus&
|
||||||
endfunc
|
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_eiw', 'D')
|
||||||
|
let buf = RunVimInTerminal('-S Xtest_winscrolled_eiw', {'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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -589,6 +589,7 @@ func Test_set_completion_string_values()
|
|||||||
|
|
||||||
" Other string options that queries the system rather than fixed enum names
|
" 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(['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('latin1', getcompletion('set fileencodings=', 'cmdline')[1])
|
||||||
" call assert_equal('top', getcompletion('set printoptions=', 'cmdline')[0])
|
" call assert_equal('top', getcompletion('set printoptions=', 'cmdline')[0])
|
||||||
" call assert_equal('SpecialKey', getcompletion('set wincolor=', 'cmdline')[0])
|
" call assert_equal('SpecialKey', getcompletion('set wincolor=', 'cmdline')[0])
|
||||||
@@ -2506,6 +2507,7 @@ func Test_string_option_revert_on_failure()
|
|||||||
\ ['eadirection', 'hor', 'a123'],
|
\ ['eadirection', 'hor', 'a123'],
|
||||||
\ ['encoding', 'utf-8', 'a123'],
|
\ ['encoding', 'utf-8', 'a123'],
|
||||||
\ ['eventignore', 'TextYankPost', 'a123'],
|
\ ['eventignore', 'TextYankPost', 'a123'],
|
||||||
|
\ ['eventignorewin', 'WinScrolled', 'a123'],
|
||||||
\ ['fileencoding', 'utf-8', 'a123,'],
|
\ ['fileencoding', 'utf-8', 'a123,'],
|
||||||
\ ['fileformat', 'mac', 'a123'],
|
\ ['fileformat', 'mac', 'a123'],
|
||||||
\ ['fileformats', 'mac', 'a123'],
|
\ ['fileformats', 'mac', 'a123'],
|
||||||
|
Reference in New Issue
Block a user