diff options
-rw-r--r-- | src/channel.c | 2 | ||||
-rw-r--r-- | src/ex_getln.c | 9 | ||||
-rw-r--r-- | src/globals.h | 1 | ||||
-rw-r--r-- | src/proto/ex_getln.pro | 1 | ||||
-rw-r--r-- | src/proto/screen.pro | 3 | ||||
-rw-r--r-- | src/screen.c | 72 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 2 |
8 files changed, 81 insertions, 11 deletions
diff --git a/src/channel.c b/src/channel.c index 4039b6b25..ffee334b5 100644 --- a/src/channel.c +++ b/src/channel.c @@ -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; } diff --git a/src/ex_getln.c b/src/ex_getln.c index c42abe983..c7a6d852d 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -3337,10 +3337,17 @@ 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(); } diff --git a/src/globals.h b/src/globals.h index 28b71ac85..1d67b0d7a 100644 --- a/src/globals.h +++ b/src/globals.h @@ -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 diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro index 58b635b9f..6f8290423 100644 --- a/src/proto/ex_getln.pro +++ b/src/proto/ex_getln.pro @@ -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); diff --git a/src/proto/screen.pro b/src/proto/screen.pro index 5bc3fbaaf..d98e34fd9 100644 --- a/src/proto/screen.pro +++ b/src/proto/screen.pro @@ -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); diff --git a/src/screen.c b/src/screen.c index fbfded1a2..43490fb8f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -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. diff --git a/src/version.c b/src/version.c index 45f80ee54..fb0d9a56b 100644 --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 592, +/**/ 591, /**/ 590, @@ -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 */ |