commit b4e602dde544d2b18bc7813415565fbe6ab1041b
parent 933b99a2b1c95c877b67eb4e0d35fd8dd6b0d532
Author: zeertzjq <zeertzjq@outlook.com>
Date: Tue, 20 Jan 2026 06:24:22 +0800
vim-patch:9.1.2095: :wqall! doesn't quit when using :quit in BufWritePost
Problem: :wqall! doesn't quit when using :quit in BufWritePost
(after 8.0.1190).
Solution: Restore old value of "exiting" when calling not_exiting()
instead of always resetting it to FALSE (zeertzjq).
related: vim/vim#2205
closes: vim/vim#19212
https://github.com/vim/vim/commit/e803ad1c56f50a4ffdfe8beb478795aa5201475e
Diffstat:
3 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
@@ -2095,6 +2095,7 @@ void do_wqall(exarg_T *eap)
{
int error = 0;
int save_forceit = eap->forceit;
+ bool save_exiting = exiting;
if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall) {
if (before_quit_all(eap) == FAIL) {
@@ -2147,7 +2148,7 @@ void do_wqall(exarg_T *eap)
if (!error) {
getout(0); // exit Vim
}
- not_exiting();
+ not_exiting(save_exiting);
}
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
@@ -4779,9 +4779,9 @@ static void ex_highlight(exarg_T *eap)
/// Call this function if we thought we were going to exit, but we won't
/// (because of an error). May need to restore the terminal mode.
-void not_exiting(void)
+void not_exiting(bool save_exiting)
{
- exiting = false;
+ exiting = save_exiting;
}
/// Call this function if we thought we were going to restart, but we won't
@@ -4858,6 +4858,7 @@ static void ex_quit(exarg_T *eap)
return;
}
+ bool save_exiting = exiting;
// If there is only one relevant window we will exit.
if (check_more(false, eap->forceit) == OK && only_one_window()) {
exiting = true;
@@ -4868,7 +4869,7 @@ static void ex_quit(exarg_T *eap)
| CCGD_EXCMD))
|| check_more(true, eap->forceit) == FAIL
|| (only_one_window() && check_changed_any(eap->forceit, true))) {
- not_exiting();
+ not_exiting(save_exiting);
} else {
// quit last window
// Note: only_one_window() returns true, even so a help window is
@@ -4879,7 +4880,7 @@ static void ex_quit(exarg_T *eap)
if (only_one_window() && (ONE_WINDOW || eap->addr_count == 0)) {
getout(0);
}
- not_exiting();
+ not_exiting(save_exiting);
// close window; may free buffer
win_close(wp, !buf_hide(wp->w_buffer) || eap->forceit, eap->forceit);
}
@@ -4925,12 +4926,12 @@ static void ex_quitall(exarg_T *eap)
if (before_quit_all(eap) == FAIL) {
return;
}
+ bool save_exiting = exiting;
exiting = true;
- if (!eap->forceit && check_changed_any(false, false)) {
- not_exiting();
- return;
+ if (eap->forceit || !check_changed_any(false, false)) {
+ getout(0);
}
- getout(0);
+ not_exiting(save_exiting);
}
/// ":restart": restart the Nvim server (using ":qall!").
@@ -5292,6 +5293,7 @@ static void ex_exit(exarg_T *eap)
return;
}
+ bool save_exiting = exiting;
// we plan to exit if there is only one relevant window
if (check_more(false, eap->forceit) == OK && only_one_window()) {
exiting = true;
@@ -5303,13 +5305,13 @@ static void ex_exit(exarg_T *eap)
|| before_quit_autocmds(curwin, false, eap->forceit)
|| check_more(true, eap->forceit) == FAIL
|| (only_one_window() && check_changed_any(eap->forceit, false))) {
- not_exiting();
+ not_exiting(save_exiting);
} else {
if (only_one_window()) {
// quit last window, exit Vim
getout(0);
}
- not_exiting();
+ not_exiting(save_exiting);
// Quit current window, may free the buffer.
win_close(curwin, !buf_hide(curwin->w_buffer), eap->forceit);
}
diff --git a/test/old/testdir/test_exit.vim b/test/old/testdir/test_exit.vim
@@ -93,6 +93,20 @@ func Test_exiting()
call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
endif
call delete('Xtestout')
+
+ " Test using :quit in BufWritePost during :wqall
+ let after =<< trim [CODE]
+ botright new Xwritebuf
+ call setline(1, 'SHOULD BE WRITTEN')
+ autocmd BufWritePost Xwritebuf 1quit
+ wqall
+ call setline(1, 'NOT REACHED') | write | qall
+ [CODE]
+
+ if RunVim([], after, '')
+ call assert_equal(['SHOULD BE WRITTEN'], readfile('Xwritebuf'))
+ endif
+ call delete('Xwritebuf')
endfunc
" Test for getting the Vim exit code from v:exiting