0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.0791: a second popup window with terminal causes trouble

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.
This commit is contained in:
Bram Moolenaar
2020-05-18 19:46:48 +02:00
parent 843700875e
commit b5383b174b
6 changed files with 46 additions and 12 deletions

View File

@@ -150,7 +150,7 @@ different: *E863*
- When the job ends, the popup window closes. - When the job ends, the popup window closes.
- The popup window can be closed with `popup_close()`, the terminal buffer - The popup window can be closed with `popup_close()`, the terminal buffer
then becomes hidden. 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 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 the color of the terminal itself set the Terminal highlight group before
creating the terminal. Setting 'wincolor' later can work but requires the creating the terminal. Setting 'wincolor' later can work but requires the

View File

@@ -2918,8 +2918,12 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
{ {
case ADDR_LINES: case ADDR_LINES:
case ADDR_OTHER: case ADDR_OTHER:
// default is current line number // Default is the cursor line number. Avoid using an invalid
eap->line2 = curwin->w_cursor.lnum; // 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; break;
case ADDR_WINDOWS: case ADDR_WINDOWS:
eap->line2 = CURRENT_WIN_NR; eap->line2 = CURRENT_WIN_NR;

View 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_create({text}, {options})
* popup_atcursor({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); semsg(_(e_nobufnr), argvars[0].vval.v_number);
return NULL; 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 else if (!(argvars[0].v_type == VAR_STRING
&& argvars[0].vval.v_string != NULL) && argvars[0].vval.v_string != NULL)

View File

@@ -2426,10 +2426,10 @@ func Test_popupwin_terminal_buffer()
let g:test_is_flaky = 1 let g:test_is_flaky = 1
let origwin = win_getid() let origwin = win_getid()
let ptybuf = term_start(&shell, #{hidden: 1}) let termbuf = term_start(&shell, #{hidden: 1})
let winid = popup_create(ptybuf, #{minwidth: 40, minheight: 10}) let winid = popup_create(termbuf, #{minwidth: 40, minheight: 10})
" Wait for shell to start " 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 sleep 100m
" Check this doesn't crash " Check this doesn't crash
call assert_equal(winnr(), winnr('j')) call assert_equal(winnr(), winnr('j'))
@@ -2440,11 +2440,16 @@ func Test_popupwin_terminal_buffer()
" Cannot quit while job is running " Cannot quit while job is running
call assert_fails('call feedkeys("\<C-W>:quit\<CR>", "xt")', 'E948:') 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 feedkeys("xxx\<C-W>N", 'xt')
call assert_fails('call feedkeys("gf", "xt")', 'E863:') call assert_fails('call feedkeys("gf", "xt")', 'E863:')
call feedkeys("a\<C-U>", 'xt') 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 " Exiting shell closes popup window
call feedkeys("exit\<CR>", 'xt') call feedkeys("exit\<CR>", 'xt')
" Wait for shell to exit " Wait for shell to exit

View File

@@ -2587,9 +2587,8 @@ func Test_double_popup_terminal()
let buf1 = term_start(&shell, #{hidden: 1}) let buf1 = term_start(&shell, #{hidden: 1})
let win1 = popup_create(buf1, {}) let win1 = popup_create(buf1, {})
let buf2 = term_start(&shell, #{hidden: 1}) 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(win1)
call popup_close(win2)
exe buf1 .. 'bwipe!' exe buf1 .. 'bwipe!'
exe buf2 .. 'bwipe!' exe buf2 .. 'bwipe!'
endfunc endfunc
@@ -2619,10 +2618,8 @@ func Test_term_nasty_callback()
CheckExecutable sh CheckExecutable sh
set hidden 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, {}) 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 assert_fails("call term_start(['sh', '-c'], #{curwin: 1})", 'E863:')
call popup_clear(1) call popup_clear(1)

View File

@@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
791,
/**/ /**/
790, 790,
/**/ /**/