[vim] 75/139: 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.

James McCoy jamessan at debian.org
Fri May 6 04:00:06 UTC 2016


This is an automated email from the git hooks/post-receive script.

jamessan pushed a commit to branch debian/sid
in repository vim.

commit 40b1b5443c88fab77f1f7c6f9e801f7ffdb7e0a8
Author: Bram Moolenaar <Bram at vim.org>
Date:   Wed Apr 20 20:18:23 2016 +0200

    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.
---
 src/gui.c                    |  6 ++++++
 src/os_unix.c                | 17 ++++++++++++-----
 src/os_win32.c               |  6 ++++++
 src/testdir/test_autocmd.vim | 27 +++++++++++++++++++++++++++
 src/version.c                |  2 ++
 5 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/src/gui.c b/src/gui.c
index 8999f79..d747d81 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -2855,6 +2855,7 @@ gui_wait_for_chars_or_timer(long wtime)
 #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,6 +2866,11 @@ gui_wait_for_chars_or_timer(long wtime)
 	/* 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))
diff --git a/src/os_unix.c b/src/os_unix.c
index 58a27da..f8cf691 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -397,7 +397,7 @@ mch_inchar(
 
     if (wtime >= 0)
     {
-	while (WaitForChar(wtime) == 0)		/* no character available */
+	while (!WaitForChar(wtime))		/* no character available */
 	{
 	    if (do_resize)
 		handle_resize();
@@ -420,7 +420,7 @@ mch_inchar(
 	 * flush all the swap files to disk.
 	 * Also done when interrupted by SIGWINCH.
 	 */
-	if (WaitForChar(p_ut) == 0)
+	if (!WaitForChar(p_ut))
 	{
 #ifdef FEAT_AUTOCMD
 	    if (trigger_cursorhold() && maxlen >= 3
@@ -448,7 +448,7 @@ mch_inchar(
 	 * We want to be interrupted by the winch signal
 	 * or by an event on the monitored file descriptors.
 	 */
-	if (WaitForChar(-1L) == 0)
+	if (!WaitForChar(-1L))
 	{
 	    if (do_resize)	    /* interrupted by SIGWINCH signal */
 		handle_resize();
@@ -482,7 +482,7 @@ handle_resize(void)
 }
 
 /*
- * return non-zero if a character is available
+ * Return non-zero if a character is available.
  */
     int
 mch_char_avail(void)
@@ -5210,7 +5210,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
 	/* See above for type of argv. */
 	execvp(argv[0], argv);
 
-	perror("executing job failed");
+	// perror("executing job failed");
 	_exit(EXEC_FAILED);	    /* exec failed, return failure code */
     }
 
@@ -5359,6 +5359,7 @@ mch_breakcheck(void)
  * "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,6 +5368,7 @@ WaitForChar(long msec)
     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,6 +5379,11 @@ WaitForChar(long msec)
 	/* 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))
diff --git a/src/os_win32.c b/src/os_win32.c
index 627d515..159905d 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -1446,6 +1446,7 @@ WaitForChar(long msec)
     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,6 +1512,11 @@ WaitForChar(long msec)
 		    /* 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;
 		}
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 12c9848..d3e0981 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -6,3 +6,30 @@ func Test_vim_did_enter()
   " 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("\<Esc>")
+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\<C-X>", 'x!')
+  call assert_equal(0, g:triggered)
+endfunc
diff --git a/src/version.c b/src/version.c
index 0993f66..f550196 100644
--- a/src/version.c
+++ b/src/version.c
@@ -749,6 +749,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1759,
+/**/
     1758,
 /**/
     1757,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vim/vim.git



More information about the pkg-vim-maintainers mailing list