patch 8.2.1769: popup filter interferes with using :normal to move the cursor
Problem: A popup filter interferes with using :normal to move the cursor in
a popup.
Solution: Do not invoke the filter when ex_normal_busy is set.
diff --git a/src/evalfunc.c b/src/evalfunc.c
index b387c8c..2af4bc0 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -2616,15 +2616,15 @@
msg_scroll = FALSE;
if (!dangerous)
+ {
++ex_normal_busy;
+ ++in_feedkeys;
+ }
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
+ --in_feedkeys;
}
msg_scroll |= save_msg_scroll;
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index bb504ff..05378fd 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -8037,10 +8037,6 @@
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 2c7bd1f..6e469f4 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1888,7 +1888,9 @@
}
#endif
#ifdef FEAT_PROP_POPUP
- if (!ex_normal_busy_done && popup_do_filter(c))
+ // Only filter keys that do not come from ":normal". Keys from feedkeys()
+ // are filtered.
+ if ((!ex_normal_busy || in_feedkeys) && popup_do_filter(c))
{
if (c == Ctrl_C)
got_int = FALSE; // avoid looping
@@ -3168,9 +3170,6 @@
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.
diff --git a/src/globals.h b/src/globals.h
index eb33507..4ca3092 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1150,12 +1150,9 @@
= {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}
#endif
;
-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
+EXTERN int ex_normal_busy INIT(= 0); // recursiveness of ex_normal()
+EXTERN int in_feedkeys INIT(= 0); // ex_normal_busy set in feedkeys()
+EXTERN int ex_normal_lock INIT(= 0); // forbid use of ex_normal()
#ifdef FEAT_EVAL
EXTERN int ignore_script INIT(= FALSE); // ignore script input
diff --git a/src/menu.c b/src/menu.c
index f383ddd..fd811de 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -2398,10 +2398,6 @@
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
index f554859..95588d6 100644
--- a/src/testdir/dumps/Test_popupwin_normal_cmd.dump
+++ b/src/testdir/dumps/Test_popupwin_normal_cmd.dump
@@ -1,10 +1,10 @@
> +0&#ffffff0@74
|~+0#4040ff13&| @73
-|~| @73
-|~| @73
-|~| @31| +0#0000000&@8| +0#4040ff13&@32
-|~| @73
-|~| @73
+|~| @33|8+0#0000001#ffd7ff255| @1| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@35
+|~| @33|9+0#0000001#ffd7ff255| @1| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@35
+|~| @33|1+0#0000001#ffd7ff255|0| | +0#0000000#0000001| +0#4040ff13#ffffff0@35
+|~| @33|1+0#0000001#ffd7ff255@1| | +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@35
+|~| @33|1+0#0000001#ffd7ff255|2| | +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@35
|~| @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 ea2ee3b..e991fc1 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -1539,13 +1539,14 @@
call popup_clear()
endfunc
-" this tests that the "ex_normal_busy_done" flag works
+" this tests that the filter is not used for :normal command
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')})
+ let text = range(1, 20)->map({_, v -> string(v)})
+ let g:winid = popup_create(text, #{maxheight: 5, minwidth: 3, filter: 'invalidfilter'})
+ call timer_start(0, {-> win_execute(g:winid, 'norm! 10Gzz')})
END
call writefile(lines, 'XtestPopupNormal')
let buf = RunVimInTerminal('-S XtestPopupNormal', #{rows: 10})
diff --git a/src/version.c b/src/version.c
index 5d84e24..3d37c85 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1769,
+/**/
1768,
/**/
1767,