mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #11331 'WinClosed autocmd'
This commit is contained in:
@@ -317,6 +317,7 @@ Name triggered by ~
|
||||
|CursorMoved| the cursor was moved in Normal mode
|
||||
|CursorMovedI| the cursor was moved in Insert mode
|
||||
|
||||
|WinClosed| after closing a window
|
||||
|WinNew| after creating a new window
|
||||
|WinEnter| after entering another window
|
||||
|WinLeave| before leaving a window
|
||||
@@ -396,17 +397,18 @@ BufFilePost After changing the name of the current buffer
|
||||
BufFilePre Before changing the name of the current buffer
|
||||
with the ":file" or ":saveas" command.
|
||||
*BufHidden*
|
||||
BufHidden Just before a buffer becomes hidden. That is,
|
||||
when there are no longer windows that show
|
||||
the buffer, but the buffer is not unloaded or
|
||||
deleted. Not used for ":qa" or ":q" when
|
||||
exiting Vim.
|
||||
BufHidden Before a buffer becomes hidden: when there are
|
||||
no longer windows that show the buffer, but
|
||||
the buffer is not unloaded or deleted.
|
||||
|
||||
Not used for ":qa" or ":q" when exiting Vim.
|
||||
NOTE: current buffer "%" may be different from
|
||||
the buffer being unloaded "<afile>".
|
||||
*BufLeave*
|
||||
BufLeave Before leaving to another buffer. Also when
|
||||
leaving or closing the current window and the
|
||||
new current window is not for the same buffer.
|
||||
|
||||
Not used for ":qa" or ":q" when exiting Vim.
|
||||
*BufNew*
|
||||
BufNew Just after creating a new buffer. Also used
|
||||
@@ -422,16 +424,17 @@ BufNewFile When starting to edit a file that doesn't
|
||||
*BufRead* *BufReadPost*
|
||||
BufRead or BufReadPost When starting to edit a new buffer, after
|
||||
reading the file into the buffer, before
|
||||
executing the modelines. See |BufWinEnter|
|
||||
for when you need to do something after
|
||||
processing the modelines.
|
||||
This does NOT work for ":r file". Not used
|
||||
when the file doesn't exist. Also used after
|
||||
successfully recovering a file.
|
||||
Also triggered for the filetypedetect group
|
||||
when executing ":filetype detect" and when
|
||||
writing an unnamed buffer in a way that the
|
||||
buffer gets a name.
|
||||
processing modelines. See |BufWinEnter| to do
|
||||
something after processing modelines.
|
||||
Also triggered:
|
||||
- when writing an unnamed buffer such that the
|
||||
buffer gets a name
|
||||
- after successfully recovering a file
|
||||
- for the "filetypedetect" group when
|
||||
executing ":filetype detect"
|
||||
Not triggered:
|
||||
- for ":r file"
|
||||
- if the file doesn't exist
|
||||
*BufReadCmd*
|
||||
BufReadCmd Before starting to edit a new buffer. Should
|
||||
read the file into the buffer. |Cmd-event|
|
||||
@@ -440,34 +443,33 @@ BufReadPre When starting to edit a new buffer, before
|
||||
reading the file into the buffer. Not used
|
||||
if the file doesn't exist.
|
||||
*BufUnload*
|
||||
BufUnload Before unloading a buffer. This is when the
|
||||
text in the buffer is going to be freed. This
|
||||
may be after a BufWritePost and before a
|
||||
BufDelete. Also used for all buffers that are
|
||||
loaded when Vim is going to exit.
|
||||
BufUnload Before unloading a buffer, when the text in
|
||||
the buffer is going to be freed.
|
||||
After BufWritePost.
|
||||
Before BufDelete.
|
||||
Triggers for all loaded buffers when Vim is
|
||||
going to exit.
|
||||
NOTE: Current buffer "%" may be different from
|
||||
the buffer being unloaded "<afile>".
|
||||
Do not change to another buffer or window!
|
||||
Do not switch buffers or windows!
|
||||
Not triggered when exiting and v:dying is 2 or
|
||||
more.
|
||||
*BufWinEnter*
|
||||
BufWinEnter After a buffer is displayed in a window. This
|
||||
can be when the buffer is loaded (after
|
||||
processing the modelines) or when a hidden
|
||||
buffer is displayed in a window (and is no
|
||||
longer hidden).
|
||||
Does not happen for |:split| without
|
||||
arguments, since you keep editing the same
|
||||
buffer, or ":split" with a file that's already
|
||||
open in a window, because it re-uses an
|
||||
existing buffer. But it does happen for a
|
||||
":split" with the name of the current buffer,
|
||||
since it reloads that buffer.
|
||||
may be when the buffer is loaded (after
|
||||
processing modelines) or when a hidden buffer
|
||||
is displayed (and is no longer hidden).
|
||||
|
||||
Not triggered for |:split| without arguments,
|
||||
since the buffer does not change, or :split
|
||||
with a file already open in a window.
|
||||
Triggered for ":split" with the name of the
|
||||
current buffer, since it reloads that buffer.
|
||||
*BufWinLeave*
|
||||
BufWinLeave Before a buffer is removed from a window.
|
||||
Not when it's still visible in another window.
|
||||
Also triggered when exiting. It's triggered
|
||||
before BufUnload or BufHidden.
|
||||
Also triggered when exiting.
|
||||
Before BufUnload, BufHidden.
|
||||
NOTE: Current buffer "%" may be different from
|
||||
the buffer being unloaded "<afile>".
|
||||
Not triggered when exiting and v:dying is 2 or
|
||||
@@ -515,7 +517,7 @@ CmdUndefined When a user command is used but it isn't
|
||||
defined. Useful for defining a command only
|
||||
when it's used. The pattern is matched
|
||||
against the command name. Both <amatch> and
|
||||
<afile> are set to the name of the command.
|
||||
<afile> expand to the command name.
|
||||
NOTE: Autocompletion won't work until the
|
||||
command is defined. An alternative is to
|
||||
always define the user command and have it
|
||||
@@ -524,12 +526,12 @@ CmdUndefined When a user command is used but it isn't
|
||||
CmdlineChanged After a change was made to the text inside
|
||||
command line. Be careful not to mess up the
|
||||
command line, it may cause Vim to lock up.
|
||||
<afile> is set to the |cmdline-char|.
|
||||
<afile> expands to the |cmdline-char|.
|
||||
*CmdlineEnter*
|
||||
CmdlineEnter After entering the command-line (including
|
||||
non-interactive use of ":" in a mapping: use
|
||||
|<Cmd>| instead to avoid this).
|
||||
<afile> is set to the |cmdline-char|.
|
||||
<afile> expands to the |cmdline-char|.
|
||||
Sets these |v:event| keys:
|
||||
cmdlevel
|
||||
cmdtype
|
||||
@@ -537,26 +539,26 @@ CmdlineEnter After entering the command-line (including
|
||||
CmdlineLeave Before leaving the command-line (including
|
||||
non-interactive use of ":" in a mapping: use
|
||||
|<Cmd>| instead to avoid this).
|
||||
<afile> is set to the |cmdline-char|.
|
||||
<afile> expands to the |cmdline-char|.
|
||||
Sets these |v:event| keys:
|
||||
abort (mutable)
|
||||
cmdlevel
|
||||
cmdtype
|
||||
Note: `abort` can only be changed from false
|
||||
to true. An autocmd cannot execute an already
|
||||
aborted cmdline by changing it to false.
|
||||
to true: cannot execute an already aborted
|
||||
cmdline by changing it to false.
|
||||
*CmdwinEnter*
|
||||
CmdwinEnter After entering the command-line window.
|
||||
Useful for setting options specifically for
|
||||
this special type of window.
|
||||
<afile> is set to a single character,
|
||||
<afile> expands to a single character,
|
||||
indicating the type of command-line.
|
||||
|cmdwin-char|
|
||||
*CmdwinLeave*
|
||||
CmdwinLeave Before leaving the command-line window.
|
||||
Useful to clean up any global setting done
|
||||
with CmdwinEnter.
|
||||
<afile> is set to a single character,
|
||||
<afile> expands to a single character,
|
||||
indicating the type of command-line.
|
||||
|cmdwin-char|
|
||||
*ColorScheme*
|
||||
@@ -575,8 +577,7 @@ ColorSchemePre Before loading a color scheme. |:colorscheme|
|
||||
CompleteChanged *CompleteChanged*
|
||||
After each time the Insert mode completion
|
||||
menu changed. Not fired on popup menu hide,
|
||||
use |CompleteDone| for that. Never triggered
|
||||
recursively.
|
||||
use |CompleteDone| for that.
|
||||
|
||||
Sets these |v:event| keys:
|
||||
completed_item See |complete-items|.
|
||||
@@ -587,7 +588,8 @@ CompleteChanged *CompleteChanged*
|
||||
size total nr of items
|
||||
scrollbar TRUE if visible
|
||||
|
||||
It is not allowed to change the text |textlock|.
|
||||
Non-recursive (event cannot trigger itself).
|
||||
Cannot change the text. |textlock|
|
||||
|
||||
The size and position of the popup are also
|
||||
available by calling |pum_getpos()|.
|
||||
@@ -598,8 +600,7 @@ CompleteDone After Insert mode completion is done. Either
|
||||
completion. |ins-completion|
|
||||
|complete_info()| can be used, the info is
|
||||
cleared after triggering CompleteDone.
|
||||
The |v:completed_item| variable contains the
|
||||
completed item.
|
||||
|v:completed_item| gives the completed item.
|
||||
|
||||
*CursorHold*
|
||||
CursorHold When the user doesn't press a key for the time
|
||||
@@ -629,9 +630,9 @@ CursorHold When the user doesn't press a key for the time
|
||||
:let &ro = &ro
|
||||
|
||||
*CursorHoldI*
|
||||
CursorHoldI Just like CursorHold, but in Insert mode.
|
||||
Not triggered when waiting for another key,
|
||||
e.g. after CTRL-V, and not when in CTRL-X mode
|
||||
CursorHoldI Like CursorHold, but in Insert mode. Not
|
||||
triggered when waiting for another key, e.g.
|
||||
after CTRL-V, and not in CTRL-X mode
|
||||
|insert_expand|.
|
||||
|
||||
*CursorMoved*
|
||||
@@ -642,7 +643,7 @@ CursorMoved After the cursor was moved in Normal or Visual
|
||||
Not triggered when there is typeahead or when
|
||||
an operator is pending.
|
||||
For an example see |match-parens|.
|
||||
Note: Cannot be skipped with `:noautocmd`.
|
||||
Note: Cannot be skipped with |:noautocmd|.
|
||||
Careful: This is triggered very often, don't
|
||||
do anything that the user does not expect or
|
||||
that is slow.
|
||||
@@ -660,11 +661,11 @@ DirChanged After the |current-directory| was changed.
|
||||
Sets these |v:event| keys:
|
||||
cwd: current working directory
|
||||
scope: "global", "tab", "window"
|
||||
Recursion is ignored.
|
||||
Non-recursive (event cannot trigger itself).
|
||||
*FileAppendCmd*
|
||||
FileAppendCmd Before appending to a file. Should do the
|
||||
appending to the file. Use the '[ and ']
|
||||
marks for the range of lines.|Cmd-event|
|
||||
marks for the range of lines. |Cmd-event|
|
||||
*FileAppendPost*
|
||||
FileAppendPost After appending to a file.
|
||||
*FileAppendPre*
|
||||
@@ -672,19 +673,18 @@ FileAppendPre Before appending to a file. Use the '[ and ']
|
||||
marks for the range of lines.
|
||||
*FileChangedRO*
|
||||
FileChangedRO Before making the first change to a read-only
|
||||
file. Can be used to check-out the file from
|
||||
file. Can be used to checkout the file from
|
||||
a source control system. Not triggered when
|
||||
the change was caused by an autocommand.
|
||||
This event is triggered when making the first
|
||||
change in a buffer or the first change after
|
||||
'readonly' was set, just before the change is
|
||||
applied to the text.
|
||||
Triggered when making the first change in
|
||||
a buffer or the first change after 'readonly'
|
||||
was set, just before the change is applied to
|
||||
the text.
|
||||
WARNING: If the autocommand moves the cursor
|
||||
the effect of the change is undefined.
|
||||
*E788*
|
||||
It is not allowed to change to another buffer
|
||||
here. You can reload the buffer but not edit
|
||||
another one.
|
||||
Cannot switch buffers. You can reload the
|
||||
buffer but not edit another one.
|
||||
*E881*
|
||||
If the number of lines changes saving for undo
|
||||
may fail and the change will be aborted.
|
||||
@@ -696,34 +696,28 @@ ExitPre When using `:quit`, `:wq` in a way it makes
|
||||
cancelled if there is a modified buffer that
|
||||
isn't automatically saved, use |VimLeavePre|
|
||||
for really exiting.
|
||||
See also |QuitPre|, |WinClosed|.
|
||||
*FileChangedShell*
|
||||
FileChangedShell When Vim notices that the modification time of
|
||||
a file has changed since editing started.
|
||||
Also when the file attributes of the file
|
||||
change or when the size of the file changes.
|
||||
|timestamp|
|
||||
Mostly triggered after executing a shell
|
||||
command, but also with a |:checktime| command
|
||||
or when gvim regains input focus.
|
||||
This autocommand is triggered for each changed
|
||||
file. It is not used when 'autoread' is set
|
||||
and the buffer was not changed. If a
|
||||
FileChangedShell autocommand is present the
|
||||
warning message and prompt is not given.
|
||||
The |v:fcs_reason| variable is set to indicate
|
||||
what happened and |v:fcs_choice| can be used
|
||||
to tell Vim what to do next.
|
||||
NOTE: When this autocommand is executed, the
|
||||
current buffer "%" may be different from the
|
||||
buffer that was changed, which is in "<afile>".
|
||||
NOTE: The commands must not change the current
|
||||
buffer, jump to another buffer or delete a
|
||||
buffer. *E246* *E811*
|
||||
NOTE: This event never nests, to avoid an
|
||||
endless loop. This means that while executing
|
||||
commands for the FileChangedShell event no
|
||||
other FileChangedShell event will be
|
||||
triggered.
|
||||
Triggered for each changed file, after:
|
||||
- executing a shell command
|
||||
- |:checktime|
|
||||
- |FocusGained|
|
||||
Not used when 'autoread' is set and the buffer
|
||||
was not changed. If a FileChangedShell
|
||||
autocommand exists the warning message and
|
||||
prompt is not given.
|
||||
|v:fcs_reason| indicates what happened. Set
|
||||
|v:fcs_choice| to control what happens next.
|
||||
NOTE: Current buffer "%" may be different from
|
||||
the buffer that was changed "<afile>".
|
||||
*E246* *E811*
|
||||
Cannot switch, jump to or delete buffers.
|
||||
Non-recursive (event cannot trigger itself).
|
||||
*FileChangedShellPost*
|
||||
FileChangedShellPost After handling a file that was changed outside
|
||||
of Vim. Can be used to update the statusline.
|
||||
@@ -740,10 +734,10 @@ FileReadPre Before reading a file with a ":read" command.
|
||||
*FileType*
|
||||
FileType When the 'filetype' option has been set. The
|
||||
pattern is matched against the filetype.
|
||||
<afile> can be used for the name of the file
|
||||
where this option was set, and <amatch> for
|
||||
the new value of 'filetype'. Navigating to
|
||||
another window or buffer is not allowed.
|
||||
<afile> is the name of the file where this
|
||||
option was set. <amatch> is the new value of
|
||||
'filetype'.
|
||||
Cannot switch windows or buffers.
|
||||
See |filetypes|.
|
||||
*FileWriteCmd*
|
||||
FileWriteCmd Before writing to a file, when not writing the
|
||||
@@ -840,7 +834,7 @@ TextYankPost Just after a |yank| or |deleting| command, but not
|
||||
and |']| marks can be used to calculate the
|
||||
precise region of the operation.
|
||||
|
||||
Recursion is ignored.
|
||||
Non-recursive (event cannot trigger itself).
|
||||
Cannot change the text. |textlock|
|
||||
*InsertEnter*
|
||||
InsertEnter Just before starting Insert mode. Also for
|
||||
@@ -907,8 +901,8 @@ OptionSet After setting an option (except during
|
||||
always use |:noautocmd| to prevent triggering
|
||||
OptionSet.
|
||||
|
||||
Recursion is ignored, thus |:set| in the
|
||||
autocommand does not trigger OptionSet again.
|
||||
Non-recursive: |:set| in the autocommand does
|
||||
not trigger OptionSet again.
|
||||
|
||||
*QuickFixCmdPre*
|
||||
QuickFixCmdPre Before a quickfix command is run (|:make|,
|
||||
@@ -940,7 +934,7 @@ QuitPre When using `:quit`, `:wq` or `:qall`, before
|
||||
or quits Vim. Can be used to close any
|
||||
non-essential window if the current window is
|
||||
the last ordinary window.
|
||||
Also see |ExitPre|.
|
||||
See also |ExitPre|, ||WinClosed|.
|
||||
*RemoteReply*
|
||||
RemoteReply When a reply from a Vim that functions as
|
||||
server was received |server2client()|. The
|
||||
@@ -1016,33 +1010,32 @@ SwapExists Detected an existing swap file when starting
|
||||
When set to an empty string the user will be
|
||||
asked, as if there was no SwapExists autocmd.
|
||||
*E812*
|
||||
It is not allowed to change to another buffer,
|
||||
change a buffer name or change directory
|
||||
here.
|
||||
Cannot change to another buffer, change
|
||||
the buffer name or change directory.
|
||||
*Syntax*
|
||||
Syntax When the 'syntax' option has been set. The
|
||||
pattern is matched against the syntax name.
|
||||
<afile> can be used for the name of the file
|
||||
where this option was set, and <amatch> for
|
||||
the new value of 'syntax'.
|
||||
<afile> expands to the name of the file where
|
||||
this option was set. <amatch> expands to the
|
||||
new value of 'syntax'.
|
||||
See |:syn-on|.
|
||||
*TabEnter*
|
||||
TabEnter Just after entering a tab page. |tab-page|
|
||||
After triggering the WinEnter and before
|
||||
triggering the BufEnter event.
|
||||
After WinEnter.
|
||||
Before BufEnter.
|
||||
*TabLeave*
|
||||
TabLeave Just before leaving a tab page. |tab-page|
|
||||
A WinLeave event will have been triggered
|
||||
first.
|
||||
After WinLeave.
|
||||
*TabNew*
|
||||
TabNew When creating a new tab page. |tab-page|
|
||||
After WinEnter and before TabEnter.
|
||||
After WinEnter.
|
||||
Before TabEnter.
|
||||
*TabNewEntered*
|
||||
TabNewEntered After entering a new tab page. |tab-page|
|
||||
After BufEnter.
|
||||
*TabClosed*
|
||||
TabClosed After closing a tab page. <afile> can be used
|
||||
for the tab page number.
|
||||
TabClosed After closing a tab page. <afile> expands to
|
||||
the tab page number.
|
||||
*TermOpen*
|
||||
TermOpen When a |terminal| job is starting. Can be
|
||||
used to configure the terminal buffer.
|
||||
@@ -1058,10 +1051,9 @@ TermClose When a |terminal| job ends.
|
||||
TermResponse After the response to t_RV is received from
|
||||
the terminal. The value of |v:termresponse|
|
||||
can be used to do things depending on the
|
||||
terminal version. Note that this event may be
|
||||
triggered halfway through another event
|
||||
(especially if file I/O, a shell command, or
|
||||
anything else that takes time is involved).
|
||||
terminal version. May be triggered halfway
|
||||
through another event (file I/O, a shell
|
||||
command, or anything else that takes time).
|
||||
*TextChanged*
|
||||
TextChanged After a change was made to the text in the
|
||||
current buffer in Normal mode. That is after
|
||||
@@ -1131,6 +1123,12 @@ VimResized After the Vim window was resized, thus 'lines'
|
||||
VimResume After Nvim resumes from |suspend| state.
|
||||
*VimSuspend*
|
||||
VimSuspend Before Nvim enters |suspend| state.
|
||||
*WinClosed*
|
||||
WinClosed After closing a window. <afile> expands to the
|
||||
|window-ID|.
|
||||
After WinLeave.
|
||||
Non-recursive (event cannot trigger itself).
|
||||
See also |ExitPre|, |QuitPre|.
|
||||
*WinEnter*
|
||||
WinEnter After entering another window. Not done for
|
||||
the first window, when Vim has just started.
|
||||
@@ -1148,11 +1146,11 @@ WinLeave Before leaving a window. If the window to be
|
||||
executes the BufLeave autocommands before the
|
||||
WinLeave autocommands (but not for ":new").
|
||||
Not used for ":qa" or ":q" when exiting Vim.
|
||||
|
||||
After WinClosed.
|
||||
*WinNew*
|
||||
WinNew When a new window was created. Not done for
|
||||
the first window, when Vim has just started.
|
||||
Before a WinEnter event.
|
||||
Before WinEnter.
|
||||
|
||||
==============================================================================
|
||||
6. Patterns *autocmd-pattern* *{pat}*
|
||||
|
||||
@@ -159,6 +159,7 @@ Events:
|
||||
|UILeave|
|
||||
|VimResume|
|
||||
|VimSuspend|
|
||||
|WinClosed|
|
||||
|
||||
Functions:
|
||||
|dictwatcheradd()| notifies a callback whenever a |Dict| is modified
|
||||
|
||||
@@ -21,12 +21,12 @@ return {
|
||||
'BufWritePre', -- before writing a buffer
|
||||
'ChanInfo', -- info was received about channel
|
||||
'ChanOpen', -- channel was opened
|
||||
'CmdlineChanged', -- command line was modified
|
||||
'CmdlineEnter', -- after entering cmdline mode
|
||||
'CmdlineLeave', -- before leaving cmdline mode
|
||||
'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
|
||||
@@ -76,8 +76,8 @@ return {
|
||||
'ShellFilterPost', -- after ":1,2!cmd", ":w !cmd", ":r !cmd".
|
||||
'Signal', -- after nvim process received a signal
|
||||
'SourceCmd', -- sourcing a Vim script using command
|
||||
'SourcePre', -- before sourcing a Vim script
|
||||
'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
|
||||
@@ -107,6 +107,7 @@ return {
|
||||
'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
|
||||
@@ -129,5 +130,6 @@ return {
|
||||
TermOpen=true,
|
||||
UIEnter=true,
|
||||
UILeave=true,
|
||||
WinClosed=true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6862,7 +6862,8 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|
||||
|| event == EVENT_SPELLFILEMISSING
|
||||
|| event == EVENT_SYNTAX
|
||||
|| event == EVENT_SIGNAL
|
||||
|| event == EVENT_TABCLOSED) {
|
||||
|| event == EVENT_TABCLOSED
|
||||
|| event == EVENT_WINCLOSED) {
|
||||
fname = vim_strsave(fname);
|
||||
} else {
|
||||
fname = (char_u *)FullName_save((char *)fname, false);
|
||||
|
||||
@@ -2502,9 +2502,10 @@ int win_close(win_T *win, bool free_buf)
|
||||
return FAIL;
|
||||
}
|
||||
win->w_closing = true;
|
||||
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
|
||||
if (!win_valid(win))
|
||||
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, false, curbuf);
|
||||
if (!win_valid(win)) {
|
||||
return FAIL;
|
||||
}
|
||||
win->w_closing = false;
|
||||
if (last_window())
|
||||
return FAIL;
|
||||
@@ -2534,6 +2535,12 @@ int win_close(win_T *win, bool free_buf)
|
||||
}
|
||||
}
|
||||
|
||||
// Fire WinClosed just before starting to free window-related resources.
|
||||
do_autocmd_winclosed(win);
|
||||
// autocmd may have freed the window already.
|
||||
if (!win_valid_any_tab(win)) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Free independent synblock before the buffer is freed. */
|
||||
if (win->w_buffer != NULL)
|
||||
@@ -2576,6 +2583,7 @@ int win_close(win_T *win, bool free_buf)
|
||||
win_close_othertab(win, false, prev_curtab);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// Autocommands may have closed the window already, or closed the only
|
||||
// other window or moved to another tab page.
|
||||
if (!win_valid(win) || (!win->w_floating && last_window())
|
||||
@@ -2585,8 +2593,9 @@ int win_close(win_T *win, bool free_buf)
|
||||
|
||||
// let terminal buffers know that this window dimensions may be ignored
|
||||
win->w_closing = true;
|
||||
/* Free the memory used for the window and get the window that received
|
||||
* the screen space. */
|
||||
|
||||
// Free the memory used for the window and get the window that received
|
||||
// the screen space.
|
||||
wp = win_free_mem(win, &dir, NULL);
|
||||
|
||||
if (help_window) {
|
||||
@@ -2678,6 +2687,20 @@ int win_close(win_T *win, bool free_buf)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void do_autocmd_winclosed(win_T *win)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
static bool recursive = false;
|
||||
if (recursive || !has_event(EVENT_WINCLOSED)) {
|
||||
return;
|
||||
}
|
||||
recursive = true;
|
||||
char_u winid[NUMBUFLEN];
|
||||
vim_snprintf((char *)winid, sizeof(winid), "%i", win->handle);
|
||||
apply_autocmds(EVENT_WINCLOSED, winid, winid, false, win->w_buffer);
|
||||
recursive = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close window "win" in tab page "tp", which is not the current tab page.
|
||||
* This may be the last window in that tab page and result in closing the tab,
|
||||
@@ -2698,6 +2721,13 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
|
||||
return; // window is already being closed
|
||||
}
|
||||
|
||||
// Fire WinClosed just before starting to free window-related resources.
|
||||
do_autocmd_winclosed(win);
|
||||
// autocmd may have freed the window already.
|
||||
if (!win_valid_any_tab(win)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (win->w_buffer != NULL) {
|
||||
// Close the link to the buffer.
|
||||
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
|
||||
local assert_visible = helpers.assert_visible
|
||||
local dedent = helpers.dedent
|
||||
local eq = helpers.eq
|
||||
local eval = helpers.eval
|
||||
@@ -18,26 +19,86 @@ local source = helpers.source
|
||||
describe('autocmd', function()
|
||||
before_each(clear)
|
||||
|
||||
it(':tabnew triggers events in the correct order', function()
|
||||
it(':tabnew, :split, :close events order, <afile>', function()
|
||||
local expected = {
|
||||
'WinLeave',
|
||||
'TabLeave',
|
||||
'WinEnter',
|
||||
'TabNew',
|
||||
'TabEnter',
|
||||
'BufLeave',
|
||||
'BufEnter'
|
||||
{'WinLeave', ''},
|
||||
{'TabLeave', ''},
|
||||
{'WinEnter', ''},
|
||||
{'TabNew', 'testfile1'}, -- :tabnew
|
||||
{'TabEnter', ''},
|
||||
{'BufLeave', ''},
|
||||
{'BufEnter', 'testfile1'}, -- :split
|
||||
{'WinLeave', 'testfile1'},
|
||||
{'WinEnter', 'testfile1'},
|
||||
{'WinLeave', 'testfile1'},
|
||||
{'WinClosed', '1002'}, -- :close, WinClosed <afile> = window-id
|
||||
{'WinEnter', 'testfile1'},
|
||||
{'WinLeave', 'testfile1'}, -- :bdelete
|
||||
{'WinEnter', 'testfile1'},
|
||||
{'BufLeave', 'testfile1'},
|
||||
{'BufEnter', 'testfile2'},
|
||||
{'WinClosed', '1000'},
|
||||
}
|
||||
command('let g:foo = []')
|
||||
command('autocmd BufEnter * :call add(g:foo, "BufEnter")')
|
||||
command('autocmd BufLeave * :call add(g:foo, "BufLeave")')
|
||||
command('autocmd TabEnter * :call add(g:foo, "TabEnter")')
|
||||
command('autocmd TabLeave * :call add(g:foo, "TabLeave")')
|
||||
command('autocmd TabNew * :call add(g:foo, "TabNew")')
|
||||
command('autocmd WinEnter * :call add(g:foo, "WinEnter")')
|
||||
command('autocmd WinLeave * :call add(g:foo, "WinLeave")')
|
||||
command('tabnew')
|
||||
assert.same(expected, eval('g:foo'))
|
||||
command('let g:evs = []')
|
||||
command('autocmd BufEnter * :call add(g:evs, ["BufEnter", expand("<afile>")])')
|
||||
command('autocmd BufLeave * :call add(g:evs, ["BufLeave", expand("<afile>")])')
|
||||
command('autocmd TabEnter * :call add(g:evs, ["TabEnter", expand("<afile>")])')
|
||||
command('autocmd TabLeave * :call add(g:evs, ["TabLeave", expand("<afile>")])')
|
||||
command('autocmd TabNew * :call add(g:evs, ["TabNew", expand("<afile>")])')
|
||||
command('autocmd WinEnter * :call add(g:evs, ["WinEnter", expand("<afile>")])')
|
||||
command('autocmd WinLeave * :call add(g:evs, ["WinLeave", expand("<afile>")])')
|
||||
command('autocmd WinClosed * :call add(g:evs, ["WinClosed", expand("<afile>")])')
|
||||
command('tabnew testfile1')
|
||||
command('split')
|
||||
command('close')
|
||||
command('new testfile2')
|
||||
command('bdelete 1')
|
||||
eq(expected, eval('g:evs'))
|
||||
end)
|
||||
|
||||
it('WinClosed is non-recursive', function()
|
||||
command('let g:triggered = 0')
|
||||
command('autocmd WinClosed * :let g:triggered+=1 | :bdelete 2')
|
||||
command('new testfile2')
|
||||
command('new testfile3')
|
||||
|
||||
-- All 3 buffers are visible.
|
||||
assert_visible(1, true)
|
||||
assert_visible(2, true)
|
||||
assert_visible(3, true)
|
||||
|
||||
-- Trigger WinClosed, which also deletes buffer/window 2.
|
||||
command('bdelete 1')
|
||||
|
||||
-- Buffers 1 and 2 were closed but WinClosed was triggered only once.
|
||||
eq(1, eval('g:triggered'))
|
||||
assert_visible(1, false)
|
||||
assert_visible(2, false)
|
||||
assert_visible(3, true)
|
||||
end)
|
||||
|
||||
it('WinClosed from a different tabpage', function()
|
||||
command('let g:evs = []')
|
||||
command('edit tesfile1')
|
||||
command('autocmd WinClosed <buffer> :call add(g:evs, ["WinClosed", expand("<abuf>")])')
|
||||
local buf1 = eval("bufnr('%')")
|
||||
command('new')
|
||||
local buf2 = eval("bufnr('%')")
|
||||
command('autocmd WinClosed <buffer> :call add(g:evs, ["WinClosed", expand("<abuf>")])'
|
||||
-- Attempt recursion.
|
||||
..' | bdelete '..buf2)
|
||||
command('tabedit testfile2')
|
||||
command('tabedit testfile3')
|
||||
command('bdelete '..buf2)
|
||||
-- Non-recursive: only triggered once.
|
||||
eq({
|
||||
{'WinClosed', '2'},
|
||||
}, eval('g:evs'))
|
||||
command('bdelete '..buf1)
|
||||
eq({
|
||||
{'WinClosed', '2'},
|
||||
{'WinClosed', '1'},
|
||||
}, eval('g:evs'))
|
||||
end)
|
||||
|
||||
it('v:vim_did_enter is 1 after VimEnter', function()
|
||||
|
||||
@@ -597,6 +597,19 @@ function module.assert_alive()
|
||||
assert(2 == module.eval('1+1'), 'crash? request failed')
|
||||
end
|
||||
|
||||
-- Asserts that buffer is loaded and visible in the current tabpage.
|
||||
function module.assert_visible(bufnr, visible)
|
||||
assert(type(visible) == 'boolean')
|
||||
eq(visible, module.bufmeths.is_loaded(bufnr))
|
||||
if visible then
|
||||
assert(-1 ~= module.funcs.bufwinnr(bufnr),
|
||||
'expected buffer to be visible in current tabpage: '..tostring(bufnr))
|
||||
else
|
||||
assert(-1 == module.funcs.bufwinnr(bufnr),
|
||||
'expected buffer NOT visible in current tabpage: '..tostring(bufnr))
|
||||
end
|
||||
end
|
||||
|
||||
local function do_rmdir(path)
|
||||
local mode, errmsg, errcode = lfs.attributes(path, 'mode')
|
||||
if mode == nil then
|
||||
|
||||
Reference in New Issue
Block a user