Skip to content

Commit 29ae377

Browse files
committed
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.
1 parent 45d2cca commit 29ae377

File tree

8 files changed

+81
-11
lines changed

8 files changed

+81
-11
lines changed

src/channel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2404,7 +2404,7 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, ch_part_T part)
24042404
curbuf = curwin->w_buffer;
24052405
}
24062406
}
2407-
redraw_buf_later(buffer, VALID);
2407+
redraw_buf_and_status_later(buffer, VALID);
24082408
channel_need_redraw = TRUE;
24092409
}
24102410

src/ex_getln.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3336,11 +3336,18 @@ cmdline_del(int from)
33363336
*/
33373337
void
33383338
redrawcmdline(void)
3339+
{
3340+
redrawcmdline_ex(TRUE);
3341+
}
3342+
3343+
void
3344+
redrawcmdline_ex(int do_compute_cmdrow)
33393345
{
33403346
if (cmd_silent)
33413347
return;
33423348
need_wait_return = FALSE;
3343-
compute_cmdrow();
3349+
if (do_compute_cmdrow)
3350+
compute_cmdrow();
33443351
redrawcmd();
33453352
cursorcmd();
33463353
}

src/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ EXTERN int cmdline_row;
9797
EXTERN int redraw_cmdline INIT(= FALSE); /* cmdline must be redrawn */
9898
EXTERN int clear_cmdline INIT(= FALSE); /* cmdline must be cleared */
9999
EXTERN int mode_displayed INIT(= FALSE); /* mode is being displayed */
100+
EXTERN int no_win_do_lines_ins INIT(= FALSE); /* don't insert lines */
100101
#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
101102
EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */
102103
#endif

src/proto/ex_getln.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ char_u *save_cmdline_alloc(void);
1919
void restore_cmdline_alloc(char_u *p);
2020
void cmdline_paste_str(char_u *s, int literally);
2121
void redrawcmdline(void);
22+
void redrawcmdline_ex(int do_compute_cmdrow);
2223
void redrawcmd(void);
2324
void compute_cmdrow(void);
2425
void gotocmdline(int clr);

src/proto/screen.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ void redraw_later_clear(void);
55
void redraw_all_later(int type);
66
void redraw_curbuf_later(int type);
77
void redraw_buf_later(buf_T *buf, int type);
8+
void redraw_buf_and_status_later(buf_T *buf, int type);
89
int redraw_asap(int type);
910
void redraw_after_callback(void);
1011
void redrawWinline(linenr_T lnum, int invalid);
1112
void update_curbuf(int type);
12-
void update_screen(int type);
13+
void update_screen(int type_arg);
1314
int conceal_cursor_line(win_T *wp);
1415
void conceal_check_cursur_line(void);
1516
void update_single_line(win_T *wp, linenr_T lnum);

src/screen.c

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,21 @@ redraw_buf_later(buf_T *buf, int type)
265265
}
266266
}
267267

268+
void
269+
redraw_buf_and_status_later(buf_T *buf, int type)
270+
{
271+
win_T *wp;
272+
273+
FOR_ALL_WINDOWS(wp)
274+
{
275+
if (wp->w_buffer == buf)
276+
{
277+
redraw_win_later(wp, type);
278+
wp->w_redr_status = TRUE;
279+
}
280+
}
281+
}
282+
268283
/*
269284
* Redraw as soon as possible. When the command line is not scrolled redraw
270285
* right away and restore what was on the command line.
@@ -421,10 +436,29 @@ redraw_after_callback(void)
421436
if (State == HITRETURN || State == ASKMORE)
422437
; /* do nothing */
423438
else if (State & CMDLINE)
424-
redrawcmdline();
439+
{
440+
/* Redrawing only works when the screen didn't scroll. */
441+
if (msg_scrolled == 0)
442+
{
443+
update_screen(0);
444+
compute_cmdrow();
445+
}
446+
else
447+
{
448+
/* Redraw in the same position, so that the user can continue
449+
* editing the command. */
450+
compute_cmdrow();
451+
if (cmdline_row > msg_scrolled)
452+
cmdline_row -= msg_scrolled;
453+
else
454+
cmdline_row = 0;
455+
}
456+
redrawcmdline_ex(FALSE);
457+
}
425458
else if (State & (NORMAL | INSERT))
426459
{
427-
update_screen(0);
460+
/* keep the command line if possible */
461+
update_screen(VALID_NO_UPDATE);
428462
setcursor();
429463
}
430464
cursor_on();
@@ -476,7 +510,7 @@ redrawWinline(
476510
}
477511

