aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-07-28 20:07:32 +0800
committerGitHub <noreply@github.com>2022-07-28 20:07:32 +0800
commitf254fc67a5c04c6454425df2f2434b52a1f9e949 (patch)
tree632093f47f3466da32d9e5bb4902f3791fdcc3c3 /src
parent9cb8b5f8dbef6c81d287639726e425d80c15c70d (diff)
downloadrneovim-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')
-rw-r--r--src/nvim/ex_getln.c1
-rw-r--r--src/nvim/message.c38
-rw-r--r--src/nvim/testdir/test_messages.vim11
3 files changed, 45 insertions, 5 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 1ee8581e00..4c17fdae02 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -3823,6 +3823,7 @@ void redrawcmd(void)
redrawing_cmdline = true;
+ sb_text_restart_cmdline();
msg_start();
redrawcmdprompt();
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.
diff --git a/src/nvim/testdir/test_messages.vim b/src/nvim/testdir/test_messages.vim
index 4be5a1b076..2f9c562771 100644
--- a/src/nvim/testdir/test_messages.vim
+++ b/src/nvim/testdir/test_messages.vim
@@ -118,7 +118,9 @@ func Test_message_more()
let buf = RunVimInTerminal('', {'rows': 6})
call term_sendkeys(buf, ":call setline(1, range(1, 100))\n")
- call term_sendkeys(buf, ":%p#\n")
+ call term_sendkeys(buf, ":%pfoo\<C-H>\<C-H>\<C-H>#")
+ call WaitForAssert({-> assert_equal(':%p#', term_getline(buf, 6))})
+ call term_sendkeys(buf, "\n")
call WaitForAssert({-> assert_equal(' 5 5', term_getline(buf, 5))})
call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))})
@@ -194,6 +196,13 @@ func Test_message_more()
call WaitForAssert({-> assert_equal('100 100', term_getline(buf, 5))})
call WaitForAssert({-> assert_equal('Press ENTER or type command to continue', term_getline(buf, 6))})
+ " A command line that doesn't print text is appended to scrollback,
+ " even if it invokes a nested command line.
+ call term_sendkeys(buf, ":\<C-R>=':'\<CR>:\<CR>g<")
+ call WaitForAssert({-> assert_equal('100 100', term_getline(buf, 4))})
+ call WaitForAssert({-> assert_equal(':::', term_getline(buf, 5))})
+ call WaitForAssert({-> assert_equal('Press ENTER or type command to continue', term_getline(buf, 6))})
+
call term_sendkeys(buf, ":%p#\n")
call WaitForAssert({-> assert_equal(' 5 5', term_getline(buf, 5))})
call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))})