To: vim_dev@googlegroups.com Subject: Patch 7.4.1759 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1759 Problem: When using feedkeys() in a timer the inserted characters are not used right away. Solution: Break the wait loop when characters have been added to typebuf. use this for testing CursorHoldI. Files: src/gui.c, src/os_win32.c, src/os_unix.c, src/testdir/test_autocmd.vim *** ../vim-7.4.1758/src/gui.c 2016-03-19 22:11:47.420675007 +0100 --- src/gui.c 2016-04-20 20:00:45.803634698 +0200 *************** *** 2855,2860 **** --- 2855,2861 ---- #ifdef FEAT_TIMERS int due_time; long remaining = wtime; + int tb_change_cnt = typebuf.tb_change_cnt; /* When waiting very briefly don't trigger timers. */ if (wtime >= 0 && wtime < 10L) *************** *** 2865,2870 **** --- 2866,2876 ---- /* Trigger timers and then get the time in wtime until the next one is * due. Wait up to that time. */ due_time = check_due_timer(); + if (typebuf.tb_change_cnt != tb_change_cnt) + { + /* timer may have used feedkeys() */ + return FALSE; + } if (due_time <= 0 || (wtime > 0 && due_time > remaining)) due_time = remaining; if (gui_mch_wait_for_chars(due_time)) *** ../vim-7.4.1758/src/os_win32.c 2016-03-17 17:58:50.701456530 +0100 --- src/os_win32.c 2016-04-20 20:02:43.802483574 +0200 *************** *** 1446,1451 **** --- 1446,1452 ---- INPUT_RECORD ir; DWORD cRecords; WCHAR ch, ch2; + int tb_change_cnt = typebuf.tb_change_cnt; if (msec > 0) /* Wait until the specified time has elapsed. */ *************** *** 1511,1516 **** --- 1512,1522 ---- /* Trigger timers and then get the time in msec until the * next one is due. Wait up to that time. */ due_time = check_due_timer(); + if (typebuf.tb_change_cnt != tb_change_cnt) + { + /* timer may have used feedkeys() */ + return FALSE; + } if (due_time > 0 && dwWaitTime > (DWORD)due_time) dwWaitTime = due_time; } *** ../vim-7.4.1758/src/os_unix.c 2016-04-04 22:03:04.254923521 +0200 --- src/os_unix.c 2016-04-20 19:56:17.598244288 +0200 *************** *** 397,403 **** if (wtime >= 0) { ! while (WaitForChar(wtime) == 0) /* no character available */ { if (do_resize) handle_resize(); --- 397,403 ---- if (wtime >= 0) { ! while (!WaitForChar(wtime)) /* no character available */ { if (do_resize) handle_resize(); *************** *** 420,426 **** * flush all the swap files to disk. * Also done when interrupted by SIGWINCH. */ ! if (WaitForChar(p_ut) == 0) { #ifdef FEAT_AUTOCMD if (trigger_cursorhold() && maxlen >= 3 --- 420,426 ---- * flush all the swap files to disk. * Also done when interrupted by SIGWINCH. */ ! if (!WaitForChar(p_ut)) { #ifdef FEAT_AUTOCMD if (trigger_cursorhold() && maxlen >= 3 *************** *** 448,454 **** * We want to be interrupted by the winch signal * or by an event on the monitored file descriptors. */ ! if (WaitForChar(-1L) == 0) { if (do_resize) /* interrupted by SIGWINCH signal */ handle_resize(); --- 448,454 ---- * We want to be interrupted by the winch signal * or by an event on the monitored file descriptors. */ ! if (!WaitForChar(-1L)) { if (do_resize) /* interrupted by SIGWINCH signal */ handle_resize(); *************** *** 482,488 **** } /* ! * return non-zero if a character is available */ int mch_char_avail(void) --- 482,488 ---- } /* ! * Return non-zero if a character is available. */ int mch_char_avail(void) *************** *** 5210,5216 **** /* See above for type of argv. */ execvp(argv[0], argv); ! perror("executing job failed"); _exit(EXEC_FAILED); /* exec failed, return failure code */ } --- 5210,5216 ---- /* See above for type of argv. */ execvp(argv[0], argv); ! // perror("executing job failed"); _exit(EXEC_FAILED); /* exec failed, return failure code */ } *************** *** 5359,5364 **** --- 5359,5365 ---- * "msec" == -1 will block forever. * Invokes timer callbacks when needed. * When a GUI is being used, this will never get called -- webb + * Returns TRUE when a character is available. */ static int WaitForChar(long msec) *************** *** 5367,5372 **** --- 5368,5374 ---- long due_time; long remaining = msec; int break_loop = FALSE; + int tb_change_cnt = typebuf.tb_change_cnt; /* When waiting very briefly don't trigger timers. */ if (msec >= 0 && msec < 10L) *************** *** 5377,5382 **** --- 5379,5389 ---- /* Trigger timers and then get the time in msec until the next one is * due. Wait up to that time. */ due_time = check_due_timer(); + if (typebuf.tb_change_cnt != tb_change_cnt) + { + /* timer may have used feedkeys() */ + return FALSE; + } if (due_time <= 0 || (msec > 0 && due_time > remaining)) due_time = remaining; if (WaitForCharOrMouse(due_time, &break_loop)) *** ../vim-7.4.1758/src/testdir/test_autocmd.vim 2016-03-26 20:59:48.111431615 +0100 --- src/testdir/test_autocmd.vim 2016-04-20 20:16:29.586342591 +0200 *************** *** 6,8 **** --- 6,35 ---- " This script will never reach the main loop, can't check if v:vim_did_enter " becomes one. endfunc + + if !has('timers') + finish + endif + + func ExitInsertMode(id) + call feedkeys("\") + endfunc + + func Test_cursorhold_insert() + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(100, 'ExitInsertMode') + call feedkeys('a', 'x!') + call assert_equal(1, g:triggered) + endfunc + + func Test_cursorhold_insert_ctrl_x() + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(100, 'ExitInsertMode') + " CursorHoldI does not trigger after CTRL-X + call feedkeys("a\", 'x!') + call assert_equal(0, g:triggered) + endfunc *** ../vim-7.4.1758/src/version.c 2016-04-20 17:37:02.102439516 +0200 --- src/version.c 2016-04-20 19:59:05.724609595 +0200 *************** *** 750,751 **** --- 750,753 ---- { /* Add new patch number below this line */ + /**/ + 1759, /**/ -- DEAD PERSON: I'm getting better! CUSTOMER: No, you're not -- you'll be stone dead in a moment. MORTICIAN: Oh, I can't take him like that -- it's against regulations. The Quest for the Holy Grail (Monty Python) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///