]> granicus.if.org Git - vim/commitdiff
patch 8.2.1729: endless loop when ":normal" feeds popup window filter v8.2.1729
authorBram Moolenaar <Bram@vim.org>
Wed, 23 Sep 2020 10:29:11 +0000 (12:29 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 23 Sep 2020 10:29:11 +0000 (12:29 +0200)
Problem:    Endless loop when ":normal" feeds popup window filter.
Solution:   Add the ex_normal_busy_done flag.

src/evalfunc.c
src/ex_docmd.c
src/getchar.c
src/globals.h
src/menu.c
src/testdir/dumps/Test_popupwin_normal_cmd.dump [new file with mode: 0644]
src/testdir/test_popupwin.vim
src/version.c

index 570aef85f723ee7de91b100493eee44f264a9552..9bdeb52d9e721534725b2003c2de67a9f8a56d1d 100644 (file)
@@ -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;
            }
index bc01b69c7759af1cde94cc621a135a181361cfad..7f963887bfe3cad6c14f887c716774838401d7b2 100644 (file)
@@ -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
index e42fc332cccf26abd72408f44290886331d73694..2c7bd1fd2ef538f5a936af963d8927f3dd0e5a87 100644 (file)
@@ -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.
index 94164bbc3c855adfdb08f04969524e461622fcf8..eb33507d9feac9e208deab5cc30a4d3a94539896 100644 (file)
@@ -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
index fd811de065556bb026e403c39ac1daa52dfba0c2..f383ddde74554609e16491c4babb1ac370e60c0a 100644 (file)
@@ -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 (file)
index 0000000..f554859
--- /dev/null
@@ -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| 
index 333e9a2843faf3b52b4c7903b607673b3bb18ea9..6607ea231ced8c517d288ae645e9bc606559dc27 100644 (file)
@@ -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)?', #{
index a9852e94e330765774db3a0a82654fec772e6f97..aa821b2d885bdeb2b8fd06edfb5f18cf1a283238 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1729,
 /**/
     1728,
 /**/