478512
/*
479-
* update all windows that are editing the current buffer
513+
* Update all windows that are editing the current buffer.
480514
*/
481515
void
482516
update_curbuf(int type)
@@ -490,8 +524,9 @@ update_curbuf(int type)
490524
* of stuff from Filemem to ScreenLines[], and update curwin->w_botline.
491525
*/
492526
void
493-
update_screen(int type)
527+
update_screen(int type_arg)
494528
{
529+
int type = type_arg;
495530
win_T *wp;
496531
static int did_intro = FALSE;
497532
#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CLIPBOARD)
@@ -502,11 +537,18 @@ update_screen(int type)
502537
int gui_cursor_col;
503538
int gui_cursor_row;
504539
#endif
540+
int no_update = FALSE;
505541

506542
/* Don't do anything if the screen structures are (not yet) valid. */
507543
if (!screen_valid(TRUE))
508544
return;
509545

546+
if (type == VALID_NO_UPDATE)
547+
{
548+
no_update = TRUE;
549+
type = 0;
550+
}
551+
510552
if (must_redraw)
511553
{
512554
if (type < must_redraw) /* use maximal type */
@@ -539,6 +581,8 @@ update_screen(int type)
539581
++display_tick; /* let syntax code know we're in a next round of
540582
* display updating */
541583
#endif
584+
if (no_update)
585+
++no_win_do_lines_ins;
542586

543587
/*
544588
* if the screen was scrolled up when displaying a message, scroll it down
@@ -576,7 +620,8 @@ update_screen(int type)
576620
}
577621
}
578622
}
579-
redraw_cmdline = TRUE;
623+
if (!no_update)
624+
redraw_cmdline = TRUE;
580625
#ifdef FEAT_WINDOWS
581626
redraw_tabline = TRUE;
582627
#endif
@@ -748,6 +793,9 @@ update_screen(int type)
748793
if (clear_cmdline || redraw_cmdline)
749794
showmode();
750795

796+
if (no_update)
797+
--no_win_do_lines_ins;
798+
751799
/* May put up an introductory message when not editing a file */
752800
if (!did_intro)
753801
maybe_intro_message();
@@ -9475,14 +9523,20 @@ win_do_lines(
94759523
if (!redrawing() || line_count <= 0)
94769524
return FAIL;
94779525

9526+
/* When inserting lines would result in loss of command output, just redraw
9527+
* the lines. */
9528+
if (no_win_do_lines_ins && !del)
9529+
return FAIL;
9530+
94789531
/* only a few lines left: redraw is faster */
94799532
if (mayclear && Rows - line_count < 5
94809533
#ifdef FEAT_WINDOWS
94819534
&& wp->w_width == Columns
94829535
#endif
94839536
)
94849537
{
9485-
screenclear(); /* will set wp->w_lines_valid to 0 */
9538+
if (!no_win_do_lines_ins)
9539+
screenclear(); /* will set wp->w_lines_valid to 0 */
94869540
return FAIL;
94879541
}
94889542

@@ -9498,10 +9552,12 @@ win_do_lines(
94989552
}
94999553

95009554
/*
9501-
* when scrolling, the message on the command line should be cleared,
9555+
* When scrolling, the message on the command line should be cleared,
95029556
* otherwise it will stay there forever.
9557+
* Don't do this when avoiding to insert lines.
95039558
*/
9504-
clear_cmdline = TRUE;
9559+
if (!no_win_do_lines_ins)
9560+
clear_cmdline = TRUE;
95059561

95069562
/*
95079563
* If the terminal can set a scroll region, use that.

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
592,
767769
/**/
768770
591,
769771
/**/

src/vim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
630630
* flags for update_screen()
631631
* The higher the value, the higher the priority
632632
*/
633+
#define VALID_NO_UPDATE 5 /* no new changes, keep the command line if
634+
possible */
633635
#define VALID 10 /* buffer not changed, or changes marked
634636
with b_mod_* */
635637
#define INVERTED 20 /* redisplay inverted part that changed */

0 commit comments

Comments
 (0)