]> granicus.if.org Git - vim/commitdiff
patch 8.0.0592: if a job writes to a buffer screen is not updated v8.0.0592
authorBram Moolenaar <Bram@vim.org>
Sun, 30 Apr 2017 17:39:39 +0000 (19:39 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 30 Apr 2017 17:39:39 +0000 (19:39 +0200)
Problem:    If a job writes to a buffer and the user is typing a command, the
            screen isn't updated. When a message is displayed the changed
            buffer may cause it to be cleared. (Ramel Eshed)
Solution:   Update the screen and then the command line if the screen didn't
            scroll. Avoid inserting screen lines, as it clears any message.
            Update the status line when the buffer changed.

src/channel.c
src/ex_getln.c
src/globals.h
src/proto/ex_getln.pro
src/proto/screen.pro
src/screen.c
src/version.c
src/vim.h

index 4039b6b25d977e6ef2c8fcedb5ebee29a2f03bb1..ffee334b54aea1e2a14d40482ca18ab4e6fd8f94 100644 (file)
@@ -2404,7 +2404,7 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, ch_part_T part)
                curbuf = curwin->w_buffer;
            }
        }
-       redraw_buf_later(buffer, VALID);
+       redraw_buf_and_status_later(buffer, VALID);
        channel_need_redraw = TRUE;
     }
 
index c42abe983f61fb5e3c3ccbf855e2347a1b89fb98..c7a6d852dfa971d5c98e91e0283c5c80ad410049 100644 (file)
@@ -3336,11 +3336,18 @@ cmdline_del(int from)
  */
     void
 redrawcmdline(void)
+{
+    redrawcmdline_ex(TRUE);
+}
+
+    void
+redrawcmdline_ex(int do_compute_cmdrow)
 {
     if (cmd_silent)
        return;
     need_wait_return = FALSE;
-    compute_cmdrow();
+    if (do_compute_cmdrow)
+       compute_cmdrow();
     redrawcmd();
     cursorcmd();
 }
index 28b71ac8511f3a4d0d8fcd5bd39be0d7dfbe8224..1d67b0d7af50d33933b31779d8bbb2e4473aefaf 100644 (file)
@@ -97,6 +97,7 @@ EXTERN int    cmdline_row;
 EXTERN int     redraw_cmdline INIT(= FALSE);   /* cmdline must be redrawn */
 EXTERN int     clear_cmdline INIT(= FALSE);    /* cmdline must be cleared */
 EXTERN int     mode_displayed INIT(= FALSE);   /* mode is being displayed */
+EXTERN int     no_win_do_lines_ins INIT(= FALSE); /* don't insert lines */
 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
 EXTERN int     cmdline_star INIT(= FALSE);     /* cmdline is crypted */
 #endif
index 58b635b9fd7481e6161e9af6e000f5e66758087d..6f8290423517fbfb96fcbbdf3686f268142fd92e 100644 (file)
@@ -19,6 +19,7 @@ char_u *save_cmdline_alloc(void);
 void restore_cmdline_alloc(char_u *p);
 void cmdline_paste_str(char_u *s, int literally);
 void redrawcmdline(void);
+void redrawcmdline_ex(int do_compute_cmdrow);
 void redrawcmd(void);
 void compute_cmdrow(void);
 void gotocmdline(int clr);
index 5bc3fbaafee91e596d9f04ebd8d8cd0611a850ab..d98e34fd9798745f4a2c2bc4f894ea781fce3b31 100644 (file)
@@ -5,11 +5,12 @@ void redraw_later_clear(void);
 void redraw_all_later(int type);
 void redraw_curbuf_later(int type);
 void redraw_buf_later(buf_T *buf, int type);
+void redraw_buf_and_status_later(buf_T *buf, int type);
 int redraw_asap(int type);
 void redraw_after_callback(void);
 void redrawWinline(linenr_T lnum, int invalid);
 void update_curbuf(int type);
-void update_screen(int type);
+void update_screen(int type_arg);
 int conceal_cursor_line(win_T *wp);
 void conceal_check_cursur_line(void);
 void update_single_line(win_T *wp, linenr_T lnum);
index fbfded1a295b5e7cfef345ce2d3e892a780066f2..43490fb8f675d40d3534fbef47e4716d5775e73e 100644 (file)
@@ -265,6 +265,21 @@ redraw_buf_later(buf_T *buf, int type)
     }
 }
 
+    void
+redraw_buf_and_status_later(buf_T *buf, int type)
+{
+    win_T      *wp;
+
+    FOR_ALL_WINDOWS(wp)
+    {
+       if (wp->w_buffer == buf)
+       {
+           redraw_win_later(wp, type);
+           wp->w_redr_status = TRUE;
+       }
+    }
+}
+
 /*
  * Redraw as soon as possible.  When the command line is not scrolled redraw
  * right away and restore what was on the command line.
@@ -421,10 +436,29 @@ redraw_after_callback(void)
     if (State == HITRETURN || State == ASKMORE)
        ; /* do nothing */
     else if (State & CMDLINE)
