summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-09-23 12:29:11 +0200
committerBram Moolenaar <Bram@vim.org>2020-09-23 12:29:11 +0200
commit189832bf661168df7ebd428e4088737718775fbd (patch)
tree41f4c1d46cc1b0b40dcff2969f189ddfd1b21d84
parentc53e9c57a9846655c2d3169788f4beefa6d22d90 (diff)
downloadvim-git-189832bf661168df7ebd428e4088737718775fbd.tar.gz
patch 8.2.1729: endless loop when ":normal" feeds popup window filterv8.2.1729
Problem: Endless loop when ":normal" feeds popup window filter. Solution: Add the ex_normal_busy_done flag.
-rw-r--r--src/evalfunc.c6
-rw-r--r--src/ex_docmd.c4
-rw-r--r--src/getchar.c6
-rw-r--r--src/globals.h5
-rw-r--r--src/menu.c4
-rw-r--r--src/testdir/dumps/Test_popupwin_normal_cmd.dump10
-rw-r--r--src/testdir/test_popupwin.vim17
-rw-r--r--src/version.c2
8 files changed, 53 insertions, 1 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 570aef85f..9bdeb52d9 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -2610,7 +2610,13 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
++ex_normal_busy;
exec_normal(TRUE, lowlevel, TRUE);
if (!dangerous)
+ {
--ex_normal_busy;
+#ifdef FEAT_PROP_POPUP
+ if (ex_normal_busy == 0)
+ ex_normal_busy_done = FALSE;
+#endif
+ }
msg_scroll |= save_msg_scroll;
}
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index bc01b69c7..7f963887b 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -8030,6 +8030,10 @@ ex_normal(exarg_T *eap)
restore_current_state(&save_state);
--ex_normal_busy;
+#ifdef FEAT_PROP_POPUP
+ if (ex_normal_busy == 0)
+ ex_normal_busy_done = FALSE;
+#endif
setmouse();
#ifdef CURSOR_SHAPE
ui_cursor_shape(); // may show different cursor shape
diff --git a/src/getchar.c b/src/getchar.c
index e42fc332c..2c7bd1fd2 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1888,7 +1888,7 @@ vgetc(void)
}
#endif
#ifdef FEAT_PROP_POPUP
- if (popup_do_filter(c))
+ if (!ex_normal_busy_done && popup_do_filter(c))
{
if (c == Ctrl_C)
got_int = FALSE; // avoid looping
@@ -3168,6 +3168,10 @@ vgetorpeek(int advance)
timedout = TRUE;
continue;
}
+#ifdef FEAT_PROP_POPUP
+ ex_normal_busy_done = TRUE;
+#endif
+
// When 'insertmode' is set, ESC just beeps in Insert
// mode. Use CTRL-L to make edit() return.
// For the command line only CTRL-C always breaks it.
diff --git a/src/globals.h b/src/globals.h
index 94164bbc3..eb33507d9 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1152,6 +1152,11 @@ EXTERN typebuf_T typebuf // typeahead buffer
;
EXTERN int ex_normal_busy INIT(= 0); // recursiveness of ex_normal()
EXTERN int ex_normal_lock INIT(= 0); // forbid use of ex_normal()
+#ifdef FEAT_PROP_POPUP
+// Set to TRUE when ex_normal_busy is set and out of typeahead.
+EXTERN int ex_normal_busy_done INIT(= FALSE);
+#endif
+
#ifdef FEAT_EVAL
EXTERN int ignore_script INIT(= FALSE); // ignore script input
#endif
diff --git a/src/menu.c b/src/menu.c
index fd811de06..f383ddde7 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -2398,6 +2398,10 @@ execute_menu(exarg_T *eap, vimmenu_T *menu, int mode_idx)
menu->silent[idx]);
restore_current_state(&save_state);
--ex_normal_busy;
+#ifdef FEAT_PROP_POPUP
+ if (ex_normal_busy == 0)
+ ex_normal_busy_done = FALSE;
+#endif
}
else
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
diff --git a/src/testdir/dumps/Test_popupwin_normal_cmd.dump b/src/testdir/dumps/Test_popupwin_normal_cmd.dump
new file mode 100644
index 000000000..f5548591c
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_normal_cmd.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @31| +0#0000000&@8| +0#4040ff13&@32
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 333e9a284..6607ea231 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -1539,6 +1539,23 @@ func Test_popup_filter()
call popup_clear()
endfunc
+" this tests that the "ex_normal_busy_done" flag works
+func Test_popup_filter_normal_cmd()
+ CheckScreendump
+
+ let lines =<< trim END
+ let g:winid = popup_create('some text', {'filter': 'invalidfilter'})
+ call timer_start(0, {-> win_execute(g:winid, 'norm! zz')})
+ END
+ call writefile(lines, 'XtestPopupNormal')
+ let buf = RunVimInTerminal('-S XtestPopupNormal', #{rows: 10})
+ call TermWait(buf, 100)
+ call VerifyScreenDump(buf, 'Test_popupwin_normal_cmd', {})
+
+ call StopVimInTerminal(buf)
+ call delete('XtestPopupNormal')
+endfunc
+
func ShowDialog(key, result)
let s:cb_res = 999
let winid = popup_dialog('do you want to quit (Yes/no)?', #{
diff --git a/src/version.c b/src/version.c
index a9852e94e..aa821b2d8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1729,
+/**/
1728,
/**/
1727,