From 147b03e7d01464030955976e08028bcd337f9ff5 Mon Sep 17 00:00:00 2001 From: Marco Hinz Date: Tue, 22 Nov 2016 14:53:07 +0100 Subject: [PATCH 1/2] Add v:exiting Contains the exit value nvim will use. Before exiting, it is v:null. That way jobs or autocmds (in VimLeavePre or VimLeave) can check if Neovim is about to quit and with what exit value. Closes #4666. --- runtime/doc/eval.txt | 3 +++ src/nvim/eval.c | 6 ++++++ src/nvim/eval.h | 1 + src/nvim/main.c | 2 ++ 4 files changed, 12 insertions(+) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 254cf8b418..cca53db531 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1383,6 +1383,9 @@ 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 The exit value Nvim will use. Before exiting, it is |v:null|. + *v:errmsg* *errmsg-variable* v:errmsg Last given error message. It's allowed to set this variable. Example: > diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 3e4f63884d..8e8d36b442 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -394,6 +394,7 @@ static struct vimvar { VV(VV_TYPE_DICT, "t_dict", VAR_NUMBER, VV_RO), VV(VV_TYPE_FLOAT, "t_float", VAR_NUMBER, VV_RO), VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO), + VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO), }; #undef VV @@ -581,6 +582,7 @@ void eval_init(void) set_vim_var_special(VV_FALSE, kSpecialVarFalse); set_vim_var_special(VV_TRUE, kSpecialVarTrue); set_vim_var_special(VV_NULL, kSpecialVarNull); + set_vim_var_special(VV_EXITING, kSpecialVarNull); set_reg_var(0); // default for v:register is not 0 but '"' } @@ -17763,6 +17765,8 @@ void set_vcount(long count, long count1, int set_prevcount) /// @param[in] val Value to set to. void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val) { + clear_tv(&vimvars[idx].vv_tv); + vimvars[idx].vv_type = VAR_NUMBER; vimvars[idx].vv_nr = val; } @@ -17772,6 +17776,8 @@ void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val) /// @param[in] val Value to set to. void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val) { + clear_tv(&vimvars[idx].vv_tv); + vimvars[idx].vv_type = VAR_SPECIAL; vimvars[idx].vv_special = val; } diff --git a/src/nvim/eval.h b/src/nvim/eval.h index cc7827b801..630e309442 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -134,6 +134,7 @@ typedef enum { VV_TYPE_DICT, VV_TYPE_FLOAT, VV_TYPE_BOOL, + VV_EXITING, } VimVarIndex; /// All recognized msgpack types diff --git a/src/nvim/main.c b/src/nvim/main.c index 1bd622bdba..9b9976ac0a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -557,6 +557,8 @@ void getout(int exitval) if (exmode_active) exitval += ex_exitval; + set_vim_var_nr(VV_EXITING, exitval); + /* Position the cursor on the last screen line, below all the text */ ui_cursor_goto((int)Rows - 1, 0); From df2ffe48ce71ec2653bd74a566a8f4ef585e1d55 Mon Sep 17 00:00:00 2001 From: Marco Hinz Date: Tue, 29 Nov 2016 20:55:41 +0100 Subject: [PATCH 2/2] Tests: add tests for v:exiting --- test/functional/core/exit_spec.lua | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/functional/core/exit_spec.lua diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua new file mode 100644 index 0000000000..3fb39f3e78 --- /dev/null +++ b/test/functional/core/exit_spec.lua @@ -0,0 +1,46 @@ +local helpers = require('test.functional.helpers')(after_each) + +local command = helpers.command +local eval = helpers.eval +local eq, neq = helpers.eq, helpers.neq +local run = helpers.run + +describe('v:exiting', function() + local cid + + before_each(function() + helpers.clear() + cid = helpers.nvim('get_api_info')[1] + end) + + it('defaults to v:null', function() + eq(1, eval('v:exiting is v:null')) + end) + + it('is 0 on normal exit', function() + local function on_setup() + command('autocmd VimLeavePre * call rpcrequest('..cid..', "")') + command('autocmd VimLeave * call rpcrequest('..cid..', "")') + command('quit') + end + local function on_request() + eq(0, eval('v:exiting')) + return '' + end + run(on_request, nil, on_setup) + end) + + it('is non-zero after :cquit', function() + local function on_setup() + command('autocmd VimLeavePre * call rpcrequest('..cid..', "")') + command('autocmd VimLeave * call rpcrequest('..cid..', "")') + command('cquit') + end + local function on_request() + neq(0, eval('v:exiting')) + return '' + end + run(on_request, nil, on_setup) + end) + +end)