# HG changeset patch # User Christian Brabandt # Date 1489690805 -3600 # Node ID f4d1fad4ac00c20df55ebe8855136e01ab95f9dd # Parent 406ed314f018699fbcffb32929f583b840129bbd patch 8.0.0468: after aborting an Ex command g< does not work commit https://github.com/vim/vim/commit/f2405ed2321da4a879fe0b0703af780fc0432c63 Author: Bram Moolenaar Date: Thu Mar 16 19:58:25 2017 +0100 patch 8.0.0468: after aborting an Ex command g< does not work Problem: After aborting an Ex command g< does not work. (Marcin Szamotulski) Solution: Postpone clearing scrollback messages to until the command line has been entered. Also fix that the screen isn't redrawn if after g< the command line is cancelled. diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -258,6 +258,7 @@ getcmdline( return NULL; /* out of memory */ ccline.cmdlen = ccline.cmdpos = 0; ccline.cmdbuff[0] = NUL; + sb_text_start_cmdline(); /* autoindent for :insert and :append */ if (firstc <= 0) @@ -2083,6 +2084,7 @@ returncmd: #ifdef CURSOR_SHAPE ui_cursor_shape(); /* may show different cursor shape */ #endif + sb_text_end_cmdline(); { char_u *p = ccline.cmdbuff; diff --git a/src/gui.c b/src/gui.c --- a/src/gui.c +++ b/src/gui.c @@ -630,7 +630,7 @@ gui_init(void) * where Vim was started. */ emsg_on_display = FALSE; msg_scrolled = 0; - clear_sb_text(); + clear_sb_text(TRUE); need_wait_return = FALSE; msg_didany = FALSE; diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -2146,8 +2146,6 @@ msg_puts_display( inc_msg_scrolled(); need_wait_return = TRUE; /* may need wait_return in main() */ - if (must_redraw < VALID) - must_redraw = VALID; redraw_cmdline = TRUE; if (cmdline_row > 0 && !exmode_active) --cmdline_row; @@ -2367,6 +2365,8 @@ inc_msg_scrolled(void) } #endif ++msg_scrolled; + if (must_redraw < VALID) + must_redraw = VALID; } /* @@ -2389,7 +2389,15 @@ static msgchunk_T *last_msgchunk = NULL; static msgchunk_T *msg_sb_start(msgchunk_T *mps); static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp); -static int do_clear_sb_text = FALSE; /* clear text on next msg */ +typedef enum { + SB_CLEAR_NONE = 0, + SB_CLEAR_ALL, + SB_CLEAR_CMDLINE_BUSY, + SB_CLEAR_CMDLINE_DONE +} sb_clear_T; + +/* When to clear text on next msg. */ +static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE; /* * Store part of a printed message for displaying when scrolling back. @@ -2404,10 +2412,11 @@ store_sb_text( { msgchunk_T *mp; - if (do_clear_sb_text) + if (do_clear_sb_text == SB_CLEAR_ALL + || do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) { - clear_sb_text(); - do_clear_sb_text = FALSE; + clear_sb_text(do_clear_sb_text == SB_CLEAR_ALL); + do_clear_sb_text = SB_CLEAR_NONE; } if (s > *sb_str) @@ -2447,23 +2456,53 @@ store_sb_text( void may_clear_sb_text(void) { - do_clear_sb_text = TRUE; + do_clear_sb_text = SB_CLEAR_ALL; +} + +/* + * Starting to edit the command line, do not clear messages now. + */ + void +sb_text_start_cmdline(void) +{ + do_clear_sb_text = SB_CLEAR_CMDLINE_BUSY; + msg_sb_eol(); +} + +/* + * Ending to edit the command line. Clear old lines but the last one later. + */ + void +sb_text_end_cmdline(void) +{ + do_clear_sb_text = SB_CLEAR_CMDLINE_DONE; } /* * Clear any text remembered for scrolling back. + * When "all" is FALSE keep the last line. * Called when redrawing the screen. */ void -clear_sb_text(void) +clear_sb_text(int all) { msgchunk_T *mp; - - while (last_msgchunk != NULL) + msgchunk_T **lastp; + + if (all) + lastp = &last_msgchunk; + else { - mp = last_msgchunk->sb_prev; - vim_free(last_msgchunk); - last_msgchunk = mp; + if (last_msgchunk == NULL) + return; + lastp = &last_msgchunk->sb_prev; + } + + while (*lastp != NULL) + { + mp = (*lastp)->sb_prev; + vim_free(*lastp); + *lastp = mp; } } diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -970,7 +970,7 @@ lalloc(long_u size, int message) break; releasing = TRUE; - clear_sb_text(); /* free any scrollback text */ + clear_sb_text(TRUE); /* free any scrollback text */ try_again = mf_release_all(); /* release as many blocks as possible */ releasing = FALSE; @@ -1148,7 +1148,7 @@ free_all_mem(void) # ifdef FEAT_DIFF diff_clear(curtab); # endif - clear_sb_text(); /* free any scrollback text */ + clear_sb_text(TRUE); /* free any scrollback text */ /* Free some global vars. */ vim_free(username); diff --git a/src/proto/message.pro b/src/proto/message.pro --- a/src/proto/message.pro +++ b/src/proto/message.pro @@ -52,7 +52,9 @@ void msg_puts_long_len_attr(char_u *long void msg_puts_attr(char_u *s, int attr); int message_filtered(char_u *msg); void may_clear_sb_text(void); -void clear_sb_text(void); +void sb_text_start_cmdline(void); +void sb_text_end_cmdline(void); +void clear_sb_text(int all); void show_sb_text(void); void msg_sb_eol(void); int msg_use_printf(void); diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 468, +/**/ 467, /**/ 466,