aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c32
-rw-r--r--src/nvim/eval/funcs.c11
2 files changed, 24 insertions, 19 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index fdb3ffdc7e..81f8b9073e 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1218,8 +1218,8 @@ do_buffer(
return FAIL;
}
- if (!forceit && (buf->terminal || bufIsChanged(buf))) {
- if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
+ if (!forceit && bufIsChanged(buf)) {
+ if ((p_confirm || cmdmod.confirm) && p_write) {
dialog_changed(buf, false);
if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
@@ -1231,22 +1231,22 @@ do_buffer(
return FAIL;
}
} else {
- if (buf->terminal) {
- if (p_confirm || cmdmod.confirm) {
- if (!dialog_close_terminal(buf)) {
- return FAIL;
- }
- } else {
- EMSG2(_("E89: %s will be killed (add ! to override)"),
- (char *)buf->b_fname);
- return FAIL;
- }
- } else {
- EMSGN(_("E89: No write since last change for buffer %" PRId64
- " (add ! to override)"),
- buf->b_fnum);
+ EMSGN(_("E89: No write since last change for buffer %" PRId64
+ " (add ! to override)"),
+ buf->b_fnum);
+ return FAIL;
+ }
+ }
+
+ if (!forceit && buf->terminal && terminal_running(buf->terminal)) {
+ if (p_confirm || cmdmod.confirm) {
+ if (!dialog_close_terminal(buf)) {
return FAIL;
}
+ } else {
+ EMSG2(_("E89: %s will be killed (add ! to override)"),
+ (char *)buf->b_fname);
+ return FAIL;
}
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 8a1258efd4..99f9f17e0a 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -5404,14 +5404,19 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
TV_LIST_ITER_CONST(args, arg, {
Channel *chan = NULL;
if (TV_LIST_ITEM_TV(arg)->v_type != VAR_NUMBER
- || !(chan = find_job(TV_LIST_ITEM_TV(arg)->vval.v_number, false))) {
+ || !(chan = find_channel(TV_LIST_ITEM_TV(arg)->vval.v_number))
+ || chan->streamtype != kChannelStreamProc) {
+ jobs[i] = NULL; // Invalid job.
+ } else if (process_is_stopped(&chan->stream.proc)) {
+ // Job is stopped but not fully destroyed.
+ // Ensure all callbacks on its event queue are executed. #15402
+ process_wait(&chan->stream.proc, -1, NULL);
jobs[i] = NULL; // Invalid job.
} else {
jobs[i] = chan;
channel_incref(chan);
if (chan->stream.proc.status < 0) {
- // Process any pending events on the job's queue before temporarily
- // replacing it.
+ // Flush any events in the job's queue before temporarily replacing it.
multiqueue_process_events(chan->events);
multiqueue_replace_parent(chan->events, waiting_jobs);
}