0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

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.
This commit is contained in:
Bram Moolenaar
2017-04-30 19:39:39 +02:00
parent 45d2cca1ea
commit 29ae377ea7
8 changed files with 81 additions and 11 deletions

View 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; curbuf = curwin->w_buffer;
} }
} }
redraw_buf_later(buffer, VALID); redraw_buf_and_status_later(buffer, VALID);
channel_need_redraw = TRUE; channel_need_redraw = TRUE;
} }

View File

@@ -3336,10 +3336,17 @@ cmdline_del(int from)
*/ */
void void
redrawcmdline(void) redrawcmdline(void)
{
redrawcmdline_ex(TRUE);
}
void
redrawcmdline_ex(int do_compute_cmdrow)
{ {
if (cmd_silent) if (cmd_silent)
return; return;
need_wait_return = FALSE; need_wait_return = FALSE;
if (do_compute_cmdrow)
compute_cmdrow(); compute_cmdrow();
redrawcmd(); redrawcmd();
cursorcmd(); cursorcmd();

View File

@@ -97,6 +97,7 @@ EXTERN int cmdline_row;
EXTERN int redraw_cmdline INIT(= FALSE); /* cmdline must be redrawn */ EXTERN int redraw_cmdline INIT(= FALSE); /* cmdline must be redrawn */
EXTERN int clear_cmdline INIT(= FALSE); /* cmdline must be cleared */ EXTERN int clear_cmdline INIT(= FALSE); /* cmdline must be cleared */
EXTERN int mode_displayed INIT(= FALSE); /* mode is being displayed */ 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) #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */ EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */
#endif #endif

View File

@@ -19,6 +19,7 @@ char_u *save_cmdline_alloc(void);
void restore_cmdline_alloc(char_u *p); void restore_cmdline_alloc(char_u *p);
void cmdline_paste_str(char_u *s, int literally); void cmdline_paste_str(char_u *s, int literally);
void redrawcmdline(void); void redrawcmdline(void);
void redrawcmdline_ex(int do_compute_cmdrow);
void redrawcmd(void); void redrawcmd(void);
void compute_cmdrow(void); void compute_cmdrow(void);
void gotocmdline(int clr); void gotocmdline(int clr);

View File

@@ -5,11 +5,12 @@ void redraw_later_clear(void);
void redraw_all_later(int type); void redraw_all_later(int type);
void redraw_curbuf_later(int type); void redraw_curbuf_later(int type);
void redraw_buf_later(buf_T *buf, 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); int redraw_asap(int type);
void redraw_after_callback(void); void redraw_after_callback(void);
void redrawWinline(linenr_T lnum, int invalid); void redrawWinline(linenr_T lnum, int invalid);
void update_curbuf(int type); void update_curbuf(int type);
void update_screen(int type); void update_screen(int type_arg);
int conceal_cursor_line(win_T *wp); int conceal_cursor_line(win_T *wp);
void conceal_check_cursur_line(void); void conceal_check_cursur_line(void);
void update_single_line(win_T *wp, linenr_T lnum); void update_single_line(win_T *wp, linenr_T lnum);

View 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 * Redraw as soon as possible. When the command line is not scrolled redraw
* right away and restore what was on the command line. * right away and restore what was on the command line.
@@ -421,10 +436,29 @@ redraw_after_callback(void)
if (State == HITRETURN || State == ASKMORE) if (State == HITRETURN || State == ASKMORE)
; /* do nothing */ ; /* do nothing */
else if (State & CMDLINE) else if (State & CMDLINE)
redrawcmdline(); {
else if (State & (NORMAL | INSERT)) /* Redrawing only works when the screen didn't scroll. */
if (msg_scrolled == 0)
{ {
update_screen(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))
{
/* keep the command line if possible */
update_screen(VALID_NO_UPDATE);
setcursor(); setcursor();
} }
cursor_on(); 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 void
update_curbuf(int type) update_curbuf(int type)
@@ -490,8 +524,9 @@ update_curbuf(int type)
* of stuff from Filemem to ScreenLines[], and update curwin->w_botline. * of stuff from Filemem to ScreenLines[], and update curwin->w_botline.
*/ */
void void
update_screen(int type) update_screen(int type_arg)
{ {
int type = type_arg;
win_T *wp; win_T *wp;
static int did_intro = FALSE; static int did_intro = FALSE;
#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD) #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD)
@@ -502,11 +537,18 @@ update_screen(int type)
int gui_cursor_col; int gui_cursor_col;
int gui_cursor_row; int gui_cursor_row;
#endif #endif
int no_update = FALSE;
/* Don't do anything if the screen structures are (not yet) valid. */ /* Don't do anything if the screen structures are (not yet) valid. */
if (!screen_valid(TRUE)) if (!screen_valid(TRUE))
return; return;
if (type == VALID_NO_UPDATE)
{
no_update = TRUE;
type = 0;
}
if (must_redraw) if (must_redraw)
{ {
if (type < must_redraw) /* use maximal type */ 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_tick; /* let syntax code know we're in a next round of
* display updating */ * display updating */
#endif #endif
if (no_update)
++no_win_do_lines_ins;
/* /*
* if the screen was scrolled up when displaying a message, scroll it down * if the screen was scrolled up when displaying a message, scroll it down
@@ -576,6 +620,7 @@ update_screen(int type)
} }
} }
} }
if (!no_update)
redraw_cmdline = TRUE; redraw_cmdline = TRUE;
#ifdef FEAT_WINDOWS #ifdef FEAT_WINDOWS
redraw_tabline = TRUE; redraw_tabline = TRUE;
@@ -748,6 +793,9 @@ update_screen(int type)
if (clear_cmdline || redraw_cmdline) if (clear_cmdline || redraw_cmdline)
showmode(); showmode();
if (no_update)
--no_win_do_lines_ins;
/* May put up an introductory message when not editing a file */ /* May put up an introductory message when not editing a file */
if (!did_intro) if (!did_intro)
maybe_intro_message(); maybe_intro_message();
@@ -9475,6 +9523,11 @@ win_do_lines(
if (!redrawing() || line_count <= 0) if (!redrawing() || line_count <= 0)
return FAIL; 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 */ /* only a few lines left: redraw is faster */
if (mayclear && Rows - line_count < 5 if (mayclear && Rows - line_count < 5
#ifdef FEAT_WINDOWS #ifdef FEAT_WINDOWS
@@ -9482,6 +9535,7 @@ win_do_lines(
#endif #endif
) )
{ {
if (!no_win_do_lines_ins)
screenclear(); /* will set wp->w_lines_valid to 0 */ screenclear(); /* will set wp->w_lines_valid to 0 */
return FAIL; return FAIL;
} }
@@ -9498,9 +9552,11 @@ 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. * otherwise it will stay there forever.
* Don't do this when avoiding to insert lines.
*/ */
if (!no_win_do_lines_ins)
clear_cmdline = TRUE; clear_cmdline = TRUE;
/* /*

View File

@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
592,
/**/ /**/
591, 591,
/**/ /**/

View File

@@ -630,6 +630,8 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
* flags for update_screen() * flags for update_screen()
* The higher the value, the higher the priority * 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 #define VALID 10 /* buffer not changed, or changes marked
with b_mod_* */ with b_mod_* */
#define INVERTED 20 /* redisplay inverted part that changed */ #define INVERTED 20 /* redisplay inverted part that changed */