summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-06-02 20:05:26 +0200
committerBram Moolenaar <Bram@vim.org>2016-06-02 20:05:26 +0200
commitcf7c11a9479ba7ce775b86c7a846fae48321d260 (patch)
tree58b3a7cd04f178bab618232b2eb3f0e4af9a1d93
parent01d46e41ba4967ee534db4b94ad642007634841e (diff)
patch 7.4.1878v7.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.
-rw-r--r--src/channel.c21
-rw-r--r--src/os_unix.c16
-rw-r--r--src/proto/channel.pro1
-rw-r--r--src/version.c2
4 files changed, 39 insertions, 1 deletions
diff --git a/src/channel.c b/src/channel.c
index 75cadae7ab..5168f7410d 100644
--- 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)
{
diff --git a/src/os_unix.c b/src/os_unix.c
index f7b5ae4b11..b4808b5fe8 100644
--- 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();
diff --git a/src/proto/channel.pro b/src/proto/channel.pro
index 60b68f0133..2f2deb4bc8 100644
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -57,6 +57,7 @@ int free_unused_jobs_contents(int copyID, int mask);
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);
diff --git a/src/version.c b/src/version.c
index aeed591801..f450ba8bbb 100644
--- 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,