diff options
author | Jan Edmund Lazo <janedmundlazo@hotmail.com> | 2018-09-04 21:57:45 -0400 |
---|---|---|
committer | Jan Edmund Lazo <janedmundlazo@hotmail.com> | 2018-09-04 22:40:48 -0400 |
commit | 958467456930badcaf218b6fac56b105ac7655c8 (patch) | |
tree | a457601f6ac69690b9f894338ba5dfdef4c8581b | |
parent | b6e83ba28469345ee145ab6da2c4ef7f3285d726 (diff) | |
download | rneovim-958467456930badcaf218b6fac56b105ac7655c8.tar.gz rneovim-958467456930badcaf218b6fac56b105ac7655c8.tar.bz2 rneovim-958467456930badcaf218b6fac56b105ac7655c8.zip |
vim-patch:8.0.1595: no autocommand triggered before exiting
Problem: No autocommand triggered before exiting.
Solution: Add the ExitPre autocommand event.
https://github.com/vim/vim/commit/12a96de430779b88795fac87a2be666d9f661d1e
-rw-r--r-- | runtime/doc/autocmd.txt | 9 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 1 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 56 | ||||
-rw-r--r-- | src/nvim/testdir/test_exit.vim | 57 |
4 files changed, 103 insertions, 20 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 24bcb13e6e..2f9d8aa7f7 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -274,7 +274,8 @@ Name triggered by ~ |GUIEnter| after starting the GUI successfully |GUIFailed| after starting the GUI failed |TermResponse| after the terminal response to |t_RV| is received -|QuitPre| when using `:quit`, before deciding whether to quit +|QuitPre| when using `:quit`, before deciding whether to exit +|ExitPre| when using a command that may make Vim exit |VimLeavePre| before exiting Nvim, before writing the shada file |VimLeave| before exiting Nvim, after writing the shada file |VimResume| after Nvim is resumed @@ -646,6 +647,11 @@ FileChangedRO Before making the first change to a read-only *E881* If the number of lines changes saving for undo may fail and the change will be aborted. + *ExitPre* +ExitPre When using `:quit`, `:wq` in a way it makes + Vim exit, or using `:qall`, just after + |QuitPre|. Can be used to close any + non-essential window. *FileChangedShell* FileChangedShell When Vim notices that the modification time of a file has changed since editing started. @@ -862,6 +868,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|. *RemoteReply* RemoteReply When a reply from a Vim that functions as server was received |server2client()|. The diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index d0a3f38c6b..d002aaae43 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -34,6 +34,7 @@ return { 'CursorMovedI', -- cursor was moved in Insert mode 'DirChanged', -- directory changed '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 diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 71d411761b..0337b37cb2 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5964,9 +5964,35 @@ void not_exiting(void) exiting = FALSE; } -/* - * ":quit": quit current window, quit Vim if the last window is closed. - */ +static bool before_quit_autocmds(win_T *wp, bool quit_all, int forceit) +{ + apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, wp->w_buffer); + + // Bail out when autocommands closed the window. + // Refuse to quit when the buffer in the last window is being closed (can + // only happen in autocommands). + if (!win_valid(wp) + || curbuf_locked() + || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) { + return true; + } + + if (quit_all + || (check_more(false, forceit) == OK && only_one_window())) { + apply_autocmds(EVENT_EXITPRE, NULL, NULL, false, curbuf); + // Refuse to quit when locked or when the buffer in the last window is + // being closed (can only happen in autocommands). + if (curbuf_locked() + || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) { + return true; + } + } + + return false; +} + +// ":quit": quit current window, quit Vim if the last window is closed. +// ":{nr}quit": quit window {nr} static void ex_quit(exarg_T *eap) { if (cmdwin_type != 0) { @@ -5996,11 +6022,9 @@ static void ex_quit(exarg_T *eap) if (curbuf_locked()) { return; } - apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, wp->w_buffer); - // Refuse to quit when locked or when the buffer in the last window is - // being closed (can only happen in autocommands). - if (!win_valid(wp) - || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) { + + // Trigger QuitPre and maybe ExitPre + if (before_quit_autocmds(wp, false, eap->forceit)) { return; } @@ -6058,10 +6082,8 @@ static void ex_quit_all(exarg_T *eap) text_locked_msg(); return; } - apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, curbuf); - // Refuse to quit when locked or when the buffer in the last window is - // being closed (can only happen in autocommands). - if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) { + + if (before_quit_autocmds(curwin, true, eap->forceit)) { return; } @@ -6347,9 +6369,7 @@ static void ex_stop(exarg_T *eap) } } -/* - * ":exit", ":xit" and ":wq": Write file and exit Vim. - */ +// ":exit", ":xit" and ":wq": Write file and quite the current window. static void ex_exit(exarg_T *eap) { if (cmdwin_type != 0) { @@ -6361,10 +6381,8 @@ static void ex_exit(exarg_T *eap) text_locked_msg(); return; } - apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, curbuf); - // Refuse to quit when locked or when the buffer in the last window is - // being closed (can only happen in autocommands). - if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) { + + if (before_quit_autocmds(curwin, false, eap->forceit)) { return; } diff --git a/src/nvim/testdir/test_exit.vim b/src/nvim/testdir/test_exit.vim new file mode 100644 index 0000000000..8f02fd29e3 --- /dev/null +++ b/src/nvim/testdir/test_exit.vim @@ -0,0 +1,57 @@ +" Tests for exiting Vim. + +source shared.vim + +func Test_exiting() + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'quit', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) + endif + call delete('Xtestout') + + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'help', + \ 'wincmd w', + \ 'quit', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) + endif + call delete('Xtestout') + + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'split', + \ 'new', + \ 'qall', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) + endif + call delete('Xtestout') + + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'augroup nasty', + \ ' au ExitPre * split', + \ 'augroup END', + \ 'quit', + \ 'augroup nasty', + \ ' au! ExitPre', + \ 'augroup END', + \ 'quit', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'], + \ readfile('Xtestout')) + endif + call delete('Xtestout') +endfunc |