@@ -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
482516update_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.
0 commit comments