]> granicus.if.org Git - vim/commitdiff
patch 8.2.0791: a second popup window with terminal causes trouble v8.2.0791
authorBram Moolenaar <Bram@vim.org>
Mon, 18 May 2020 17:46:48 +0000 (19:46 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 18 May 2020 17:46:48 +0000 (19:46 +0200)
Problem:    A second popup window with terminal causes trouble.
Solution:   Disallow opening a second terminal-popup window. (closes #6101,
            closes #6103) Avoid defaulting to an invalid line number.

runtime/doc/popup.txt
src/ex_docmd.c
src/popupwin.c
src/testdir/test_popupwin.vim
src/testdir/test_terminal.vim
src/version.c

index 5950c4753dc5be2bf3058290f93d9059a66aa4a3..fdf28a5e7a04b7b5631620ddaee0b17f72d30853 100644 (file)
@@ -150,7 +150,7 @@ different:                                          *E863*
 - When the job ends, the popup window closes.
 - The popup window can be closed with `popup_close()`, the terminal buffer
   then becomes hidden.
-- It is not possible to enter Terminal-Normal mode.
+- It is not possible to open a second popup window with a terminal. *E861*
 - The default Pmenu color is only used for the border and padding.  To change
   the color of the terminal itself set the Terminal highlight group before
   creating the terminal.  Setting 'wincolor' later can work but requires the
index 94a3367a3af459c9fb745e41eadce07d386f31a8..5447b741956b39886353504bd720c55b91814c20 100644 (file)
@@ -2918,8 +2918,12 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
        {
            case ADDR_LINES:
            case ADDR_OTHER:
-               // default is current line number
-               eap->line2 = curwin->w_cursor.lnum;
+               // Default is the cursor line number.  Avoid using an invalid
+               // line number though.
+               if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+                   eap->line2 = curbuf->b_ml.ml_line_count;
+               else
+                   eap->line2 = curwin->w_cursor.lnum;
                break;
            case ADDR_WINDOWS:
                eap->line2 = CURRENT_WIN_NR;
index 4ee097a066987057ffc47c5231a45a0c4e3365fc..79021c38c9ab5827fd3e313545caf49ddfe2a323 100644 (file)
@@ -1757,6 +1757,25 @@ add_border_left_right_padding(win_T *wp)
     }
 }
 
+/*
+ * Return TRUE if there is any popup window with a terminal buffer.
+ */
+    static int
+popup_terminal_exists(void)
+{
+    win_T      *wp;
+    tabpage_T  *tp;
+
+    FOR_ALL_POPUPWINS(wp)
+       if (wp->w_buffer->b_term != NULL)
+           return TRUE;
+    FOR_ALL_TABPAGES(tp)
+       FOR_ALL_POPUPWINS_IN_TAB(tp, wp)
+           if (wp->w_buffer->b_term != NULL)
+               return TRUE;
+    return FALSE;
+}
+
 /*
  * popup_create({text}, {options})
  * popup_atcursor({text}, {options})
@@ -1786,6 +1805,13 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
                semsg(_(e_nobufnr), argvars[0].vval.v_number);
                return NULL;
            }
+#ifdef FEAT_TERMINAL
+           if (buf->b_term != NULL && popup_terminal_exists())
+           {
+               emsg(_("E861: Cannot open a second popup with a terminal"));
+               return NULL;
+           }
+#endif
        }
        else if (!(argvars[0].v_type == VAR_STRING
                        && argvars[0].vval.v_string != NULL)
index feaa5e4c0dd7c399b1fbb1b30d741234009b7b89..8c917bc8e3be24a5e5cc5deff38889339221e03a 100644 (file)
@@ -2426,10 +2426,10 @@ func Test_popupwin_terminal_buffer()
   let g:test_is_flaky = 1
 
   let origwin = win_getid()
-  let ptybuf = term_start(&shell, #{hidden: 1})
-  let winid = popup_create(ptybuf, #{minwidth: 40, minheight: 10})
+  let termbuf = term_start(&shell, #{hidden: 1})
+  let winid = popup_create(termbuf, #{minwidth: 40, minheight: 10})
   " Wait for shell to start
-  call WaitForAssert({-> assert_equal("run", job_status(term_getjob(ptybuf)))})
+  call WaitForAssert({-> assert_equal("run", job_status(term_getjob(termbuf)))})
   sleep 100m
   " Check this doesn't crash
   call assert_equal(winnr(), winnr('j'))
@@ -2440,11 +2440,16 @@ func Test_popupwin_terminal_buffer()
   " Cannot quit while job is running
   call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:')
 
-  " Cannot enter Terminal-Normal mode.
+  " Cannot enter Terminal-Normal mode. (TODO: but it works...)
   call feedkeys("xxx\<C-W>N", 'xt')
   call assert_fails('call feedkeys("gf", "xt")', 'E863:')
   call feedkeys("a\<C-U>", 'xt')
 
+  " Cannot open a second one.
+  let termbuf2 = term_start(&shell, #{hidden: 1})
+  call assert_fails('call popup_create(termbuf2, #{})', 'E861:')
+  call term_sendkeys(termbuf2, "exit\<CR>")
+
   " Exiting shell closes popup window
   call feedkeys("exit\<CR>", 'xt')
   " Wait for shell to exit
index ab1961aa37ab8aab6ede024689178355d18e6b4a..7f85f6cf10fdcfef0eeb80147dd0dd28cdd4dad0 100644 (file)
@@ -2587,9 +2587,8 @@ func Test_double_popup_terminal()
   let buf1 = term_start(&shell, #{hidden: 1})
   let win1 = popup_create(buf1, {})
   let buf2 = term_start(&shell, #{hidden: 1})
-  let win2 = popup_create(buf2, {})
+  call assert_fails('call popup_create(buf2, {})', 'E861:')
   call popup_close(win1)
-  call popup_close(win2)
   exe buf1 .. 'bwipe!'
   exe buf2 .. 'bwipe!'
 endfunc
@@ -2619,10 +2618,8 @@ func Test_term_nasty_callback()
   CheckExecutable sh
 
   set hidden
-  let g:buf0 = term_start('sh', #{hidden: 1})
+  let g:buf0 = term_start('sh', #{hidden: 1, term_finish: 'close'})
   call popup_create(g:buf0, {})
-  let g:buf1 = term_start('sh', #{hidden: 1, term_finish: 'close'})
-  call popup_create(g:buf1, {})
   call assert_fails("call term_start(['sh', '-c'], #{curwin: 1})", 'E863:')
 
   call popup_clear(1)
index aa03f906cd2a4ce04e765b3042722fb4074a9f32..92f5660e5396c17125ae35182824894f40bb070e 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    791,
 /**/
     790,
 /**/