diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/auevents.lua | 285 | ||||
-rw-r--r-- | src/nvim/autocmd.c | 77 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/generators/gen_events.lua | 49 | ||||
-rw-r--r-- | src/nvim/generators/gen_vimvim.lua | 18 | ||||
-rw-r--r-- | src/nvim/option.c | 5 | ||||
-rw-r--r-- | src/nvim/options.lua | 17 | ||||
-rw-r--r-- | src/nvim/optionstr.c | 15 | ||||
-rw-r--r-- | src/nvim/window.c | 56 |
9 files changed, 266 insertions, 258 deletions
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index 84735c293a..9655fef0a4 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -1,156 +1,139 @@ return { + --- @type [string, string[], boolean][] List of [eventname, aliases, window-local event] tuples. events = { - 'BufAdd', -- after adding a buffer to the buffer list - 'BufDelete', -- deleting a buffer from the buffer list - 'BufEnter', -- after entering a buffer - 'BufFilePost', -- after renaming a buffer - 'BufFilePre', -- before renaming a buffer - 'BufHidden', -- just after buffer becomes hidden - 'BufLeave', -- before leaving a buffer - 'BufModifiedSet', -- after the 'modified' state of a buffer changes - 'BufNew', -- after creating any buffer - 'BufNewFile', -- when creating a buffer for a new file - 'BufReadCmd', -- read buffer using command - 'BufReadPost', -- after reading a buffer - 'BufReadPre', -- before reading a buffer - 'BufUnload', -- just before unloading a buffer - 'BufWinEnter', -- after showing a buffer in a window - 'BufWinLeave', -- just after buffer removed from window - 'BufWipeout', -- just before really deleting a buffer - 'BufWriteCmd', -- write buffer using command - 'BufWritePost', -- after writing a buffer - 'BufWritePre', -- before writing a buffer - 'ChanInfo', -- info was received about channel - 'ChanOpen', -- channel was opened - 'CmdUndefined', -- command undefined - 'CmdWinEnter', -- after entering the cmdline window - 'CmdWinLeave', -- before leaving the cmdline window - 'CmdlineChanged', -- command line was modified - 'CmdlineEnter', -- after entering cmdline mode - 'CmdlineLeave', -- before leaving cmdline mode - 'ColorScheme', -- after loading a colorscheme - 'ColorSchemePre', -- before loading a colorscheme - 'CompleteChanged', -- after popup menu changed - 'CompleteDone', -- after finishing insert complete - 'CompleteDonePre', -- idem, before clearing info - 'CursorHold', -- cursor in same position for a while - 'CursorHoldI', -- idem, in Insert mode - 'CursorMoved', -- cursor was moved - 'CursorMovedC', -- cursor was moved in Cmdline mode - 'CursorMovedI', -- cursor was moved in Insert mode - 'DiagnosticChanged', -- diagnostics in a buffer were modified - 'DiffUpdated', -- diffs have been updated - 'DirChanged', -- directory changed - 'DirChangedPre', -- directory is going to change - 'EncodingChanged', -- after changing the 'encoding' option - 'ExitPre', -- before exiting - 'FileAppendCmd', -- append to a file using command - 'FileAppendPost', -- after appending to a file - 'FileAppendPre', -- before appending to a file - 'FileChangedRO', -- before first change to read-only file - 'FileChangedShell', -- after shell command that changed file - 'FileChangedShellPost', -- after (not) reloading changed file - 'FileReadCmd', -- read from a file using command - 'FileReadPost', -- after reading a file - 'FileReadPre', -- before reading a file - 'FileType', -- new file type detected (user defined) - 'FileWriteCmd', -- write to a file using command - 'FileWritePost', -- after writing a file - 'FileWritePre', -- before writing a file - 'FilterReadPost', -- after reading from a filter - 'FilterReadPre', -- before reading from a filter - 'FilterWritePost', -- after writing to a filter - 'FilterWritePre', -- before writing to a filter - 'FocusGained', -- got the focus - 'FocusLost', -- lost the focus to another app - 'FuncUndefined', -- if calling a function which doesn't exist - 'GUIEnter', -- after starting the GUI - 'GUIFailed', -- after starting the GUI failed - 'InsertChange', -- when changing Insert/Replace mode - 'InsertCharPre', -- before inserting a char - 'InsertEnter', -- when entering Insert mode - 'InsertLeave', -- just after leaving Insert mode - 'InsertLeavePre', -- just before leaving Insert mode - 'LspAttach', -- after an LSP client attaches to a buffer - 'LspDetach', -- after an LSP client detaches from a buffer - 'LspNotify', -- after an LSP notice has been sent to the server - 'LspProgress', -- after a LSP progress update - 'LspRequest', -- after an LSP request is started, canceled, or completed - 'LspTokenUpdate', -- after a visible LSP token is updated - 'MenuPopup', -- just before popup menu is displayed - 'ModeChanged', -- after changing the mode - 'OptionSet', -- after setting any option - 'QuickFixCmdPost', -- after :make, :grep etc. - 'QuickFixCmdPre', -- before :make, :grep etc. - 'QuitPre', -- before :quit - 'RecordingEnter', -- when starting to record a macro - 'RecordingLeave', -- just before a macro stops recording - 'RemoteReply', -- upon string reception from a remote vim - 'SafeState', -- going to wait for a character - 'SearchWrapped', -- after the search wrapped around - 'SessionLoadPost', -- after loading a session file - 'SessionWritePost', -- after writing a session file - 'ShellCmdPost', -- after ":!cmd" - 'ShellFilterPost', -- after ":1,2!cmd", ":w !cmd", ":r !cmd". - 'Signal', -- after nvim process received a signal - 'SourceCmd', -- sourcing a Vim script using command - 'SourcePost', -- after sourcing a Vim script - 'SourcePre', -- before sourcing a Vim script - 'SpellFileMissing', -- spell file missing - 'StdinReadPost', -- after reading from stdin - 'StdinReadPre', -- before reading from stdin - 'SwapExists', -- found existing swap file - 'Syntax', -- syntax selected - 'TabClosed', -- a tab has closed - 'TabEnter', -- after entering a tab page - 'TabLeave', -- before leaving a tab page - 'TabNew', -- when creating a new tab - 'TabNewEntered', -- after entering a new tab - 'TermChanged', -- after changing 'term' - 'TermClose', -- after the process exits - 'TermEnter', -- after entering Terminal mode - 'TermLeave', -- after leaving Terminal mode - 'TermOpen', -- after opening a terminal buffer - 'TermRequest', -- after an unhandled OSC sequence is emitted - 'TermResponse', -- after setting "v:termresponse" - 'TextChanged', -- text was modified - 'TextChangedI', -- text was modified in Insert mode(no popup) - 'TextChangedP', -- text was modified in Insert mode(popup) - 'TextChangedT', -- text was modified in Terminal mode - 'TextYankPost', -- after a yank or delete was done (y, d, c) - 'UIEnter', -- after UI attaches - 'UILeave', -- after UI detaches - 'User', -- user defined autocommand - 'VimEnter', -- after starting Vim - 'VimLeave', -- before exiting Vim - 'VimLeavePre', -- before exiting Vim and writing ShaDa file - 'VimResized', -- after Vim window was resized - 'VimResume', -- after Nvim is resumed - 'VimSuspend', -- before Nvim is suspended - 'WinClosed', -- after closing a window - 'WinEnter', -- after entering a window - 'WinLeave', -- before leaving a window - 'WinNew', -- when entering a new window - 'WinResized', -- after a window was resized - 'WinScrolled', -- after a window was scrolled or resized - }, - aliases = { - { - 'BufCreate', - 'BufAdd', - }, - { - 'BufRead', - 'BufReadPost', - }, - { - 'BufWrite', - 'BufWritePre', - }, - { - 'FileEncoding', - 'EncodingChanged', - }, + { 'BufAdd', { 'BufCreate' }, true }, -- after adding a buffer to the buffer list + { 'BufDelete', {}, true }, -- deleting a buffer from the buffer list + { 'BufEnter', {}, true }, -- after entering a buffer + { 'BufFilePost', {}, true }, -- after renaming a buffer + { 'BufFilePre', {}, true }, -- before renaming a buffer + { 'BufHidden', {}, true }, -- just after buffer becomes hidden + { 'BufLeave', {}, true }, -- before leaving a buffer + { 'BufModifiedSet', {}, true }, -- after the 'modified' state of a buffer changes + { 'BufNew', {}, true }, -- after creating any buffer + { 'BufNewFile', {}, true }, -- when creating a buffer for a new file + { 'BufReadCmd', {}, true }, -- read buffer using command + { 'BufReadPost', { 'BufRead' }, true }, -- after reading a buffer + { 'BufReadPre', {}, true }, -- before reading a buffer + { 'BufUnload', {}, true }, -- just before unloading a buffer + { 'BufWinEnter', {}, true }, -- after showing a buffer in a window + { 'BufWinLeave', {}, true }, -- just after buffer removed from window + { 'BufWipeout', {}, true }, -- just before really deleting a buffer + { 'BufWriteCmd', {}, true }, -- write buffer using command + { 'BufWritePost', {}, true }, -- after writing a buffer + { 'BufWritePre', { 'BufWrite' }, true }, -- before writing a buffer + { 'ChanInfo', {}, false }, -- info was received about channel + { 'ChanOpen', {}, false }, -- channel was opened + { 'CmdUndefined', {}, false }, -- command undefined + { 'CmdWinEnter', {}, false }, -- after entering the cmdline window + { 'CmdWinLeave', {}, false }, -- before leaving the cmdline window + { 'CmdlineChanged', {}, false }, -- command line was modified + { 'CmdlineEnter', {}, false }, -- after entering cmdline mode + { 'CmdlineLeave', {}, false }, -- before leaving cmdline mode + { 'ColorScheme', {}, false }, -- after loading a colorscheme + { 'ColorSchemePre', {}, false }, -- before loading a colorscheme + { 'CompleteChanged', {}, false }, -- after popup menu changed + { 'CompleteDone', {}, false }, -- after finishing insert complete + { 'CompleteDonePre', {}, false }, -- idem, before clearing info + { 'CursorHold', {}, true }, -- cursor in same position for a while + { 'CursorHoldI', {}, true }, -- idem, in Insert mode + { 'CursorMoved', {}, true }, -- cursor was moved + { 'CursorMovedC', {}, true }, -- cursor was moved in Cmdline mode + { 'CursorMovedI', {}, true }, -- cursor was moved in Insert mode + { 'DiagnosticChanged', {}, false }, -- diagnostics in a buffer were modified + { 'DiffUpdated', {}, false }, -- diffs have been updated + { 'DirChanged', {}, false }, -- directory changed + { 'DirChangedPre', {}, false }, -- directory is going to change + { 'EncodingChanged', { 'FileEncoding' }, false }, -- after changing the 'encoding' option + { 'ExitPre', {}, false }, -- before exiting + { 'FileAppendCmd', {}, true }, -- append to a file using command + { 'FileAppendPost', {}, true }, -- after appending to a file + { 'FileAppendPre', {}, true }, -- before appending to a file + { 'FileChangedRO', {}, true }, -- before first change to read-only file + { 'FileChangedShell', {}, true }, -- after shell command that changed file + { 'FileChangedShellPost', {}, true }, -- after (not) reloading changed file + { 'FileReadCmd', {}, true }, -- read from a file using command + { 'FileReadPost', {}, true }, -- after reading a file + { 'FileReadPre', {}, true }, -- before reading a file + { 'FileType', {}, true }, -- new file type detected (user defined) + { 'FileWriteCmd', {}, true }, -- write to a file using command + { 'FileWritePost', {}, true }, -- after writing a file + { 'FileWritePre', {}, true }, -- before writing a file + { 'FilterReadPost', {}, true }, -- after reading from a filter + { 'FilterReadPre', {}, true }, -- before reading from a filter + { 'FilterWritePost', {}, true }, -- after writing to a filter + { 'FilterWritePre', {}, true }, -- before writing to a filter + { 'FocusGained', {}, false }, -- got the focus + { 'FocusLost', {}, false }, -- lost the focus to another app + { 'FuncUndefined', {}, false }, -- if calling a function which doesn't exist + { 'GUIEnter', {}, false }, -- after starting the GUI + { 'GUIFailed', {}, false }, -- after starting the GUI failed + { 'InsertChange', {}, true }, -- when changing Insert/Replace mode + { 'InsertCharPre', {}, true }, -- before inserting a char + { 'InsertEnter', {}, true }, -- when entering Insert mode + { 'InsertLeave', {}, true }, -- just after leaving Insert mode + { 'InsertLeavePre', {}, true }, -- just before leaving Insert mode + { 'LspAttach', {}, false }, -- after an LSP client attaches to a buffer + { 'LspDetach', {}, false }, -- after an LSP client detaches from a buffer + { 'LspNotify', {}, false }, -- after an LSP notice has been sent to the server + { 'LspProgress', {}, false }, -- after a LSP progress update + { 'LspRequest', {}, false }, -- after an LSP request is started, canceled, or completed + { 'LspTokenUpdate', {}, false }, -- after a visible LSP token is updated + { 'MenuPopup', {}, false }, -- just before popup menu is displayed + { 'ModeChanged', {}, false }, -- after changing the mode + { 'OptionSet', {}, false }, -- after setting any option + { 'QuickFixCmdPost', {}, false }, -- after :make, :grep etc. + { 'QuickFixCmdPre', {}, false }, -- before :make, :grep etc. + { 'QuitPre', {}, false }, -- before :quit + { 'RecordingEnter', {}, true }, -- when starting to record a macro + { 'RecordingLeave', {}, true }, -- just before a macro stops recording + { 'RemoteReply', {}, false }, -- upon string reception from a remote vim + { 'SafeState', {}, false }, -- going to wait for a character + { 'SearchWrapped', {}, true }, -- after the search wrapped around + { 'SessionLoadPost', {}, false }, -- after loading a session file + { 'SessionWritePost', {}, false }, -- after writing a session file + { 'ShellCmdPost', {}, false }, -- after ":!cmd" + { 'ShellFilterPost', {}, true }, -- after ":1,2!cmd", ":w !cmd", ":r !cmd". + { 'Signal', {}, false }, -- after nvim process received a signal + { 'SourceCmd', {}, false }, -- sourcing a Vim script using command + { 'SourcePost', {}, false }, -- after sourcing a Vim script + { 'SourcePre', {}, false }, -- before sourcing a Vim script + { 'SpellFileMissing', {}, false }, -- spell file missing + { 'StdinReadPost', {}, false }, -- after reading from stdin + { 'StdinReadPre', {}, false }, -- before reading from stdin + { 'SwapExists', {}, false }, -- found existing swap file + { 'Syntax', {}, false }, -- syntax selected + { 'TabClosed', {}, false }, -- a tab has closed + { 'TabEnter', {}, false }, -- after entering a tab page + { 'TabLeave', {}, false }, -- before leaving a tab page + { 'TabNew', {}, false }, -- when creating a new tab + { 'TabNewEntered', {}, false }, -- after entering a new tab + { 'TermChanged', {}, false }, -- after changing 'term' + { 'TermClose', {}, false }, -- after the process exits + { 'TermEnter', {}, false }, -- after entering Terminal mode + { 'TermLeave', {}, false }, -- after leaving Terminal mode + { 'TermOpen', {}, false }, -- after opening a terminal buffer + { 'TermRequest', {}, false }, -- after an unhandled OSC sequence is emitted + { 'TermResponse', {}, false }, -- after setting "v:termresponse" + { 'TextChanged', {}, true }, -- text was modified + { 'TextChangedI', {}, true }, -- text was modified in Insert mode(no popup) + { 'TextChangedP', {}, true }, -- text was modified in Insert mode(popup) + { 'TextChangedT', {}, true }, -- text was modified in Terminal mode + { 'TextYankPost', {}, true }, -- after a yank or delete was done (y, d, c) + { 'UIEnter', {}, false }, -- after UI attaches + { 'UILeave', {}, false }, -- after UI detaches + { 'User', {}, false }, -- user defined autocommand + { 'VimEnter', {}, false }, -- after starting Vim + { 'VimLeave', {}, false }, -- before exiting Vim + { 'VimLeavePre', {}, false }, -- before exiting Vim and writing ShaDa file + { 'VimResized', {}, false }, -- after Vim window was resized + { 'VimResume', {}, false }, -- after Nvim is resumed + { 'VimSuspend', {}, false }, -- before Nvim is suspended + { 'WinClosed', {}, true }, -- after closing a window + { 'WinEnter', {}, true }, -- after entering a window + { 'WinLeave', {}, true }, -- before leaving a window + { 'WinNew', {}, false }, -- when entering a new window + { 'WinResized', {}, true }, -- after a window was resized + { 'WinScrolled', {}, true }, -- after a window was scrolled or resized }, -- List of nvim-specific events or aliases for the purpose of generating -- syntax file diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 96da4695de..ad27823667 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -634,7 +634,7 @@ event_T event_name2nr(const char *start, char **end) if (event_names[i].name == NULL) { return NUM_EVENTS; } - return event_names[i].event; + return (event_T)abs(event_names[i].event); } /// 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++) { 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; @@ -658,25 +658,23 @@ const char *event_nr2name(event_T event) FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST { 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 "Unknown"; } -/// Return true if "event" is included in 'eventignore'. +/// Return true if "event" is included in 'eventignore(win)'. /// /// @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 { - char *p = p_ei; - - while (*p != NUL) { - if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) { + while (*ei != NUL) { + if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ',')) { return true; - } else if (event_name2nr(p, &p) == event) { + } else if (event_name2nr(ei, &ei) == event) { return true; } } @@ -684,19 +682,23 @@ static bool event_ignored(event_T event) return false; } -// Return OK when the contents of p_ei is valid, FAIL otherwise. -int check_ei(void) +/// Return OK when the contents of 'eventignore' or 'eventignorewin' is valid, +/// FAIL otherwise. +int check_ei(char *ei) { - char *p = p_ei; + bool win = ei != p_ei; - while (*p) { - if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) { - p += 3; - if (*p == ',') { - p++; + while (*ei) { + if (STRNICMP(ei, "all", 3) == 0 && (ei[3] == NUL || ei[3] == ',')) { + ei += 3; + if (*ei == ',') { + ei++; + } + } else { + event_T event = event_name2nr(ei, &ei); + if (event == NUM_EVENTS || (win && event_names[event].event > 0)) { + return FAIL; } - } else if (event_name2nr(p, &p) == NUM_EVENTS) { - return FAIL; } } @@ -1631,7 +1633,24 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force } // 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; } @@ -2279,9 +2298,21 @@ char *expand_get_event_name(expand_T *xp, int idx) /// Function given to ExpandGeneric() to obtain the list of event names. Don't /// 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) { - return event_names[idx].name; + if (!win) { + 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 diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index bffb29578f..28029d0249 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -96,6 +96,8 @@ typedef struct { int wo_diff; #define w_p_diff w_onebuf_opt.wo_diff // 'diff' 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' char *wo_fdc_save; #define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode diff --git a/src/nvim/generators/gen_events.lua b/src/nvim/generators/gen_events.lua index ee48e918e8..8c87815a74 100644 --- a/src/nvim/generators/gen_events.lua +++ b/src/nvim/generators/gen_events.lua @@ -3,7 +3,6 @@ local names_file = arg[2] local auevents = require('auevents') local events = auevents.events -local aliases = auevents.aliases local enum_tgt = io.open(fileio_enum_file, 'w') local names_tgt = io.open(names_file, 'w') @@ -16,46 +15,28 @@ names_tgt:write([[ static const struct event_name { size_t len; char *name; - event_T event; + int event; } event_names[] = {]]) +local aliases = 0 for i, event in ipairs(events) do - enum_tgt:write(('\n EVENT_%s = %u,'):format(event:upper(), i - 1)) - names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#event, event, event:upper())) + enum_tgt:write(('\n EVENT_%s = %u,'):format(event[1]:upper(), i + aliases - 1)) + -- 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. - enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i)) + enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i + aliases)) end end -for _, v in ipairs(aliases) do - local alias = v[1] - local event = v[2] - names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#alias, alias, event:upper())) -end - -names_tgt:write('\n {0, NULL, (event_T)0},') +names_tgt:write('\n {0, NULL, (event_T)0},\n};\n') +names_tgt:write('\nstatic AutoCmdVec autocmds[NUM_EVENTS] = { 0 };\n') +names_tgt:close() 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() -names_tgt:close() diff --git a/src/nvim/generators/gen_vimvim.lua b/src/nvim/generators/gen_vimvim.lua index d8053822bf..3817735a55 100644 --- a/src/nvim/generators/gen_vimvim.lua +++ b/src/nvim/generators/gen_vimvim.lua @@ -114,19 +114,19 @@ local vimau_start = 'syn keyword vimAutoEvent contained ' w('\n\n' .. vimau_start) 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 w('\n' .. vimau_start) end - w(' ' .. au) - end -end -for _, au in pairs(auevents.aliases) do - if lld.line_length > 850 then - w('\n' .. vimau_start) + 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 - -- au[1] is aliased to au[2] - w(' ' .. au[1]) end local nvimau_start = 'syn keyword nvimAutoEvent contained ' diff --git a/src/nvim/option.c b/src/nvim/option.c index 796165453c..f92ec349da 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4580,6 +4580,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win) return &(win->w_p_cc); case kOptDiff: return &(win->w_p_diff); + case kOptEventignorewin: + return &(win->w_p_eiw); case kOptFoldcolumn: return &(win->w_p_fdc); 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_diff = from->wo_diff; 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_cole = from->wo_cole; 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_fdt); check_string_option(&wop->wo_fmr); + check_string_option(&wop->wo_eiw); check_string_option(&wop->wo_scl); check_string_option(&wop->wo_rlc); 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_fdt); clear_string_option(&wop->wo_fmr); + clear_string_option(&wop->wo_eiw); clear_string_option(&wop->wo_scl); clear_string_option(&wop->wo_rlc); clear_string_option(&wop->wo_sbr); diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 99ac9d61ad..36799e9a24 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2628,6 +2628,23 @@ local options = { 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', defaults = false, desc = [=[ diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 645bb23638..3a6b4c9936 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -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); } -/// The 'eventignore' option is changed. -const char *did_set_eventignore(optset_T *args FUNC_ATTR_UNUSED) +/// The 'eventignore(win)' option is changed. +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 NULL; } +static bool expand_eiw = false; + 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. if (idx == 0) { 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) { + expand_eiw = args->oe_varp != (char *)&p_ei; return expand_set_opt_generic(args, get_eventignore_name, numMatches, matches); } diff --git a/src/nvim/window.c b/src/nvim/window.c index fa2bfec138..1fa31f10b1 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5530,31 +5530,20 @@ static dict_T *make_win_info_dict(int width, int height, int topline, int topfil 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: -/// 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. /// /// 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 check_window_scroll_resize(int *size_count, win_T **first_scroll_win, - win_T **first_size_win, list_T *winlist, dict_T *v_event) +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) { - int result = 0; // int listidx = 0; int tot_width = 0; int tot_height = 0; @@ -5576,10 +5565,11 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, continue; } - const bool size_changed = wp->w_last_width != wp->w_width - || wp->w_last_height != wp->w_height; + const bool ignore_scroll = event_ignored(EVENT_WINSCROLLED, wp->w_p_eiw); + 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) { - result |= CWSR_RESIZED; if (winlist != NULL) { // Add this window to the list of changed windows. typval_T tv = { @@ -5597,21 +5587,19 @@ 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 // even when it didn't scroll. - if (*first_scroll_win == NULL) { + if (*first_scroll_win == NULL && !ignore_scroll) { *first_scroll_win = wp; } } } - const bool scroll_changed = wp->w_last_topline != wp->w_topline - || wp->w_last_topfill != wp->w_topfill - || 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; - } + const bool scroll_changed = !ignore_scroll + && (wp->w_last_topline != wp->w_topline + || wp->w_last_topfill != wp->w_topfill + || wp->w_last_leftcol != wp->w_leftcol + || wp->w_last_skipcol != wp->w_skipcol); + if (scroll_changed && first_scroll_win != NULL && *first_scroll_win == NULL) { + *first_scroll_win = wp; } if ((size_changed || scroll_changed) && v_event != NULL) { @@ -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 @@ -5676,11 +5662,9 @@ void may_trigger_win_scrolled_resized(void) int size_count = 0; win_T *first_scroll_win = NULL; win_T *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); 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) { return; // no relevant changes } |