]> granicus.if.org Git - vim/commitdiff
patch 8.0.0854: no redraw after terminal was closed v8.0.0854
authorBram Moolenaar <Bram@vim.org>
Thu, 3 Aug 2017 18:44:48 +0000 (20:44 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 3 Aug 2017 18:44:48 +0000 (20:44 +0200)
Problem:    No redraw after terminal was closed.
Solution:   Set typebuf_was_filled. (Yasuhiro Matsumoto, closes #1925, closes
            #1924)  Add function to check for messages even when input is
            available.

src/os_mswin.c
src/os_unix.c
src/os_win32.c
src/proto/os_unix.pro
src/proto/os_win32.pro
src/terminal.c
src/version.c

index 696847e50c7ad36d5a45a0779e871568daacb213..dd420122248f6092c14bd82c81de52a7d86aa314 100644 (file)
@@ -809,6 +809,18 @@ mch_char_avail(void)
     /* never used */
     return TRUE;
 }
+
+# if defined(FEAT_TERMINAL) || defined(PROTO)
+/*
+ * Check for any pending input or messages.
+ */
+    int
+mch_check_messages(void)
+{
+    /* TODO: check for messages */
+    return TRUE;
+}
+# endif
 #endif
 
 
index c90ab34f621eba26282ee5f3aec530fc75f4acab..ade8d88187547eb762a71da8fcd89dd721226c4b 100644 (file)
@@ -175,8 +175,8 @@ typedef int waitstatus;
 #endif
 static pid_t wait4pid(pid_t, waitstatus *);
 
-static int  WaitForChar(long msec, int *interrupted);
-static int  WaitForCharOrMouse(long msec, int *interrupted);
+static int  WaitForChar(long msec, int *interrupted, int ignore_input);
+static int  WaitForCharOrMouse(long msec, int *interrupted, int ignore_input);
 #if defined(__BEOS__) || defined(VMS)
 int  RealWaitForChar(int, long, int *, int *interrupted);
 #else
@@ -481,7 +481,7 @@ mch_inchar(
         * We want to be interrupted by the winch signal
         * or by an event on the monitored file descriptors.
         */
-       if (WaitForChar(wait_time, &interrupted))
+       if (WaitForChar(wait_time, &interrupted, FALSE))
        {
            /* If input was put directly in typeahead buffer bail out here. */
            if (typebuf_changed(tb_change_cnt))
@@ -536,9 +536,20 @@ handle_resize(void)
     int
 mch_char_avail(void)
 {
-    return WaitForChar(0L, NULL);
+    return WaitForChar(0L, NULL, FALSE);
 }
 
+#if defined(FEAT_TERMINAL) || defined(PROTO)
+/*
+ * Check for any pending input or messages.
+ */
+    int
+mch_check_messages(void)
+{
+    return WaitForChar(0L, NULL, TRUE);
+}
+#endif
+
 #if defined(HAVE_TOTAL_MEM) || defined(PROTO)
 # ifdef HAVE_SYS_RESOURCE_H
 #  include <sys/resource.h>
@@ -718,7 +729,7 @@ mch_delay(long msec, int ignoreinput)
        in_mch_delay = FALSE;
     }
     else
-       WaitForChar(msec, NULL);
+       WaitForChar(msec, NULL, FALSE);
 }
 
 #if defined(HAVE_STACK_LIMIT) \
@@ -5616,13 +5627,15 @@ mch_breakcheck(int force)
  * from inbuf[].
  * "msec" == -1 will block forever.
  * Invokes timer callbacks when needed.
+ * When "ignore_input" is TRUE even check for pending input when input is
+ * already available.
  * "interrupted" (if not NULL) is set to TRUE when no character is available
  * but something else needs to be done.
  * Returns TRUE when a character is available.
  * When a GUI is being used, this will never get called -- webb
  */
     static int
-WaitForChar(long msec, int *interrupted)
+WaitForChar(long msec, int *interrupted, int ignore_input)
 {
 #ifdef FEAT_TIMERS
     long    due_time;
@@ -5631,7 +5644,7 @@ WaitForChar(long msec, int *interrupted)
 
     /* When waiting very briefly don't trigger timers. */
     if (msec >= 0 && msec < 10L)
-       return WaitForCharOrMouse(msec, NULL);
+       return WaitForCharOrMouse(msec, NULL, ignore_input);
 
     while (msec < 0 || remaining > 0)
     {
@@ -5645,7 +5658,7 @@ WaitForChar(long msec, int *interrupted)
        }
        if (due_time <= 0 || (msec > 0 && due_time > remaining))
            due_time = remaining;
-       if (WaitForCharOrMouse(due_time, interrupted))
+       if (WaitForCharOrMouse(due_time, interrupted, ignore_input))
            return TRUE;
        if (interrupted != NULL && *interrupted)
            /* Nothing available, but need to return so that side effects get
@@ -5656,7 +5669,7 @@ WaitForChar(long msec, int *interrupted)
     }
     return FALSE;
 #else
-    return WaitForCharOrMouse(msec, interrupted);
+    return WaitForCharOrMouse(msec, interrupted, ignore_input);
 #endif
 }
 
@@ -5664,12 +5677,13 @@ WaitForChar(long msec, int *interrupted)
  * Wait "msec" msec until a character is available from the mouse or keyboard
  * or from inbuf[].
  * "msec" == -1 will block forever.
+ * for "ignore_input" see WaitForCharOr().
  * "interrupted" (if not NULL) is set to TRUE when no character is available
  * but something else needs to be done.
  * When a GUI is being used, this will never get called -- webb
  */
     static int
-WaitForCharOrMouse(long msec, int *interrupted)
+WaitForCharOrMouse(long msec, int *interrupted, int ignore_input)
 {
 #ifdef FEAT_MOUSE_GPM
     int                gpm_process_wanted;
@@ -5679,7 +5693,7 @@ WaitForCharOrMouse(long msec, int *interrupted)
 #endif
     int                avail;
 
-    if (input_available())         /* something in inbuf[] */
+    if (!ignore_input && input_available())        /* something in inbuf[] */
        return 1;
 
 #if defined(FEAT_MOUSE_DEC)
@@ -5722,7 +5736,7 @@ WaitForCharOrMouse(long msec, int *interrupted)
 # endif
        if (!avail)
        {
-           if (input_available())
+           if (!ignore_input && input_available())
                return 1;
 # ifdef FEAT_XCLIPBOARD
            if (rest == 0 || !do_xterm_trace())
index d3cab022348da4c36c2a6daaad80e03770d38e18..f75040c11f3e3c56c57ee7899ebbb7cc38b591a3 100644 (file)
@@ -1400,10 +1400,11 @@ handle_focus_event(INPUT_RECORD ir)
 /*
  * Wait until console input from keyboard or mouse is available,
  * or the time is up.
+ * When "ignore_input" is TRUE even wait when input is available.
  * Return TRUE if something is available FALSE if not.
  */
     static int
-WaitForChar(long msec)
+WaitForChar(long msec, int ignore_input)
 {
     DWORD          dwNow = 0, dwEndTime = 0;
     INPUT_RECORD    ir;
@@ -1440,7 +1441,7 @@ WaitForChar(long msec)
                || g_nMouseClick != -1
 #endif
 #ifdef FEAT_CLIENTSERVER
-               || input_available()
+               || (!ignore_input && input_available())
 #endif
           )
            return TRUE;
@@ -1583,8 +1584,19 @@ WaitForChar(long msec)
     int
 mch_char_avail(void)
 {
-    return WaitForChar(0L);
+    return WaitForChar(0L, FALSE);
 }
+
+# if defined(FEAT_TERMINAL) || defined(PROTO)
+/*
+ * Check for any pending input or messages.
+ */
+    int
+mch_check_messages(void)
+{
+    return WaitForChar(0L, TRUE);
+}
+# endif
 #endif
 
 /*
@@ -1614,7 +1626,7 @@ tgetch(int *pmodifiers, WCHAR *pch2)
        DWORD cRecords = 0;
 
 #ifdef FEAT_CLIENTSERVER
-       (void)WaitForChar(-1L);
+       (void)WaitForChar(-1L, FALSE);
        if (input_available())
            return 0;
 # ifdef FEAT_MOUSE
@@ -1681,7 +1693,7 @@ mch_inchar(
 
     if (time >= 0)
     {
-       if (!WaitForChar(time))     /* no character available */
+       if (!WaitForChar(time, FALSE))     /* no character available */
            return 0;
     }
     else    /* time == -1, wait forever */
@@ -1693,7 +1705,7 @@ mch_inchar(
         * write the autoscript file to disk.  Or cause the CursorHold event
         * to be triggered.
         */
-       if (!WaitForChar(p_ut))
+       if (!WaitForChar(p_ut, FALSE))
        {
 #ifdef FEAT_AUTOCMD
            if (trigger_cursorhold() && maxlen >= 3)
@@ -1723,7 +1735,7 @@ mch_inchar(
     /* Keep looping until there is something in the typeahead buffer and more
      * to get and still room in the buffer (up to two bytes for a char and
      * three bytes for a modifier). */
-    while ((typeaheadlen == 0 || WaitForChar(0L))
+    while ((typeaheadlen == 0 || WaitForChar(0L, FALSE))
                                          && typeaheadlen + 5 <= TYPEAHEADLEN)
     {
        if (typebuf_changed(tb_change_cnt))
@@ -5721,7 +5733,7 @@ cursor_visible(BOOL fVisible)
 
 
 /*
- * write `cbToWrite' bytes in `pchBuf' to the screen
+ * Write "cbToWrite" bytes in `pchBuf' to the screen.
  * Returns the number of bytes actually written (at least one).
  */
     static DWORD
@@ -5828,7 +5840,7 @@ mch_write(
 
        if (p_wd)
        {
-           WaitForChar(p_wd);
+           WaitForChar(p_wd, FALSE);
            if (prefix != 0)
                prefix = 1;
        }
@@ -6120,7 +6132,7 @@ mch_delay(
 # endif
            Sleep((int)msec);
     else
-       WaitForChar(msec);
+       WaitForChar(msec, FALSE);
 #endif
 }
 
index 46230dc15d2be93287fc5ebb84836d9b31787197..8e955aa7b1c1967a0b166015fe77f85ecd55b2af 100644 (file)
@@ -3,6 +3,7 @@ int mch_chdir(char *path);
 void mch_write(char_u *s, int len);
 int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
 int mch_char_avail(void);
+int mch_check_messages(void);
 long_u mch_total_mem(int special);
 void mch_delay(long msec, int ignoreinput);
 int mch_stackcheck(char *p);
index 4e0629867a4439f97fdc88ed12795dc475fc8de2..bc16a193aa10acc37c0450eec2b9ed31794955be 100644 (file)
@@ -8,6 +8,7 @@ void PlatformId(void);
 void mch_setmouse(int on);
 void mch_update_cursor(void);
 int mch_char_avail(void);
+int mch_check_messages(void);
 int mch_inchar(char_u *buf, int maxlen, long time, int tb_change_cnt);
 void mch_init(void);
 void mch_exit(int r);
index b06feffc2fbba5bb8988a67dc095249fc3d9918f..9c165337bed9275cd3be8f63541367adb0fe0a99 100644 (file)
@@ -1305,6 +1305,7 @@ term_channel_closed(channel_T *ch)
 
        /* Need to break out of vgetc(). */
        ins_char_typebuf(K_IGNORE);
+       typebuf_was_filled = TRUE;
 
        term = curbuf->b_term;
        if (term != NULL)
@@ -2140,31 +2141,36 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
        ch_log(NULL, "term_wait(): invalid argument");
        return;
     }
+    if (buf->b_term->tl_job == NULL)
+    {
+       ch_log(NULL, "term_wait(): no job to wait for");
+       return;
+    }
 
     /* Get the job status, this will detect a job that finished. */
-    if (buf->b_term->tl_job == NULL
-           || STRCMP(job_status(buf->b_term->tl_job), "dead") == 0)
+    if (STRCMP(job_status(buf->b_term->tl_job), "dead") == 0)
     {
        /* The job is dead, keep reading channel I/O until the channel is
         * closed. */
+       ch_log(NULL, "term_wait(): waiting for channel to close");
        while (buf->b_term != NULL && !buf->b_term->tl_channel_closed)
        {
-           mch_char_avail();
+           mch_check_messages();
            parse_queued_messages();
            ui_delay(10L, FALSE);
        }
-       mch_char_avail();
+       mch_check_messages();
        parse_queued_messages();
     }
     else
     {
-       mch_char_avail();
+       mch_check_messages();
        parse_queued_messages();
 
        /* Wait for 10 msec for any channel I/O. */
        /* TODO: use delay from optional argument */
        ui_delay(10L, TRUE);
-       mch_char_avail();
+       mch_check_messages();
 
        /* Flushing messages on channels is hopefully sufficient.
         * TODO: is there a better way? */
index 617042584b15d3130f390f15450d2cb2b1b1d48b..25750b5c63457d5f1a33df21d889e6a17b1dc641 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    854,
 /**/
     853,
 /**/