patch 8.2.0196: blocking commands for a finished job in a popup window
Problem: Blocking commands for a finished job in a popup window.
Solution: Do not block commands if the job has finished. Adjust test.
diff --git a/src/popupwin.c b/src/popupwin.c
index d4f6026..714f457 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -2863,10 +2863,15 @@
}
# if defined(FEAT_TERMINAL) || defined(PROTO)
+/*
+ * Return TRUE if the current window is running a terminal in a popup window.
+ * Return FALSE when the job has ended.
+ */
int
error_if_term_popup_window()
{
- if (WIN_IS_POPUP(curwin) && curbuf->b_term != NULL)
+ if (WIN_IS_POPUP(curwin) && curbuf->b_term != NULL
+ && term_job_running(curbuf->b_term))
{
emsg(_("E899: Not allowed for a terminal in a popup window"));
return TRUE;
diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro
index 8d37db8..e8760d1 100644
--- a/src/proto/terminal.pro
+++ b/src/proto/terminal.pro
@@ -19,6 +19,7 @@
int term_use_loop(void);
void term_win_entered(void);
int terminal_loop(int blocking);
+int may_close_term_popup(void);
void term_channel_closed(channel_T *ch);
void term_check_channel_closed_recently(void);
int term_do_update_window(win_T *wp);
diff --git a/src/terminal.c b/src/terminal.c
index 7f92ab1..cbf8fe0 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -3260,6 +3260,29 @@
return FALSE;
}
+#if defined(FEAT_PROP_POPUP) || defined(PROTO)
+/*
+ * If the current window is a terminal in a popup window and the job has
+ * finished, close the popup window and to back to the previous window.
+ * Otherwise return FAIL.
+ */
+ int
+may_close_term_popup(void)
+{
+ if (popup_is_popup(curwin) && curbuf->b_term != NULL
+ && !term_job_running(curbuf->b_term))
+ {
+ win_T *pwin = curwin;
+
+ if (win_valid(prevwin))
+ win_enter(prevwin, FALSE);
+ popup_close_with_retval(pwin, 0);
+ return OK;
+ }
+ return FAIL;
+}
+#endif
+
/*
* Called when a channel has been closed.
* If this was a channel for a terminal window then finish it up.
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 75247b5..f8f501a 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -2396,10 +2396,20 @@
func Test_popupwin_terminal_buffer()
CheckFeature terminal
+ CheckUnix
+ let origwin = win_getid()
let ptybuf = term_start(&shell, #{hidden: 1})
- call assert_fails('let winnr = popup_create(ptybuf, #{})', 'E278:')
- exe 'bwipe! ' .. ptybuf
+ let winnr = popup_create(ptybuf, #{minwidth: 40, minheight: 10})
+ " Wait for shell to start
+ sleep 200m
+ " Cannot quit while job is running
+ call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:')
+ call feedkeys("exit\<CR>", 'xt')
+ " Wait for shell to exit
+ sleep 100m
+ call feedkeys(":quit\<CR>", 'xt')
+ call assert_equal(origwin, win_getid())
endfunc
func Test_popupwin_with_buffer_and_filter()
diff --git a/src/version.c b/src/version.c
index 65d961d..8c5cb53 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 196,
+/**/
195,
/**/
194,
diff --git a/src/window.c b/src/window.c
index aeafb26..23037fe 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2441,6 +2441,11 @@
int had_diffmode = win->w_p_diff;
#endif
+#if defined(FEAT_TERMINAL) && defined(FEAT_PROP_POPUP)
+ // Can close a popup window with a terminal if the job has finished.
+ if (may_close_term_popup() == OK)
+ return OK;
+#endif
if (ERROR_IF_ANY_POPUP_WINDOW)
return FAIL;
@@ -6439,6 +6444,12 @@
int count = 0;
win_T *wp;
+#if defined(FEAT_PROP_POPUP)
+ // If the current window is a popup then there always is another window.
+ if (popup_is_popup(curwin))
+ return FALSE;
+#endif
+
// If there is another tab page there always is another window.
if (first_tabpage->tp_next != NULL)
return FALSE;