mirror of
https://github.com/vim/vim.git
synced 2025-09-01 21:03:39 -04:00
patch 8.2.1636: get stuck if a popup filter causes an error
Problem: Get stuck if a popup filter causes an error. Solution: Check whether the function can be called and does not cause an error. (closes #6902)
This commit is contained in:
parent
57ad94c5a9
commit
6defa7bf0a
@ -3126,6 +3126,7 @@ invoke_popup_filter(win_T *wp, int c)
|
|||||||
typval_T argv[3];
|
typval_T argv[3];
|
||||||
char_u buf[NUMBUFLEN];
|
char_u buf[NUMBUFLEN];
|
||||||
linenr_T old_lnum = wp->w_cursor.lnum;
|
linenr_T old_lnum = wp->w_cursor.lnum;
|
||||||
|
int prev_called_emsg = called_emsg;
|
||||||
|
|
||||||
// Emergency exit: CTRL-C closes the popup.
|
// Emergency exit: CTRL-C closes the popup.
|
||||||
if (c == Ctrl_C)
|
if (c == Ctrl_C)
|
||||||
@ -3151,10 +3152,35 @@ invoke_popup_filter(win_T *wp, int c)
|
|||||||
argv[2].v_type = VAR_UNKNOWN;
|
argv[2].v_type = VAR_UNKNOWN;
|
||||||
|
|
||||||
// NOTE: The callback might close the popup and make "wp" invalid.
|
// NOTE: The callback might close the popup and make "wp" invalid.
|
||||||
call_callback(&wp->w_filter_cb, -1, &rettv, 2, argv);
|
if (call_callback(&wp->w_filter_cb, -1, &rettv, 2, argv) == FAIL)
|
||||||
|
{
|
||||||
|
// Cannot call the function, close the popup to avoid that the filter
|
||||||
|
// eats keys and the user can't get out.
|
||||||
|
popup_close_with_retval(wp, -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (win_valid_popup(wp) && old_lnum != wp->w_cursor.lnum)
|
if (win_valid_popup(wp) && old_lnum != wp->w_cursor.lnum)
|
||||||
popup_highlight_curline(wp);
|
popup_highlight_curline(wp);
|
||||||
res = tv_get_bool(&rettv);
|
|
||||||
|
// If an error was given always return FALSE, so that keys are not
|
||||||
|
// consumed and the user can type something.
|
||||||
|
// If we get three errors in a row then close the popup. Decrement the
|
||||||
|
// error count by 1/10 if there are no errors, thus allowing up to 1 in
|
||||||
|
// 10 calls to cause an error.
|
||||||
|
if (win_valid_popup(wp) && called_emsg > prev_called_emsg)
|
||||||
|
{
|
||||||
|
wp->w_filter_errors += 10;
|
||||||
|
if (wp->w_filter_errors >= 30)
|
||||||
|
popup_close_with_retval(wp, -1);
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (win_valid_popup(wp) && wp->w_filter_errors > 0)
|
||||||
|
--wp->w_filter_errors;
|
||||||
|
res = tv_get_bool(&rettv);
|
||||||
|
}
|
||||||
|
|
||||||
vim_free(argv[1].vval.v_string);
|
vim_free(argv[1].vval.v_string);
|
||||||
clear_tv(&rettv);
|
clear_tv(&rettv);
|
||||||
|
@ -3338,6 +3338,7 @@ struct window_S
|
|||||||
// with "cursorline" set
|
// with "cursorline" set
|
||||||
callback_T w_close_cb; // popup close callback
|
callback_T w_close_cb; // popup close callback
|
||||||
callback_T w_filter_cb; // popup filter callback
|
callback_T w_filter_cb; // popup filter callback
|
||||||
|
int w_filter_errors; // popup filter error count
|
||||||
int w_filter_mode; // mode when filter callback is used
|
int w_filter_mode; // mode when filter callback is used
|
||||||
|
|
||||||
win_T *w_popup_curwin; // close popup if curwin differs
|
win_T *w_popup_curwin; // close popup if curwin differs
|
||||||
|
10
src/testdir/dumps/Test_popupwin_three_errors_1.dump
Normal file
10
src/testdir/dumps/Test_popupwin_three_errors_1.dump
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
> +0&#ffffff0@74
|
||||||
|
|~+0#4040ff13&| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @27|o+0#0000001#ffd7ff255|n|e| |t|w|o| |t|h|r|e@1|.@2| +0#4040ff13#ffffff0@29
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|E+0#ffffff16#e000002|8|9|6|:| |A|r|g|u|m|e|n|t| |o|f| |f|i|l|t|e|r|(|)| |m|u|s|t| |b|e| |a| |L|i|s|t|,| |D|i|c|t|i|o|n|a|r|y| |o|r| |B|l|o|b| +0#0000000#ffffff0@13
|
||||||
|
@57|0|,|0|-|1| @8|A|l@1|
|
10
src/testdir/dumps/Test_popupwin_three_errors_2.dump
Normal file
10
src/testdir/dumps/Test_popupwin_three_errors_2.dump
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
> +0&#ffffff0@74
|
||||||
|
|~+0#4040ff13&| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|E+0#ffffff16#e000002|8|9|6|:| |A|r|g|u|m|e|n|t| |o|f| |f|i|l|t|e|r|(|)| |m|u|s|t| |b|e| |a| |L|i|s|t|,| |D|i|c|t|i|o|n|a|r|y| |o|r| |B|l|o|b| +0#0000000#ffffff0@13
|
||||||
|
@57|0|,|0|-|1| @8|A|l@1|
|
10
src/testdir/dumps/Test_popupwin_wrong_name.dump
Normal file
10
src/testdir/dumps/Test_popupwin_wrong_name.dump
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
> +0&#ffffff0@74
|
||||||
|
|~+0#4040ff13&| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|E+0#ffffff16#e000002|1@1|7|:| |U|n|k|n|o|w|n| |f|u|n|c|t|i|o|n|:| |N|o|S|u|c|h|F|u|n|c| +0#0000000#ffffff0@22|0|,|0|-|1| @8|A|l@1|
|
@ -3516,7 +3516,44 @@ func Test_popupwin_filter_close_ctrl_c()
|
|||||||
call VerifyScreenDump(buf, 'Test_popupwin_ctrl_c', {})
|
call VerifyScreenDump(buf, 'Test_popupwin_ctrl_c', {})
|
||||||
|
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
call delete('XtestPopupCorners')
|
call delete('XtestPopupCtrlC')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_popupwin_filter_close_wrong_name()
|
||||||
|
CheckScreendump
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
call popup_create('one two three...', {'filter': 'NoSuchFunc'})
|
||||||
|
END
|
||||||
|
call writefile(lines, 'XtestPopupWrongName')
|
||||||
|
|
||||||
|
let buf = RunVimInTerminal('-S XtestPopupWrongName', #{rows: 10})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "j")
|
||||||
|
call VerifyScreenDump(buf, 'Test_popupwin_wrong_name', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('XtestPopupWrongName')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_popupwin_filter_close_three_errors()
|
||||||
|
CheckScreendump
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
set cmdheight=2
|
||||||
|
call popup_create('one two three...', {'filter': 'filter'})
|
||||||
|
END
|
||||||
|
call writefile(lines, 'XtestPopupThreeErrors')
|
||||||
|
|
||||||
|
let buf = RunVimInTerminal('-S XtestPopupThreeErrors', #{rows: 10})
|
||||||
|
|
||||||
|
call term_sendkeys(buf, "jj")
|
||||||
|
call VerifyScreenDump(buf, 'Test_popupwin_three_errors_1', {})
|
||||||
|
call term_sendkeys(buf, "j")
|
||||||
|
call VerifyScreenDump(buf, 'Test_popupwin_three_errors_2', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('XtestPopupThreeErrors')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_popupwin_atcursor_far_right()
|
func Test_popupwin_atcursor_far_right()
|
||||||
|
@ -754,6 +754,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 */
|
||||||
|
/**/
|
||||||
|
1636,
|
||||||
/**/
|
/**/
|
||||||
1635,
|
1635,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user