Skip to content

Commit 12a96de

Browse files
committed
patch 8.0.1595: no autocommand triggered before exiting
Problem: No autocommand triggered before exiting. Solution: Add the ExitPre autocommand event.
1 parent 435acdb commit 12a96de

File tree

8 files changed

+106
-16
lines changed

8 files changed

+106
-16
lines changed

runtime/doc/autocmd.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ Name triggered by ~
285285
|GUIFailed| after starting the GUI failed
286286
|TermResponse| after the terminal response to |t_RV| is received
287287

288-
|QuitPre| when using `:quit`, before deciding whether to quit
288+
|QuitPre| when using `:quit`, before deciding whether to exit
289+
|ExitPre| when using a command that may make Vim exit
289290
|VimLeavePre| before exiting Vim, before writing the viminfo file
290291
|VimLeave| before exiting Vim, after writing the viminfo file
291292

@@ -651,6 +652,11 @@ DirChanged The working directory has changed in response
651652
"auto" to trigger on 'autochdir'.
652653
"drop" to trigger on editing a file
653654
<afile> is set to the new directory name.
655+
*ExitPre*
656+
ExitPre When using `:quit`, `:wq` in a way it makes
657+
Vim exit, or using `:qall`, just after
658+
|QuitPre|. Can be used to close any
659+
non-essential window.
654660
*FileChangedShell*
655661
FileChangedShell When Vim notices that the modification time of
656662
a file has changed since editing started.
@@ -866,6 +872,7 @@ QuitPre When using `:quit`, `:wq` or `:qall`, before
866872
or quits Vim. Can be used to close any
867873
non-essential window if the current window is
868874
the last ordinary window.
875+
Also see |ExitPre|.
869876
*RemoteReply*
870877
RemoteReply When a reply from a Vim that functions as
871878
server was received |server2client()|. The

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,7 @@ test_arglist \
21552155
test_eval_stuff \
21562156
test_ex_undo \
21572157
test_ex_z \
2158+
test_exit \
21582159
test_exec_while_if \
21592160
test_execute_func \
21602161
test_exists \

src/ex_docmd.c

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7187,8 +7187,35 @@ not_exiting(void)
71877187
settmode(TMODE_RAW);
71887188
}
71897189

7190+
static int
7191+
before_quit_autocmds(win_T *wp, int quit_all, int forceit)
7192+
{
7193+
apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, wp->w_buffer);
7194+
7195+
/* Bail out when autocommands closed the window.
7196+
* Refuse to quit when the buffer in the last window is being closed (can
7197+
* only happen in autocommands). */
7198+
if (!win_valid(wp)
7199+
|| curbuf_locked()
7200+
|| (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0))
7201+
return TRUE;
7202+
7203+
if (quit_all || (check_more(FALSE, forceit) == OK && only_one_window()))
7204+
{
7205+
apply_autocmds(EVENT_EXITPRE, NULL, NULL, FALSE, curbuf);
7206+
/* Refuse to quit when locked or when the buffer in the last window is
7207+
* being closed (can only happen in autocommands). */
7208+
if (curbuf_locked()
7209+
|| (curbuf->b_nwindows == 1 && curbuf->b_locked > 0))
7210+
return TRUE;
7211+
}
7212+
7213+
return FALSE;
7214+
}
7215+
71907216
/*
71917217
* ":quit": quit current window, quit Vim if the last window is closed.
7218+
* ":{nr}quit": quit window {nr}
71927219
*/
71937220
static void
71947221
ex_quit(exarg_T *eap)
@@ -7222,12 +7249,9 @@ ex_quit(exarg_T *eap)
72227249
/* Refuse to quit when locked. */
72237250
if (curbuf_locked())
72247251
return;
7225-
apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, wp->w_buffer);
7226-
/* Bail out when autocommands closed the window.
7227-
* Refuse to quit when the buffer in the last window is being closed (can
7228-
* only happen in autocommands). */
7229-
if (!win_valid(wp)
7230-
|| (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0))
7252+
7253+
/* Trigger QuitPre and maybe ExitPre */
7254+
if (before_quit_autocmds(wp, FALSE, eap->forceit))
72317255
return;
72327256

