From 12e8db38471eacd12da28d42103d67619ea9af0f Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Sat, 18 Jul 2026 03:07:14 -0500 Subject: [PATCH] fix(restart): distinguish v:exitreason for :restart! #40801 --- runtime/doc/vvars.txt | 1 + runtime/lua/vim/_meta/vvars.gen.lua | 1 + src/nvim/ex_docmd.c | 2 +- src/nvim/vvars.lua | 1 + test/functional/terminal/tui_spec.lua | 21 ++++++++++++++++----- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/runtime/doc/vvars.txt b/runtime/doc/vvars.txt index 58d5c5d4dd..4e0ef4654b 100644 --- a/runtime/doc/vvars.txt +++ b/runtime/doc/vvars.txt @@ -242,6 +242,7 @@ v:exitreason - "" Not exiting, or exit was canceled. - "quit" |:quit|, |:qall|, |:wq|, |ZZ|, |ZQ|, etc. - "restart" |:restart|, |ZR|. + - "restart!" |:restart!|, |[count]||ZR|. Example: >vim autocmd ExitPre * if v:exitreason ==# 'restart' | echomsg 'restarting' | endif diff --git a/runtime/lua/vim/_meta/vvars.gen.lua b/runtime/lua/vim/_meta/vvars.gen.lua index 0154045f20..7969239afe 100644 --- a/runtime/lua/vim/_meta/vvars.gen.lua +++ b/runtime/lua/vim/_meta/vvars.gen.lua @@ -256,6 +256,7 @@ vim.v.exiting = ... --- - "" Not exiting, or exit was canceled. --- - "quit" `:quit`, `:qall`, `:wq`, `ZZ`, `ZQ`, etc. --- - "restart" `:restart`, `ZR`. +--- - "restart!" `:restart!`, `[count]``ZR`. --- --- Example: --- diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 15f3824f5b..f34551a299 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5172,7 +5172,7 @@ static void ex_restart(exarg_T *eap) ui_flush(); xfree(listen_addr); - set_vim_var_string(VV_EXITREASON, S_LEN("restart")); + set_vim_var_string(VV_EXITREASON, startreason, -1); char *quit_cmd_copy = NULL; diff --git a/src/nvim/vvars.lua b/src/nvim/vvars.lua index d57c4b4596..e185c2a6ae 100644 --- a/src/nvim/vvars.lua +++ b/src/nvim/vvars.lua @@ -282,6 +282,7 @@ M.vars = { - "" Not exiting, or exit was canceled. - "quit" |:quit|, |:qall|, |:wq|, |ZZ|, |ZQ|, etc. - "restart" |:restart|, |ZR|. + - "restart!" |:restart!|, |[count]||ZR|. Example: >vim autocmd ExitPre * if v:exitreason ==# 'restart' | echomsg 'restarting' | endif diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index b7672e3330..c493a10c31 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -498,7 +498,8 @@ describe('TUI :restart', function() end) local function assert_exitreason(expected) - local default = 'QuitPre:restart\nExitPre:restart\nVimLeavePre:restart\nVimLeave:restart\n' + local default = + 'QuitPre:restart!\nExitPre:restart!\nVimLeavePre:restart!\nVimLeave:restart!\n' eq(expected or default, t.read_file(eventlog)) os.remove(eventlog) end @@ -565,6 +566,13 @@ describe('TUI :restart', function() {5:-- TERMINAL --} | ]] + tt.feed_data(':set nomodified\013') + tt.feed_data(':restart\013') + screen:expect(s0) + assert_new_pid() + assert_exitreason('QuitPre:restart\nExitPre:restart\nVimLeavePre:restart\nVimLeave:restart\n') + assert_termguicolors_and_no_gui_running() + tt.feed_data(':set nomodified\013') -- Command is run on new server. tt.feed_data(":restart! put ='Hello1'\013") @@ -630,7 +638,7 @@ describe('TUI :restart', function() tt.feed_data('C\013') screen:expect({ any = vim.pesc('[No Name]') }) -- Failed/cancelled restarts still fire QuitPre/ExitPre (but not VimLeave[Pre]). - assert_exitreason('QuitPre:restart\nExitPre:restart\n') + assert_exitreason('QuitPre:restart!\nExitPre:restart!\n') -- Check :restart! respects 'confirm' option. tt.feed_data(':set confirm\013') @@ -640,7 +648,7 @@ describe('TUI :restart', function() screen:expect({ any = vim.pesc('[No Name]') }) tt.feed_data(':set noconfirm\013') -- Failed/cancelled restarts still fire QuitPre/ExitPre (but not VimLeave[Pre]). - assert_exitreason('QuitPre:restart\nExitPre:restart\n') + assert_exitreason('QuitPre:restart!\nExitPre:restart!\n') -- Check ":confirm restart! " on a modified buffer. tt.feed_data(":confirm restart! put ='Hello3'\013") @@ -657,10 +665,13 @@ describe('TUI :restart', function() -- Check ":restart[!]" on a modified buffer. tt.feed_data('ithis will be removed\027') - for _, cmd in ipairs({ ':restart', ':restart!' }) do + for cmd, exitreason in pairs({ + [':restart'] = 'restart', + [':restart!'] = 'restart!', + }) do tt.feed_data(cmd .. '\013') screen:expect({ any = vim.pesc('Vim(qall):E37: No write since last change') }) - assert_exitreason('QuitPre:restart\nExitPre:restart\n') + assert_exitreason(('QuitPre:%s\nExitPre:%s\n'):format(exitreason, exitreason)) end -- Check ":restart! +qall!" on a modified buffer.