@@ -3126,6 +3126,7 @@ invoke_popup_filter(win_T *wp, int c)
31263126 typval_T argv [3 ];
31273127 char_u buf [NUMBUFLEN ];
31283128 linenr_T old_lnum = wp -> w_cursor .lnum ;
3129+ int prev_called_emsg = called_emsg ;
31293130
31303131 // Emergency exit: CTRL-C closes the popup.
31313132 if (c == Ctrl_C )
@@ -3151,10 +3152,35 @@ invoke_popup_filter(win_T *wp, int c)
31513152 argv [2 ].v_type = VAR_UNKNOWN ;
31523153
31533154 // NOTE: The callback might close the popup and make "wp" invalid.
3154- call_callback (& wp -> w_filter_cb , -1 , & rettv , 2 , argv );
3155+ if (call_callback (& wp -> w_filter_cb , -1 , & rettv , 2 , argv ) == FAIL )
3156+ {
3157+ // Cannot call the function, close the popup to avoid that the filter
3158+ // eats keys and the user can't get out.
3159+ popup_close_with_retval (wp , -1 );
3160+ return 1 ;
3161+ }
3162+
31553163 if (win_valid_popup (wp ) && old_lnum != wp -> w_cursor .lnum )
31563164 popup_highlight_curline (wp );
3157- res = tv_get_bool (& rettv );
3165+
3166+ // If an error was given always return FALSE, so that keys are not
3167+ // consumed and the user can type something.
3168+ // If we get three errors in a row then close the popup. Decrement the
3169+ // error count by 1/10 if there are no errors, thus allowing up to 1 in
3170+ // 10 calls to cause an error.
3171+ if (win_valid_popup (wp ) && called_emsg > prev_called_emsg )
3172+ {
3173+ wp -> w_filter_errors += 10 ;
3174+ if (wp -> w_filter_errors >= 30 )
3175+ popup_close_with_retval (wp , -1 );
3176+ res = FALSE;
3177+ }
3178+ else
3179+ {
3180+ if (win_valid_popup (wp ) && wp -> w_filter_errors > 0 )
3181+ -- wp -> w_filter_errors ;
3182+ res = tv_get_bool (& rettv );
3183+ }
31583184
31593185 vim_free (argv [1 ].vval .v_string );
31603186 clear_tv (& rettv );
0 commit comments