diff options
author | luukvbaal <luukvbaal@gmail.com> | 2025-02-12 11:01:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-12 11:01:06 +0100 |
commit | 82a215cb2dc2b80c1b8bc455c90a928b636d8b3a (patch) | |
tree | b264cb2900a0bd59b3ff4976f0cf47a06cfd5f19 /src/nvim/autocmd.c | |
parent | 6982106f8ca5ceaa00c9909e64cc94d2794b9143 (diff) | |
download | rneovim-82a215cb2dc2b80c1b8bc455c90a928b636d8b3a.tar.gz rneovim-82a215cb2dc2b80c1b8bc455c90a928b636d8b3a.tar.bz2 rneovim-82a215cb2dc2b80c1b8bc455c90a928b636d8b3a.zip |
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.
https://github.com/vim/vim/commit/b7147f8236c962cd74d1ce028d9106f1c449ea6c
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 unique
https://github.com/vim/vim/commit/bfc7719e48ffc365ee0a1bd1888120d26b6365f0
Diffstat (limited to 'src/nvim/autocmd.c')
-rw-r--r-- | src/nvim/autocmd.c | 77 |
1 files changed, 54 insertions, 23 deletions
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 |