]> granicus.if.org Git - vim/commitdiff
patch 8.0.0670: can't use input() in a timer callback v8.0.0670
authorBram Moolenaar <Bram@vim.org>
Sat, 24 Jun 2017 14:03:06 +0000 (16:03 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 24 Jun 2017 14:03:06 +0000 (16:03 +0200)
Problem:    Can't use input() in a timer callback. (Cosmin Popescu)
Solution:   Reset vgetc_busy and set timer_busy. (Ozaki Kiichi, closes #1790,
            closes #1129)

src/evalfunc.c
src/ex_cmds2.c
src/globals.h
src/testdir/test_timers.vim
src/version.c

index 7c781d8b916220488c0e025ba101e1f94e71a87d..581ad7b5bf42ce93869d4f41b9e746756f43ac55 100644 (file)
@@ -3191,7 +3191,7 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
            ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
                                  insert ? 0 : typebuf.tb_len, !typed, FALSE);
            vim_free(keys_esc);
-           if (vgetc_busy)
+           if (vgetc_busy || timer_busy)
                typebuf_was_filled = TRUE;
            if (execute)
            {
index 225225a78c0206df453f111af18159ef46930cf5..33ad924d222348e5dab90770e1245e6581effeaa 100644 (file)
@@ -1209,11 +1209,18 @@ check_due_timer(void)
        this_due = GET_TIMEDIFF(timer, now);
        if (this_due <= 1)
        {
+           int save_timer_busy = timer_busy;
+           int save_vgetc_busy = vgetc_busy;
+
+           timer_busy = timer_busy > 0 || vgetc_busy > 0;
+           vgetc_busy = 0;
            timer->tr_firing = TRUE;
            timer_callback(timer);
            timer->tr_firing = FALSE;
            timer_next = timer->tr_next;
            did_one = TRUE;
+           timer_busy = save_timer_busy;
+           vgetc_busy = save_vgetc_busy;
 
            /* Only fire the timer again if it repeats and stop_timer() wasn't
             * called while inside the callback (tr_id == -1). */
index 56df6d5083775c5f2a3d283a5dd8bc1b00c23109..7cf928c16d3c7341371491c47b720238d6785e43 100644 (file)
@@ -1659,6 +1659,7 @@ EXTERN int  in_free_unref_items INIT(= FALSE);
 
 #ifdef FEAT_TIMERS
 EXTERN int  did_add_timer INIT(= FALSE);
+EXTERN int  timer_busy INIT(= 0);   /* when timer is inside vgetc() then > 0 */
 #endif
 
 #ifdef FEAT_EVAL
index ebc66658084930512d2cc0e4f7e26374a786ffab..fdb74e79581a04be53fbb0bc068a11eaef12d4c0 100644 (file)
@@ -172,5 +172,21 @@ func Test_stop_all_in_callback()
   call assert_equal(0, len(info))
 endfunc
 
+func FeedkeysCb(timer)
+  call feedkeys("hello\<CR>", 'nt')
+endfunc
+
+func InputCb(timer)
+  call timer_start(10, 'FeedkeysCb')
+  let g:val = input('?')
+  call Resume()
+endfunc
+
+func Test_input_in_timer()
+  let g:val = ''
+  call timer_start(10, 'InputCb')
+  call Standby(1000)
+  call assert_equal('hello', g:val)
+endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
index d1c6119a19d7ef014a2b75500ed898a6a498ac00..d9fef0afd0e9463953475c837ffc13a714a24bdc 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    670,
 /**/
     669,
 /**/