72337257
#ifdef FEAT_NETBEANS_INTG
@@ -7301,10 +7325,8 @@ ex_quit_all(exarg_T *eap)
73017325
text_locked_msg();
73027326
return;
73037327
}
7304-
apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
7305-
/* Refuse to quit when locked or when the buffer in the last window is
7306-
* being closed (can only happen in autocommands). */
7307-
if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0))
7328+
7329+
if (before_quit_autocmds(curwin, TRUE, eap->forceit))
73087330
return;
73097331

73107332
exiting = TRUE;
@@ -7743,7 +7765,7 @@ ex_stop(exarg_T *eap)
77437765
}
77447766

77457767
/*
7746-
* ":exit", ":xit" and ":wq": Write file and exit Vim.
7768+
* ":exit", ":xit" and ":wq": Write file and quite the current window.
77477769
*/
77487770
static void
77497771
ex_exit(exarg_T *eap)
@@ -7761,10 +7783,8 @@ ex_exit(exarg_T *eap)
77617783
text_locked_msg();
77627784
return;
77637785
}
7764-
apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
7765-
/* Refuse to quit when locked or when the buffer in the last window is
7766-
* being closed (can only happen in autocommands). */
7767-
if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0))
7786+
7787+
if (before_quit_autocmds(curwin, FALSE, eap->forceit))
77687788
return;
77697789

77707790
/*

src/fileio.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7724,6 +7724,7 @@ static struct event_name
77247724
{"CursorMovedI", EVENT_CURSORMOVEDI},
77257725
{"DirChanged", EVENT_DIRCHANGED},
77267726
{"EncodingChanged", EVENT_ENCODINGCHANGED},
7727+
{"ExitPre", EVENT_EXITPRE},
77277728
{"FileEncoding", EVENT_ENCODINGCHANGED},
77287729
{"FileAppendPost", EVENT_FILEAPPENDPOST},
77297730
{"FileAppendPre", EVENT_FILEAPPENDPRE},

src/testdir/Make_all.mak

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ NEW_TESTS = test_arabic.res \
9797
test_exec_while_if.res \
9898
test_exists.res \
9999
test_exists_autocmd.res \
100+
test_exit.res \
100101
test_farsi.res \
101102
test_file_size.res \
102103
test_find_complete.res \

src/testdir/test_exit.vim

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
" Tests for exiting Vim.
2+
3+
source shared.vim
4+
5+
func Test_exiting()
6+
let after = [
7+
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
8+
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
9+
\ 'quit',
10+
\ ]
11+
if RunVim([], after, '')
12+
call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
13+
endif
14+
call delete('Xtestout')
15+
16+
let after = [
17+
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
18+
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
19+
\ 'help',
20+
\ 'wincmd w',
21+
\ 'quit',
22+
\ ]
23+
if RunVim([], after, '')
24+
call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
25+
endif
26+
call delete('Xtestout')
27+
28+
let after = [
29+
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
30+
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
31+
\ 'split',
32+
\ 'new',
33+
\ 'qall',
34+
\ ]
35+
if RunVim([], after, '')
36+
call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
37+
endif
38+
call delete('Xtestout')
39+
40+
let after = [
41+
\ 'au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")',
42+
\ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
43+
\ 'augroup nasty',
44+
\ ' au ExitPre * split',
45+
\ 'augroup END',
46+
\ 'quit',
47+
\ 'augroup nasty',
48+
\ ' au! ExitPre',
49+
\ 'augroup END',
50+
\ 'quit',
51+
\ ]
52+
if RunVim([], after, '')
53+
call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'],
54+
\ readfile('Xtestout'))
55+
endif
56+
call delete('Xtestout')
57+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,8 @@ static char *(features[]) =
766766

767767
static int included_patches[] =
768768
{ /* Add new patch number below this line */
769+
/**/
770+
1595,
769771
/**/
770772
1594,
771773
/**/

src/vim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,7 @@ enum auto_event
12771277
EVENT_COLORSCHEME, /* after loading a colorscheme */
12781278
EVENT_COMPLETEDONE, /* after finishing insert complete */
12791279
EVENT_DIRCHANGED, /* after changing directory as a result of user cmd */
1280+
EVENT_EXITPRE, /* before exiting */
12801281
EVENT_FILEAPPENDPOST, /* after appending to a file */
12811282
EVENT_FILEAPPENDPRE, /* before appending to a file */
12821283
EVENT_FILEAPPENDCMD, /* append to a file using command */

0 commit comments

Comments
 (0)