commit 681d00654998baf2a743602e513062cf876f107b
parent e002e4d7fceeac91adb57bf00bb23e383447c99f
Author: zeertzjq <zeertzjq@outlook.com>
Date: Fri, 9 Jan 2026 07:36:47 +0800
vim-patch:9.1.2066: :wqall! doesn't close a terminal like :qall! does (#37314)
Problem: :wqall! doesn't close a terminal buffer like :qall! does
(after 8.0.1525).
Solution: Check eap->forceit (zeertzjq).
Ref: https://github.com/vim/vim/issues/2654#issuecomment-366803932
related: vim/vim#2654
related: neovim/neovim#14061
closes: vim/vim#19129
https://github.com/vim/vim/commit/d8558fdf4f2758163218289637e82c3ae2d617ec
Diffstat:
4 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
@@ -1363,7 +1363,7 @@ static int do_buffer_ext(int action, int start, int dir, int count, int flags)
return FAIL;
}
} else {
- semsg(_("E89: No write since last change for buffer %d (add ! to override)"),
+ semsg(_(e_no_write_since_last_change_for_buffer_nr_add_bang_to_override),
buf->b_fnum);
return FAIL;
}
@@ -1819,13 +1819,24 @@ void do_autochdir(void)
}
}
+void no_write_message_buf(buf_T *buf)
+{
+ if (buf->terminal
+ && channel_job_running((uint64_t)buf->b_p_channel)) {
+ emsg(_(e_job_still_running_add_bang_to_end_the_job));
+ } else {
+ semsg(_(e_no_write_since_last_change_for_buffer_nr_add_bang_to_override),
+ buf->b_fnum);
+ }
+}
+
void no_write_message(void)
{
if (curbuf->terminal
&& channel_job_running((uint64_t)curbuf->b_p_channel)) {
- emsg(_("E948: Job still running (add ! to end the job)"));
+ emsg(_(e_job_still_running_add_bang_to_end_the_job));
} else {
- emsg(_("E37: No write since last change (add ! to override)"));
+ emsg(_(e_no_write_since_last_change_add_bang_to_override));
}
}
@@ -1834,9 +1845,9 @@ void no_write_message_nobang(const buf_T *const buf)
{
if (buf->terminal
&& channel_job_running((uint64_t)buf->b_p_channel)) {
- emsg(_("E948: Job still running"));
+ emsg(_(e_job_still_running));
} else {
- emsg(_("E37: No write since last change"));
+ emsg(_(e_no_write_since_last_change));
}
}
diff --git a/src/nvim/errors.h b/src/nvim/errors.h
@@ -131,9 +131,14 @@ EXTERN const char e_missingparen[] INIT(= N_("E107: Missing parentheses: %s"));
EXTERN const char e_empty_buffer[] INIT(= N_("E749: Empty buffer"));
EXTERN const char e_nobufnr[] INIT(= N_("E86: Buffer %" PRId64 " does not exist"));
+EXTERN const char e_no_write_since_last_change[] INIT(= N_("E37: No write since last change"));
+EXTERN const char e_no_write_since_last_change_add_bang_to_override[] INIT(= N_("E37: No write since last change (add ! to override)"));
+EXTERN const char e_no_write_since_last_change_for_buffer_nr_add_bang_to_override[] INIT(= N_("E89: No write since last change for buffer %d (add ! to override)"));
EXTERN const char e_buffer_nr_not_found[] INIT(= N_("E92: Buffer %d not found"));
EXTERN const char e_unknown_function_str[] INIT(= N_("E117: Unknown function: %s"));
EXTERN const char e_str_not_inside_function[] INIT(= N_("E193: %s not inside a function"));
+EXTERN const char e_job_still_running[] INIT(= N_("E948: Job still running"));
+EXTERN const char e_job_still_running_add_bang_to_end_the_job[] INIT(= N_("E948: Job still running (add ! to end the job)"));
EXTERN const char e_invalpat[] INIT(= N_("E682: Invalid search pattern or delimiter"));
EXTERN const char e_bufloaded[] INIT(= N_("E139: File is loaded in another buffer"));
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
@@ -2104,10 +2104,10 @@ void do_wqall(exarg_T *eap)
}
FOR_ALL_BUFFERS(buf) {
- if (exiting
+ if (exiting && !eap->forceit
&& buf->terminal
&& channel_job_running((uint64_t)buf->b_p_channel)) {
- no_write_message_nobang(buf);
+ no_write_message_buf(buf);
error++;
} else if (!bufIsChanged(buf) || bt_dontwrite(buf)) {
continue;
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
@@ -243,7 +243,7 @@ describe(':terminal buffer', function()
it('requires bang (!) to close a running job #15402', function()
skip(is_os('win'), 'Test freezes the CI and makes it time out')
- eq('Vim(wqall):E948: Job still running', exc_exec('wqall'))
+ eq('Vim(wqall):E948: Job still running (add ! to end the job)', exc_exec('wqall'))
for _, cmd in ipairs({ 'bdelete', '%bdelete', 'bwipeout', 'bunload' }) do
matches(
'^Vim%('
@@ -257,6 +257,10 @@ describe(':terminal buffer', function()
command('bdelete')
end)
+ it(':wqall! closes a running job', function()
+ n.expect_exit(command, 'wqall!')
+ end)
+
it('stops running jobs with :quit', function()
-- Open in a new window to avoid terminating the nvim instance
command('split')