-       redrawcmdline();
+    {
+       /* Redrawing only works when the screen didn't scroll. */
+       if (msg_scrolled == 0)
+       {
+           update_screen(0);
+           compute_cmdrow();
+       }
+       else
+       {
+           /* Redraw in the same position, so that the user can continue
+            * editing the command. */
+           compute_cmdrow();
+           if (cmdline_row > msg_scrolled)
+               cmdline_row -= msg_scrolled;
+           else
+               cmdline_row = 0;
+       }
+       redrawcmdline_ex(FALSE);
+    }
     else if (State & (NORMAL | INSERT))
     {
-       update_screen(0);
+       /* keep the command line if possible */
+       update_screen(VALID_NO_UPDATE);
        setcursor();
     }
     cursor_on();
@@ -476,7 +510,7 @@ redrawWinline(
 }
 
 /*
- * update all windows that are editing the current buffer
+ * Update all windows that are editing the current buffer.
  */
     void
 update_curbuf(int type)
@@ -490,8 +524,9 @@ update_curbuf(int type)
  * of stuff from Filemem to ScreenLines[], and update curwin->w_botline.
  */
     void
-update_screen(int type)
+update_screen(int type_arg)
 {
+    int                type = type_arg;
     win_T      *wp;
     static int did_intro = FALSE;
 #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD)
@@ -502,11 +537,18 @@ update_screen(int type)
     int                gui_cursor_col;
     int                gui_cursor_row;
 #endif
+    int                no_update = FALSE;
 
     /* Don't do anything if the screen structures are (not yet) valid. */
     if (!screen_valid(TRUE))
        return;
 
+    if (type == VALID_NO_UPDATE)
+    {
+       no_update = TRUE;
+       type = 0;
+    }
+
     if (must_redraw)
     {
        if (type < must_redraw)     /* use maximal type */
@@ -539,6 +581,8 @@ update_screen(int type)
     ++display_tick;        /* let syntax code know we're in a next round of
                             * display updating */
 #endif
+    if (no_update)
+       ++no_win_do_lines_ins;
 
     /*
      * if the screen was scrolled up when displaying a message, scroll it down
@@ -576,7 +620,8 @@ update_screen(int type)
                    }
                }
            }
-           redraw_cmdline = TRUE;
+           if (!no_update)
+               redraw_cmdline = TRUE;
 #ifdef FEAT_WINDOWS
            redraw_tabline = TRUE;
 #endif
@@ -748,6 +793,9 @@ update_screen(int type)
     if (clear_cmdline || redraw_cmdline)
        showmode();
 
+    if (no_update)
+       --no_win_do_lines_ins;
+
     /* May put up an introductory message when not editing a file */
     if (!did_intro)
        maybe_intro_message();
@@ -9475,6 +9523,11 @@ win_do_lines(
     if (!redrawing() || line_count <= 0)
        return FAIL;
 
+    /* When inserting lines would result in loss of command output, just redraw
+     * the lines. */
+    if (no_win_do_lines_ins && !del)
+       return FAIL;
+
     /* only a few lines left: redraw is faster */
     if (mayclear && Rows - line_count < 5
 #ifdef FEAT_WINDOWS
@@ -9482,7 +9535,8 @@ win_do_lines(
 #endif
            )
     {
-       screenclear();      /* will set wp->w_lines_valid to 0 */
+       if (!no_win_do_lines_ins)
+           screenclear();          /* will set wp->w_lines_valid to 0 */
        return FAIL;
     }
 
@@ -9498,10 +9552,12 @@ win_do_lines(
     }
 
     /*
-     * when scrolling, the message on the command line should be cleared,
+     * When scrolling, the message on the command line should be cleared,
      * otherwise it will stay there forever.
+     * Don't do this when avoiding to insert lines.
      */
-    clear_cmdline = TRUE;
+    if (!no_win_do_lines_ins)
+       clear_cmdline = TRUE;
 
     /*
      * If the terminal can set a scroll region, use that.
index 45f80ee544ca663ce4b5e9f07b22478a6afcbed2..fb0d9a56b5898e2f6b3540af8931a1dc66f5e29e 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    592,
 /**/
     591,
 /**/
index 57866ef53e4d4b95a0e2f0580f0028a8ec9fec62..cbe14e5356a693ba292b624cdd9ff3c8824f571c 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -630,6 +630,8 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
  * flags for update_screen()
  * The higher the value, the higher the priority
  */
+#define VALID_NO_UPDATE                 5  /* no new changes, keep the command line if
+                                      possible */
 #define VALID                  10  /* buffer not changed, or changes marked
                                       with b_mod_* */
 #define INVERTED               20  /* redisplay inverted part that changed */