diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-07-28 20:07:32 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-28 20:07:32 +0800 |
commit | f254fc67a5c04c6454425df2f2434b52a1f9e949 (patch) | |
tree | 632093f47f3466da32d9e5bb4902f3791fdcc3c3 /src/nvim/message.c | |
parent | 9cb8b5f8dbef6c81d287639726e425d80c15c70d (diff) | |
download | rneovim-f254fc67a5c04c6454425df2f2434b52a1f9e949.tar.gz rneovim-f254fc67a5c04c6454425df2f2434b52a1f9e949.tar.bz2 rneovim-f254fc67a5c04c6454425df2f2434b52a1f9e949.zip |
vim-patch:9.0.0099: scrollback can be wrong after redrawing the command line (#19562)
Problem: Scrollback can be wrong after redrawing the command line.
Solution: Clear unfinished scrollback when redrawing. (closes vim/vim#10807)
https://github.com/vim/vim/commit/46af7bc08debbf408d025680eeef136fb3b528ef
Diffstat (limited to 'src/nvim/message.c')
-rw-r--r-- | src/nvim/message.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/nvim/message.c b/src/nvim/message.c index 3a6c690ff6..80d11c096b 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2503,6 +2503,7 @@ static void store_sb_text(char_u **sb_str, char_u *s, int attr, int *sb_col, int 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); + msg_sb_eol(); // prevent messages from overlapping do_clear_sb_text = SB_CLEAR_NONE; } @@ -2537,18 +2538,47 @@ void may_clear_sb_text(void) do_clear_sb_text = SB_CLEAR_ALL; } -/// Starting to edit the command line, do not clear messages now. +/// Starting to edit the command line: do not clear messages now. void sb_text_start_cmdline(void) { + if (do_clear_sb_text == SB_CLEAR_CMDLINE_BUSY) { + // Invoking command line recursively: the previous-level command line + // doesn't need to be remembered as it will be redrawn when returning + // to that level. + sb_text_restart_cmdline(); + } else { + msg_sb_eol(); + do_clear_sb_text = SB_CLEAR_CMDLINE_BUSY; + } +} + +/// Redrawing the command line: clear the last unfinished line. +void sb_text_restart_cmdline(void) +{ + // Needed when returning from nested command line. do_clear_sb_text = SB_CLEAR_CMDLINE_BUSY; - msg_sb_eol(); + + if (last_msgchunk == NULL || last_msgchunk->sb_eol) { + // No unfinished line: don't clear anything. + return; + } + + msgchunk_T *tofree = msg_sb_start(last_msgchunk); + last_msgchunk = tofree->sb_prev; + if (last_msgchunk != NULL) { + last_msgchunk->sb_next = NULL; + } + while (tofree != NULL) { + msgchunk_T *tofree_next = tofree->sb_next; + xfree(tofree); + tofree = tofree_next; + } } -/// Ending to edit the command line. Clear old lines but the last one later. +/// 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; - msg_sb_eol(); } /// Clear any text remembered for scrolling back. |