changeset 9189:4b55d8e162d4 v7.4.1878

commit https://github.com/vim/vim/commit/cf7c11a9479ba7ce775b86c7a846fae48321d260 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jun 2 20:05:26 2016 +0200 patch 7.4.1878 Problem: Whether a job has exited isn't detected until a character is typed. After calling exit_cb the cursor is in the wrong place. Solution: Don't wait forever for a character to be typed when there is a pending job. Update the screen if neede after calling exit_cb.
author Christian Brabandt <cb@256bit.org>
date Thu, 02 Jun 2016 20:15:05 +0200
parents 6de68608c4ea
children 468d1d8dc054
files src/channel.c src/os_unix.c src/proto/channel.pro src/version.c
diffstat 4 files changed, 39 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/channel.c
+++ b/src/channel.c
@@ -4403,6 +4403,21 @@ job_stop_on_exit()
 }
 
 /*
+ * Return TRUE when there is any job that might exit, which means
+ * job_check_ended() should be called once in a while.
+ */
+    int
+has_pending_job()
+{
+    job_T	    *job;
+
+    for (job = first_job; job != NULL; job = job->jv_next)
+	if (job->jv_status == JOB_STARTED && job_still_useful(job))
+	    return TRUE;
+    return FALSE;
+}
+
+/*
  * Called once in a while: check if any jobs that seem useful have ended.
  */
     void
@@ -4425,6 +4440,11 @@ job_check_ended(void)
 		job_status(job); /* may free "job" */
 	}
     }
+    if (channel_need_redraw)
+    {
+	channel_need_redraw = FALSE;
+	redraw_after_callback();
+    }
 }
 
 /*
@@ -4658,6 +4678,7 @@ job_status(job_T *job)
 			   job->jv_exit_partial, NULL);
 	    clear_tv(&rettv);
 	    --job->jv_refcount;
+	    channel_need_redraw = TRUE;
 	}
 	if (job->jv_status == JOB_ENDED && job->jv_refcount == 0)
 	{
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -438,17 +438,31 @@ mch_inchar(
 
     for (;;)	/* repeat until we got a character */
     {
+	long	wtime_now = -1L;
+
 	while (do_resize)    /* window changed size */
 	    handle_resize();
 
 #ifdef MESSAGE_QUEUE
 	parse_queued_messages();
+
+# ifdef FEAT_JOB_CHANNEL
+	if (has_pending_job())
+	{
+	    /* Don't wait longer than a few seconds, checking for a finished
+	     * job requires polling. */
+	    if (p_ut > 9000L)
+		wtime_now = 1000L;
+	    else
+		wtime_now = 10000L - p_ut;
+	}
+# endif
 #endif
 	/*
 	 * We want to be interrupted by the winch signal
 	 * or by an event on the monitored file descriptors.
 	 */
-	if (!WaitForChar(-1L))
+	if (!WaitForChar(wtime_now))
 	{
 	    if (do_resize)	    /* interrupted by SIGWINCH signal */
 		handle_resize();
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -57,6 +57,7 @@ int free_unused_jobs_contents(int copyID
 void free_unused_jobs(int copyID, int mask);
 void job_set_options(job_T *job, jobopt_T *opt);
 void job_stop_on_exit(void);
+int has_pending_job(void);
 void job_check_ended(void);
 job_T *job_start(typval_T *argvars);
 char *job_status(job_T *job);
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1878,
+/**/
     1877,
 /**/
     1876,