]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0196: blocking commands for a finished job in a popup window v8.2.0196
authorBram Moolenaar <Bram@vim.org>
Sun, 2 Feb 2020 14:25:16 +0000 (15:25 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 2 Feb 2020 14:25:16 +0000 (15:25 +0100)
Problem:    Blocking commands for a finished job in a popup window.
Solution:   Do not block commands if the job has finished.  Adjust test.

src/popupwin.c
src/proto/terminal.pro
src/terminal.c
src/testdir/test_popupwin.vim
src/version.c
src/window.c

index d4f6026f9f5e3f8484411fb9aab5d65ca68e37eb..714f457febcf7337373bcd7bfdd5dc4495edc12c 100644 (file)
@@ -2863,10 +2863,15 @@ error_if_popup_window(int also_with_term UNUSED)
 }
 
 # 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;
index 8d37db8e36bb682a97b511dca7e6384f3f8dc143..e8760d14a73691e01d8dbb88bf3e5738bfba90ab 100644 (file)
@@ -19,6 +19,7 @@ cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
 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);
index 7f92ab1a445da41f36f5c9dd478d512e96a34c5c..cbf8fe0799159ee7194590a47b59c54b41f564ed 100644 (file)
@@ -3260,6 +3260,29 @@ term_after_channel_closed(term_T *term)
     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.
index 75247b5334545cfcf17df384f8d9d7c5ffb19b3c..f8f501afaa9a3b5c0aeefb7f2b3cceb105272717 100644 (file)
@@ -2396,10 +2396,20 @@ endfunc
 
 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()
index 65d961d02ef73ab90481069757c4997034d01401..8c5cb53dc7ea068a6367b2aa190587a771ecfed3 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    196,
 /**/
     195,
 /**/
index aeafb267ca152cbaadc168c08ad57aabeb40e322..23037fe753f3eea41746da96466c1e1c9e1d6e7e 100644 (file)
@@ -2441,6 +2441,11 @@ win_close(win_T *win, int free_buf)
     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 @@ only_one_window(void)
     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;