Patch 8.2.0791
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.
Files:      runtime/doc/popup.txt, src/popupwin.c, src/ex_docmd.c,
            src/testdir/test_popupwin.vim, src/testdir/test_terminal.vim


*** ../vim-8.2.0790/runtime/doc/popup.txt       2020-05-13 16:34:10.401723784 
+0200
--- runtime/doc/popup.txt       2020-05-18 18:53:28.576588705 +0200
***************
*** 150,163 ****
  - When the job ends, the popup window closes.
  - The popup window can be closed with `popup_close()`, the terminal buffer
    then becomes hidden.
  - The default Pmenu color is only used for the border and padding.  To change
!   the color of the terminal itself set 'wincolor'.
  
  To run a terminal in a popup window, first create the terminal hidden.  Then
  pass the buffer number to popup_create().  Example: >
        let buf = term_start(['picker', 'Something'], #{hidden: 1, term_finish: 
'close'})
        let winid = popup_create(buf, #{minwidth: 50, minheight: 20})
-       set wincolor=Search
  
  ==============================================================================
  2. Functions                                          *popup-functions*
--- 150,170 ----
  - 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 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
!   program in the terminal to redraw everything.
! - The default minimal size is 5 lines of 20 characters; Use the "minwidth" and
!   "minheight" parameters to set a different value.
! - The terminal size will grow if the program running in the terminal writes
!   text.  Set "maxheight" and "maxwidth" to restrict the size.
  
  To run a terminal in a popup window, first create the terminal hidden.  Then
  pass the buffer number to popup_create().  Example: >
+       hi link Terminal Search
        let buf = term_start(['picker', 'Something'], #{hidden: 1, term_finish: 
'close'})
        let winid = popup_create(buf, #{minwidth: 50, minheight: 20})
  
  ==============================================================================
  2. Functions                                          *popup-functions*
***************
*** 578,598 ****
  
  If you want to create a new buffer yourself use |bufadd()| and pass the buffer
  number to popup_create().
! It is not possible to use the buffer of a terminal window. *E278*
  
  The second argument of |popup_create()| is a dictionary with options:
        line            Screen line where to position the popup.  Can use a
                        number or "cursor", "cursor+1" or "cursor-1" to use
                        the line of the cursor and add or subtract a number of
!                       lines.  If omitted the popup is vertically centered.
!                       The first line is 1.
                        When using "textprop" the number is relative to the
                        text property and can be negative.
        col             Screen column where to position the popup.  Can use a
                        number or "cursor" to use the column of the cursor,
                        "cursor+9" or "cursor-9" to add or subtract a number
!                       of columns.  If omitted the popup is horizontally
!                       centered.  The first column is 1.
                        When using "textprop" the number is relative to the
                        text property and can be negative.
        pos             "topleft", "topright", "botleft" or "botright":
--- 587,608 ----
  
  If you want to create a new buffer yourself use |bufadd()| and pass the buffer
  number to popup_create().
! It is not possible to use the buffer of a terminal window. *E278*  You CAN
! create a hidden terminal buffer and use that one in a popup window.
  
  The second argument of |popup_create()| is a dictionary with options:
        line            Screen line where to position the popup.  Can use a
                        number or "cursor", "cursor+1" or "cursor-1" to use
                        the line of the cursor and add or subtract a number of
!                       lines.  If omitted or zero the popup is vertically
!                       centered.  The first line is 1.
                        When using "textprop" the number is relative to the
                        text property and can be negative.
        col             Screen column where to position the popup.  Can use a
                        number or "cursor" to use the column of the cursor,
                        "cursor+9" or "cursor-9" to add or subtract a number
!                       of columns.  If omitted or zero the popup is
!                       horizontally centered.  The first column is 1.
                        When using "textprop" the number is relative to the
                        text property and can be negative.
        pos             "topleft", "topright", "botleft" or "botright":
*** ../vim-8.2.0790/src/popupwin.c      2020-05-13 22:44:18.142288807 +0200
--- src/popupwin.c      2020-05-18 18:52:40.032705255 +0200
***************
*** 1758,1763 ****
--- 1758,1782 ----
  }
  
  /*
+  * 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})
   * etc.
***************
*** 1786,1791 ****
--- 1805,1817 ----
                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)
*** ../vim-8.2.0790/src/ex_docmd.c      2020-05-01 15:44:24.535895262 +0200
--- src/ex_docmd.c      2020-05-18 19:28:50.057685500 +0200
***************
*** 2918,2925 ****
        {
            case ADDR_LINES:
            case ADDR_OTHER:
!               // default is current line number
!               eap->line2 = curwin->w_cursor.lnum;
                break;
            case ADDR_WINDOWS:
                eap->line2 = CURRENT_WIN_NR;
--- 2918,2929 ----
        {
            case ADDR_LINES:
            case ADDR_OTHER:
!               // 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;
*** ../vim-8.2.0790/src/testdir/test_popupwin.vim       2020-05-13 
23:24:06.797864068 +0200
--- src/testdir/test_popupwin.vim       2020-05-18 19:44:30.574846372 +0200
***************
*** 2426,2435 ****
    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})
    " Wait for shell to start
!   call WaitForAssert({-> assert_equal("run", 
job_status(term_getjob(ptybuf)))})
    sleep 100m
    " Check this doesn't crash
    call assert_equal(winnr(), winnr('j'))
--- 2426,2435 ----
    let g:test_is_flaky = 1
  
    let origwin = win_getid()
!   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(termbuf)))})
    sleep 100m
    " Check this doesn't crash
    call assert_equal(winnr(), winnr('j'))
***************
*** 2440,2450 ****
    " Cannot quit while job is running
    call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:')
  
!   " Cannot enter Terminal-Normal mode.
    call feedkeys("xxx\<C-W>N", 'xt')
    call assert_fails('call feedkeys("gf", "xt")', 'E863:')
    call feedkeys("a\<C-U>", 'xt')
  
    " Exiting shell closes popup window
    call feedkeys("exit\<CR>", 'xt')
    " Wait for shell to exit
--- 2440,2455 ----
    " Cannot quit while job is running
    call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:')
  
!   " 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
*** ../vim-8.2.0790/src/testdir/test_terminal.vim       2020-05-17 
15:09:23.233533264 +0200
--- src/testdir/test_terminal.vim       2020-05-18 19:39:43.443686025 +0200
***************
*** 2587,2595 ****
    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 popup_close(win1)
-   call popup_close(win2)
    exe buf1 .. 'bwipe!'
    exe buf2 .. 'bwipe!'
  endfunc
--- 2587,2594 ----
    let buf1 = term_start(&shell, #{hidden: 1})
    let win1 = popup_create(buf1, {})
    let buf2 = term_start(&shell, #{hidden: 1})
!   call assert_fails('call popup_create(buf2, {})', 'E861:')
    call popup_close(win1)
    exe buf1 .. 'bwipe!'
    exe buf2 .. 'bwipe!'
  endfunc
***************
*** 2619,2628 ****
    CheckExecutable sh
  
    set hidden
!   let g:buf0 = term_start('sh', #{hidden: 1})
    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)
--- 2618,2625 ----
    CheckExecutable sh
  
    set hidden
!   let g:buf0 = term_start('sh', #{hidden: 1, term_finish: 'close'})
    call popup_create(g:buf0, {})
    call assert_fails("call term_start(['sh', '-c'], #{curwin: 1})", 'E863:')
  
    call popup_clear(1)
*** ../vim-8.2.0790/src/version.c       2020-05-18 14:20:33.915289768 +0200
--- src/version.c       2020-05-18 18:54:49.388392505 +0200
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     791,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
131. You challenge authority and society by portnuking people

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202005181747.04IHlLlc024810%40masaka.moolenaar.net.

Raspunde prin e-mail lui