diff options
author | KunMing Xie <qqzz014@gmail.com> | 2018-06-21 17:36:26 +0800 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2018-06-21 11:36:26 +0200 |
commit | 7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87 (patch) | |
tree | fe8c991ec9bbb4f3c72cd3a3b53d08e3540d5354 /src | |
parent | b92d6f490d93f788f018d7c8417d68d2d3de1a95 (diff) | |
download | rneovim-7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87.tar.gz rneovim-7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87.tar.bz2 rneovim-7ae7da8fb9ab2e23ffc19000798ae27a2dee4e87.zip |
vim-patch:8.0.0468: g< after aborting an Ex command (#7941)
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.
https://github.com/vim/vim/commit/f2405ed2321da4a879fe0b0703af780fc0432c63
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ex_getln.c | 3 | ||||
-rw-r--r-- | src/nvim/memory.c | 4 | ||||
-rw-r--r-- | src/nvim/message.c | 87 |
3 files changed, 63 insertions, 31 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 774007c66e..3372edb8fd 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -273,6 +273,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) ccline.last_colors = (ColoredCmdline){ .cmdbuff = NULL, .colors = KV_INITIAL_VALUE }; + sb_text_start_cmdline(); // autoindent for :insert and :append if (s->firstc <= 0) { @@ -480,6 +481,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) xfree(ccline.last_colors.cmdbuff); kv_destroy(ccline.last_colors.colors); + sb_text_end_cmdline(); + { char_u *p = ccline.cmdbuff; diff --git a/src/nvim/memory.c b/src/nvim/memory.c index bfc2f208dd..b2aef13946 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -66,7 +66,7 @@ void try_to_free_memory(void) trying_to_free = true; // free any scrollback text - clear_sb_text(); + clear_sb_text(true); // Try to save all buffers and release as many blocks as possible mf_release_all(); @@ -633,7 +633,7 @@ void free_all_mem(void) free_signs(); set_expr_line(NULL); diff_clear(curtab); - clear_sb_text(); /* free any scrollback text */ + clear_sb_text(true); // free any scrollback text /* Free some global vars. */ xfree(last_cmdline); diff --git a/src/nvim/message.c b/src/nvim/message.c index 2643d644a9..097c8b16e4 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1759,12 +1759,11 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, } 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; + need_wait_return = true; // may need wait_return in main() + redraw_cmdline = true; + if (cmdline_row > 0 && !exmode_active) { + cmdline_row--; + } /* * If screen is completely filled and 'more' is set then wait @@ -1921,30 +1920,38 @@ static void inc_msg_scrolled(void) xfree(tofree); } msg_scrolled++; + if (must_redraw < VALID) { + must_redraw = VALID; + } } -static msgchunk_T *last_msgchunk = NULL; /* last displayed text */ +static msgchunk_T *last_msgchunk = NULL; // last displayed text +typedef enum { + SB_CLEAR_NONE = 0, + SB_CLEAR_ALL, + SB_CLEAR_CMDLINE_BUSY, + SB_CLEAR_CMDLINE_DONE +} sb_clear_T; -static int do_clear_sb_text = FALSE; /* clear text on next msg */ +// 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. - */ -static void -store_sb_text ( - char_u **sb_str, /* start of string */ - char_u *s, /* just after string */ +/// Store part of a printed message for displaying when scrolling back. +static void store_sb_text( + char_u **sb_str, // start of string + char_u *s, // just after string int attr, int *sb_col, - int finish /* line ends */ + int finish // line ends ) { msgchunk_T *mp; - if (do_clear_sb_text) { - clear_sb_text(); - do_clear_sb_text = FALSE; + if (do_clear_sb_text == SB_CLEAR_ALL + || do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) { + clear_sb_text(do_clear_sb_text == SB_CLEAR_ALL); + do_clear_sb_text = SB_CLEAR_NONE; } if (s > *sb_str) { @@ -1976,21 +1983,43 @@ store_sb_text ( */ void may_clear_sb_text(void) { - do_clear_sb_text = TRUE; + do_clear_sb_text = SB_CLEAR_ALL; } -/* - * Clear any text remembered for scrolling back. - * Called when redrawing the screen. - */ -void clear_sb_text(void) +/// 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(int all) { msgchunk_T *mp; + msgchunk_T **lastp; + + if (all) { + lastp = &last_msgchunk; + } else { + if (last_msgchunk == NULL) { + return; + } + lastp = &last_msgchunk->sb_prev; + } - while (last_msgchunk != NULL) { - mp = last_msgchunk->sb_prev; - xfree(last_msgchunk); - last_msgchunk = mp; + while (*lastp != NULL) { + mp = (*lastp)->sb_prev; + xfree(*lastp); + *lastp = mp; } } |