To: vim_dev@googlegroups.com Subject: Patch 8.0.1595 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1595 Problem: No autocommand triggered before exiting. Solution: Add the ExitPre autocommand event. Files: src/ex_docmd.c, src/fileio.c, src/vim.h, src/testdir/test_exit.vim, src/Makefile, src/testdir/Make_all.mak, runtime/doc/autocmd.txt *** ../vim-8.0.1594/src/ex_docmd.c 2018-03-09 21:33:29.244607400 +0100 --- src/ex_docmd.c 2018-03-11 14:12:58.927695531 +0100 *************** *** 7187,7194 **** --- 7187,7221 ---- settmode(TMODE_RAW); } + static int + before_quit_autocmds(win_T *wp, int 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) *************** *** 7222,7233 **** /* Refuse to quit when locked. */ if (curbuf_locked()) return; ! 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) ! || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) return; #ifdef FEAT_NETBEANS_INTG --- 7249,7257 ---- /* Refuse to quit when locked. */ if (curbuf_locked()) return; ! ! /* Trigger QuitPre and maybe ExitPre */ ! if (before_quit_autocmds(wp, FALSE, eap->forceit)) return; #ifdef FEAT_NETBEANS_INTG *************** *** 7301,7310 **** 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)) return; exiting = TRUE; --- 7325,7332 ---- text_locked_msg(); return; } ! ! if (before_quit_autocmds(curwin, TRUE, eap->forceit)) return; exiting = TRUE; *************** *** 7743,7749 **** } /* ! * ":exit", ":xit" and ":wq": Write file and exit Vim. */ static void ex_exit(exarg_T *eap) --- 7765,7771 ---- } /* ! * ":exit", ":xit" and ":wq": Write file and quite the current window. */ static void ex_exit(exarg_T *eap) *************** *** 7761,7770 **** 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)) return; /* --- 7783,7790 ---- text_locked_msg(); return; } ! ! if (before_quit_autocmds(curwin, FALSE, eap->forceit)) return; /* *** ../vim-8.0.1594/src/fileio.c 2018-03-04 18:07:04.256592423 +0100 --- src/fileio.c 2018-03-11 13:49:57.923902785 +0100 *************** *** 7724,7729 **** --- 7724,7730 ---- {"CursorMovedI", EVENT_CURSORMOVEDI}, {"DirChanged", EVENT_DIRCHANGED}, {"EncodingChanged", EVENT_ENCODINGCHANGED}, + {"ExitPre", EVENT_EXITPRE}, {"FileEncoding", EVENT_ENCODINGCHANGED}, {"FileAppendPost", EVENT_FILEAPPENDPOST}, {"FileAppendPre", EVENT_FILEAPPENDPRE}, *** ../vim-8.0.1594/src/vim.h 2018-03-06 18:59:53.489546080 +0100 --- src/vim.h 2018-03-11 13:51:04.039510486 +0100 *************** *** 1277,1282 **** --- 1277,1283 ---- EVENT_COLORSCHEME, /* after loading a colorscheme */ EVENT_COMPLETEDONE, /* after finishing insert complete */ EVENT_DIRCHANGED, /* after changing directory as a result of user cmd */ + EVENT_EXITPRE, /* before exiting */ EVENT_FILEAPPENDPOST, /* after appending to a file */ EVENT_FILEAPPENDPRE, /* before appending to a file */ EVENT_FILEAPPENDCMD, /* append to a file using command */ *** ../vim-8.0.1594/src/testdir/test_exit.vim 2018-03-11 14:42:26.485059006 +0100 --- src/testdir/test_exit.vim 2018-03-11 14:36:34.999178507 +0100 *************** *** 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 *** ../vim-8.0.1594/src/Makefile 2018-02-27 17:25:48.016151913 +0100 --- src/Makefile 2018-03-11 14:24:09.015677335 +0100 *************** *** 2155,2160 **** --- 2155,2161 ---- test_eval_stuff \ test_ex_undo \ test_ex_z \ + test_exit \ test_exec_while_if \ test_execute_func \ test_exists \ *** ../vim-8.0.1594/src/testdir/Make_all.mak 2018-02-13 13:59:42.191667272 +0100 --- src/testdir/Make_all.mak 2018-03-11 14:25:08.351319473 +0100 *************** *** 97,102 **** --- 97,103 ---- test_exec_while_if.res \ test_exists.res \ test_exists_autocmd.res \ + test_exit.res \ test_farsi.res \ test_file_size.res \ test_find_complete.res \ *** ../vim-8.0.1594/runtime/doc/autocmd.txt 2018-02-10 18:15:00.750098838 +0100 --- runtime/doc/autocmd.txt 2018-03-11 14:08:53.885154286 +0100 *************** *** 270,276 **** |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 |VimLeavePre| before exiting Vim, before writing the viminfo file |VimLeave| before exiting Vim, after writing the viminfo file --- 285,292 ---- |GUIFailed| after starting the GUI failed |TermResponse| after the terminal response to |t_RV| is received ! |QuitPre| when using `:quit`, before deciding whether to exit ! |ExitPre| when using a command that may make Vim exit |VimLeavePre| before exiting Vim, before writing the viminfo file |VimLeave| before exiting Vim, after writing the viminfo file *************** *** 632,637 **** --- 652,662 ---- "auto" to trigger on 'autochdir'. "drop" to trigger on editing a file is set to the new directory name. + *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. *************** *** 846,851 **** --- 872,878 ---- 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 *** ../vim-8.0.1594/src/version.c 2018-03-10 20:51:21.262808421 +0100 --- src/version.c 2018-03-11 14:36:51.015081926 +0100 *************** *** 768,769 **** --- 768,771 ---- { /* Add new patch number below this line */ + /**/ + 1595, /**/ -- For society, it's probably a good thing that engineers value function over appearance. For example, you wouldn't want engineers to build nuclear power plants that only _look_ like they would keep all the radiation inside. (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///