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)
diff --git a/src/popupwin.c b/src/popupwin.c
index 953e76c..23f8efc 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -3126,6 +3126,7 @@
typval_T argv[3];
char_u buf[NUMBUFLEN];
linenr_T old_lnum = wp->w_cursor.lnum;
+ int prev_called_emsg = called_emsg;
// Emergency exit: CTRL-C closes the popup.
if (c == Ctrl_C)
@@ -3151,10 +3152,35 @@
argv[2].v_type = VAR_UNKNOWN;
// 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)
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);
clear_tv(&rettv);