# HG changeset patch # User Bram Moolenaar # Date 1662929103 -7200 # Node ID b871016ea7c15f516677397bd7075bda8dfc9af4 # Parent a5dace90aec6723ff74c44c8e866ac666ad06f72 patch 9.0.0447: using :echowin while at the hit-enter prompt causes problems Commit: https://github.com/vim/vim/commit/cf0995d7d7301e36c81cafa14e68782f1d3be2ad Author: Bram Moolenaar Date: Sun Sep 11 21:36:17 2022 +0100 patch 9.0.0447: using :echowin while at the hit-enter prompt causes problems Problem: Using :echowin while at the hit-enter prompt causes problems. Solution: Do not prompt for :echowin. Postpone showing the message window. Start the timer when the window is displayed. diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -3890,7 +3890,8 @@ redrawcmd(void) void compute_cmdrow(void) { - if (exmode_active || msg_scrolled != 0) + // ignore "msg_scrolled" in update_screen(), it will be reset soon. + if (exmode_active || (msg_scrolled != 0 && !updating_screen)) cmdline_row = Rows - 1; else cmdline_row = W_WINROW(lastwin) + lastwin->w_height diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -1157,6 +1157,10 @@ wait_return(int redraw) // need_wait_return to do it later. if (msg_silent != 0) return; +#ifdef HAS_MESSAGE_WINDOW + if (in_echowindow) + return; +#endif /* * When inside vgetc(), we can't wait for a typed character at all. diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -31,6 +31,13 @@ static poppos_entry_T poppos_entries[] = #ifdef HAS_MESSAGE_WINDOW // Window used for ":echowindow" static win_T *message_win = NULL; + +// Flag set when a message is added to the message window, timer is started +// when the message window is drawn. This might be after pressing Enter at the +// hit-enter prompt. +static int start_message_win_timer = FALSE; + +static void may_start_message_win_timer(win_T *wp); #endif static void popup_adjust_position(win_T *wp); @@ -4268,6 +4275,11 @@ update_popups(void (*win_update)(win_T * // Back to the normal zindex. screen_zindex = 0; + +#ifdef HAS_MESSAGE_WINDOW + // if this was the message window popup may start the timer now + may_start_message_win_timer(wp); +#endif } #if defined(FEAT_SEARCH_EXTRA) @@ -4513,8 +4525,18 @@ popup_show_message_win(void) popup_update_color(message_win, TYPE_MESSAGE_WIN); popup_show(message_win); } + start_message_win_timer = TRUE; + } +} + + static void +may_start_message_win_timer(win_T *wp) +{ + if (wp == message_win && start_message_win_timer) + { if (message_win->w_popup_timer != NULL) timer_start(message_win->w_popup_timer); + start_message_win_timer = FALSE; } } @@ -4552,8 +4574,9 @@ end_echowindow(void) { in_echowindow = FALSE; - // show the message window now - redraw_cmd(FALSE); + if ((State & MODE_HITRETURN) == 0) + // show the message window now + redraw_cmd(FALSE); // do not overwrite messages // TODO: only for message window diff --git a/src/screen.c b/src/screen.c --- a/src/screen.c +++ b/src/screen.c @@ -3038,18 +3038,18 @@ screenclear2(int doclear) screen_cleared = TRUE; // can use contents of ScreenLines now win_rest_invalid(firstwin); // redraw all regular windows -#ifdef FEAT_PROP_POPUP - popup_redraw_all(); // redraw all popup windows -#endif redraw_cmdline = TRUE; redraw_tabline = TRUE; if (must_redraw == UPD_CLEAR) // no need to clear again must_redraw = UPD_NOT_VALID; + msg_scrolled = 0; // compute_cmdrow() uses this compute_cmdrow(); +#ifdef FEAT_PROP_POPUP + popup_redraw_all(); // redraw all popup windows +#endif msg_row = cmdline_row; // put cursor on last line for messages msg_col = 0; screen_start(); // don't know where cursor is now - msg_scrolled = 0; // can't scroll back msg_didany = FALSE; msg_didout = FALSE; } diff --git a/src/testdir/dumps/Test_echowindow_6.dump b/src/testdir/dumps/Test_echowindow_6.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_6.dump @@ -0,0 +1,8 @@ +|~+0#4040ff13#ffffff0| @73 +|~| @73 +|~| @73 +|~| @73 +|o+0#0000000&|n|e| @71 +|t|w|o| @71 +|t|h|r|e@1| @69 +|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35 diff --git a/src/testdir/dumps/Test_echowindow_7.dump b/src/testdir/dumps/Test_echowindow_7.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_7.dump @@ -0,0 +1,8 @@ +>s+0&#ffffff0|o|m|e| |t|e|x|t| @65 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|═+0#e000002&@74 +|l|a|t|e|r| |m|e|s@1|a|g|e| @61 +| +0#0000000&@74 +@57|1|,|1| @10|A|l@1| diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim --- a/src/testdir/test_messages.vim +++ b/src/testdir/test_messages.vim @@ -401,6 +401,28 @@ func Test_echowindow() echowindow 'line' n endfor endfunc + + def TwoMessages() + popup_clear() + set cmdheight=2 + redraw + timer_start(100, (_) => { + echowin 'message' + }) + echo 'one' + echo 'two' + enddef + + def ThreeMessages() + popup_clear() + redraw + timer_start(100, (_) => { + echowin 'later message' + }) + echo 'one' + echo 'two' + echo 'three' + enddef END call writefile(lines, 'XtestEchowindow') let buf = RunVimInTerminal('-S XtestEchowindow', #{rows: 8}) @@ -415,6 +437,16 @@ func Test_echowindow() call term_sendkeys(buf, ":call ManyMessages()\") call VerifyScreenDump(buf, 'Test_echowindow_4', {}) + call term_sendkeys(buf, ":call TwoMessages()\") + call VerifyScreenDump(buf, 'Test_echowindow_5', {}) + + call term_sendkeys(buf, ":call ThreeMessages()\") + sleep 120m + call VerifyScreenDump(buf, 'Test_echowindow_6', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_echowindow_7', {}) + " clean up call StopVimInTerminal(buf) call delete('XtestEchowindow') diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 447, +/**/ 446, /**/ 445,