Permalink
Browse files

patch 8.0.0592: if a job writes to a buffer screen is not updated

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.
  • Loading branch information...
brammool committed Apr 30, 2017
1 parent 45d2cca commit 29ae377ea7039874337bc79ace9ab2b37b9056e5
Showing with 81 additions and 11 deletions.
  1. +1 −1 src/channel.c
  2. +8 −1 src/ex_getln.c
  3. +1 −0 src/globals.h
  4. +1 −0 src/proto/ex_getln.pro
  5. +2 −1 src/proto/screen.pro
  6. +64 −8 src/screen.c
  7. +2 −0 src/version.c
  8. +2 −0 src/vim.h
View
@@ -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;
}
View
@@ -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();
}
View
@@ -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
View
@@ -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);
View
@@ -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);
View
@@ -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,14 +9523,20 @@ 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
&& wp->w_width == Columns
#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.
View
@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
592,
/**/
591,
/**/
View
@@ -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 */

0 comments on commit 29ae377

Please sign in to comment.