To: vim_dev@googlegroups.com Subject: Patch 8.2.0791 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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("\:quit\", "xt")', 'E948:') ! " Cannot enter Terminal-Normal mode. call feedkeys("xxx\N", 'xt') call assert_fails('call feedkeys("gf", "xt")', 'E863:') call feedkeys("a\", 'xt') " Exiting shell closes popup window call feedkeys("exit\", 'xt') " Wait for shell to exit --- 2440,2455 ---- " Cannot quit while job is running call assert_fails('call feedkeys("\:quit\", "xt")', 'E948:') ! " Cannot enter Terminal-Normal mode. (TODO: but it works...) call feedkeys("xxx\N", 'xt') call assert_fails('call feedkeys("gf", "xt")', 'E863:') call feedkeys("a\", '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\") + " Exiting shell closes popup window call feedkeys("exit\", '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 -- Bram@Moolenaar.net -- 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 ///