]> granicus.if.org Git - vim/commitdiff
patch 8.2.2070: can't get the exit value in VimLeave(Pre) autocommands v8.2.2070
authorBram Moolenaar <Bram@vim.org>
Mon, 30 Nov 2020 16:42:10 +0000 (17:42 +0100)
committerBram Moolenaar <Bram@vim.org>
Mon, 30 Nov 2020 16:42:10 +0000 (17:42 +0100)
Problem:    Can't get the exit value in VimLeave or VimLeavePre autocommands.
Solution:   Add v:exiting like in Neovim. (Yegappan Lakshmanan, closes #7395)

runtime/doc/autocmd.txt
runtime/doc/eval.txt
src/evalvars.c
src/main.c
src/testdir/test_exit.vim
src/version.c
src/vim.h

index c35e89907151e4e1448082c412b06cc46bd7f3e3..ea9a220cdbc675e9f0ab2b087b4735d0f733774d 100644 (file)
@@ -1214,6 +1214,7 @@ VimLeave                  Before exiting Vim, just after writing the
                                To detect an abnormal exit use |v:dying|.
                                When v:dying is 2 or more this event is not
                                triggered.
+                               To get the exit code use |v:exiting|.
                                                        *VimLeavePre*
 VimLeavePre                    Before exiting Vim, just before writing the
                                .viminfo file.  This is executed only once,
@@ -1224,6 +1225,7 @@ VimLeavePre                       Before exiting Vim, just before writing the
 <                              To detect an abnormal exit use |v:dying|.
                                When v:dying is 2 or more this event is not
                                triggered.
+                               To get the exit code use |v:exiting|.
                                                        *VimResized*
 VimResized                     After the Vim window was resized, thus 'lines'
                                and/or 'columns' changed.  Not when starting
index 72a66d548ca282aa0de136687a2904f4579f139a..6f594ab81bf5291e30705d7a283b6d9bab515101 100644 (file)
@@ -1850,6 +1850,13 @@ v:dying          Normally zero.  When a deadly signal is caught it's set to
 <              Note: if another deadly signal is caught when v:dying is one,
                VimLeave autocommands will not be executed.
 
+                                       *v:exiting* *exiting-variable*
+v:exiting      Vim exit code.  Normally zero, non-zero when something went
+               wrong.  The value is v:null before invoking the |VimLeavePre|
+               and |VimLeave| autocmds.  See |:q|, |:x| and |:cquit|.
+               Example: >
+                       :au VimLeave * echo "Exit value is " .. v:exiting
+<
                                        *v:echospace* *echospace-variable*
 v:echospace    Number of screen cells that can be used for an `:echo` message
                in the last screen line before causing the |hit-enter-prompt|.
index 75893bb27cc4d5640f3b2f5a05d40b9c4e11bfdf..dea56be75facf92233b30dc80ba5a23e40abbe03 100644 (file)
@@ -146,6 +146,7 @@ static struct vimvar
     {VV_NAME("echospace",       VAR_NUMBER), VV_RO},
     {VV_NAME("argv",            VAR_LIST), VV_RO},
     {VV_NAME("collate",                 VAR_STRING), VV_RO},
+    {VV_NAME("exiting",                 VAR_SPECIAL), VV_RO},
 };
 
 // shorthand
@@ -218,6 +219,7 @@ evalvars_init(void)
 
     set_vim_var_nr(VV_SEARCHFORWARD, 1L);
     set_vim_var_nr(VV_HLSEARCH, 1L);
+    set_vim_var_nr(VV_EXITING, VVAL_NULL);
     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
     set_vim_var_list(VV_ERRORS, list_alloc());
     set_vim_var_dict(VV_EVENT, dict_alloc_lock(VAR_FIXED));
index e3ce9e4a6069c3cd49f83c9212d2a4ca905c9b81..1b7811a6707d93a72f068433d2e24773bdabe377 100644 (file)
@@ -1505,7 +1505,8 @@ getout_preserve_modified(int exitval)
 
 
 /*
- * Exit properly.
+ * Exit properly.  This is the only way to exit Vim after startup has
+ * succeeded.  We are certain to exit here, no way to abort it.
  */
     void
 getout(int exitval)
@@ -1521,6 +1522,11 @@ getout(int exitval)
     if (exmode_active)
        exitval += ex_exitval;
 
+#ifdef FEAT_EVAL
+    set_vim_var_type(VV_EXITING, VAR_NUMBER);
+    set_vim_var_nr(VV_EXITING, exitval);
+#endif
+
     // Position the cursor on the last screen line, below all the text
 #ifdef FEAT_GUI
     if (!gui.in_use)
index 2b29c3766dcd34ca36d66c20fe95a18b924b8e28..93b8f5171a4a904c4a7d6b0dddc016ee0a635896 100644 (file)
@@ -82,4 +82,31 @@ func Test_exiting()
   call delete('Xtestout')
 endfunc
 
+" Test for getting the Vim exit code from v:exiting
+func Test_exit_code()
+  call assert_equal(v:null, v:exiting)
+
+  let before =<< trim [CODE]
+    au QuitPre * call writefile(['qp = ' .. v:exiting], 'Xtestout', 'a')
+    au ExitPre * call writefile(['ep = ' .. v:exiting], 'Xtestout', 'a')
+    au VimLeavePre * call writefile(['lp = ' .. v:exiting], 'Xtestout', 'a')
+    au VimLeave * call writefile(['l = ' .. v:exiting], 'Xtestout', 'a')
+  [CODE]
+
+  if RunVim(before, ['quit'], '')
+    call assert_equal(['qp = v:null', 'ep = v:null', 'lp = 0', 'l = 0'], readfile('Xtestout'))
+  endif
+  call delete('Xtestout')
+
+  if RunVim(before, ['cquit'], '')
+    call assert_equal(['lp = 1', 'l = 1'], readfile('Xtestout'))
+  endif
+  call delete('Xtestout')
+
+  if RunVim(before, ['cquit 4'], '')
+    call assert_equal(['lp = 4', 'l = 4'], readfile('Xtestout'))
+  endif
+  call delete('Xtestout')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 6e9dfbcd9ca9412659d05f88bd0df9d5af31f033..4eb7f4b5910b0b8bcce46aa9c16b7ca0b285cca0 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2070,
 /**/
     2069,
 /**/
index 6dcc509aa15c36a245b281733410590629c247ff..eda07348c06e52e9e325fd7a50057e50b178def4 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -1996,7 +1996,8 @@ typedef int sock_T;
 #define VV_ECHOSPACE   93
 #define VV_ARGV                94
 #define VV_COLLATE      95
-#define VV_LEN         96      // number of v: vars
+#define VV_EXITING     96
+#define VV_LEN         97      // number of v: vars
 
 // used for v_number in VAR_BOOL and VAR_SPECIAL
 #define VVAL_FALSE     0L      // VAR_BOOL