# HG changeset patch # User Bram Moolenaar # Date 1661794204 -7200 # Node ID 5dfd4bd66ad83bc195ec187eacb2f673724bbba6 # Parent 2c4538a21c2df7b7072a19fafb5eca5854e5373d patch 9.0.0321: cannot use the message popup window directly Commit: https://github.com/vim/vim/commit/37fef16c225eabed28a3c7a0542d2eeef30d812b Author: Bram Moolenaar Date: Mon Aug 29 18:16:32 2022 +0100 patch 9.0.0321: cannot use the message popup window directly Problem: Cannot use the message popup window directly. Solution: Add ":echowindow". diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -3821,6 +3821,16 @@ text... :echomsg "It's a Zizzer Zazzer Zuzz, as you can plainly see." < See |:echo-redraw| to avoid the message disappearing when the screen is redrawn. + + *:echow* *:echowin* *:echowindow* +:echow[indow] {expr1} .. + Like |:echomsg| but when the messages popup window is + available the message is displayed there. This means + it will show for three seconds and avoid a + |hit-enter| prompt. + The message window is available when Vim was compiled + with the +timer and the +popupwin features. + *:echoe* *:echoerr* :echoe[rr] {expr1} .. Echo the expression(s) as an error message, saving the message in the |message-history|. When used in a diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -2078,7 +2078,8 @@ set_context_for_expression( if ((cmdidx == CMD_execute || cmdidx == CMD_echo || cmdidx == CMD_echon - || cmdidx == CMD_echomsg) + || cmdidx == CMD_echomsg + || cmdidx == CMD_echowindow) && xp->xp_context == EXPAND_EXPRESSION) { for (;;) @@ -6709,6 +6710,7 @@ get_echo_attr(void) /* * ":execute expr1 ..." execute the result of an expression. * ":echomsg expr1 ..." Print a message + * ":echowindow expr1 ..." Print a message in the messages window * ":echoerr expr1 ..." Print an error * ":echoconsole expr1 ..." Print a message on stdout * Each gets spaces around each argument and a newline at the end for @@ -6726,6 +6728,9 @@ ex_execute(exarg_T *eap) long start_lnum = SOURCING_LNUM; ga_init2(&ga, 1, 80); +#ifdef HAS_MESSAGE_WINDOW + in_echowindow = (eap->cmdidx == CMD_echowindow); +#endif if (eap->skip) ++emsg_skip; @@ -6780,7 +6785,9 @@ ex_execute(exarg_T *eap) // use the first line of continuation lines for messages SOURCING_LNUM = start_lnum; - if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr) + if (eap->cmdidx == CMD_echomsg + || eap->cmdidx == CMD_echowindow + || eap->cmdidx == CMD_echoerr) { // Mark the already saved text as finishing the line, so that what // follows is displayed on a new line when scrolling back at the @@ -6788,7 +6795,7 @@ ex_execute(exarg_T *eap) msg_sb_eol(); } - if (eap->cmdidx == CMD_echomsg) + if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echowindow) { msg_attr(ga.ga_data, echo_attr); out_flush(); @@ -6835,6 +6842,7 @@ ex_execute(exarg_T *eap) if (msg_col == 0) msg_col = 1; } + in_echowindow = FALSE; #endif set_nextcmd(eap, arg); } diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h --- a/src/ex_cmdidxs.h +++ b/src/ex_cmdidxs.h @@ -10,27 +10,27 @@ static const unsigned short cmdidxs1[26] /* c */ 45, /* d */ 112, /* e */ 137, - /* f */ 165, - /* g */ 182, - /* h */ 188, - /* i */ 197, - /* j */ 217, - /* k */ 219, - /* l */ 224, - /* m */ 287, - /* n */ 305, - /* o */ 325, - /* p */ 337, - /* q */ 376, - /* r */ 379, - /* s */ 399, - /* t */ 469, - /* u */ 515, - /* v */ 526, - /* w */ 547, - /* x */ 561, - /* y */ 571, - /* z */ 572 + /* f */ 166, + /* g */ 183, + /* h */ 189, + /* i */ 198, + /* j */ 218, + /* k */ 220, + /* l */ 225, + /* m */ 288, + /* n */ 306, + /* o */ 326, + /* p */ 338, + /* q */ 377, + /* r */ 380, + /* s */ 400, + /* t */ 470, + /* u */ 516, + /* v */ 527, + /* w */ 548, + /* x */ 562, + /* y */ 572, + /* z */ 573 }; /* @@ -45,7 +45,7 @@ static const unsigned char cmdidxs2[26][ /* b */ { 2, 0, 0, 5, 6, 8, 0, 0, 0, 0, 0, 9, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 23, 0, 0, 0 }, /* c */ { 3, 12, 16, 18, 20, 22, 25, 0, 0, 0, 0, 33, 38, 41, 47, 57, 59, 60, 61, 0, 63, 0, 66, 0, 0, 0 }, /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 19, 0, 0, 20, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0 }, - /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 11, 0, 0, 0, 0, 0, 0, 0, 22, 0, 23, 0, 0 }, + /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 9, 11, 12, 0, 0, 0, 0, 0, 0, 0, 23, 0, 24, 0, 0 }, /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0 }, /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 }, /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -69,4 +69,4 @@ static const unsigned char cmdidxs2[26][ /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; -static const int command_count = 589; +static const int command_count = 590; diff --git a/src/ex_cmds.h b/src/ex_cmds.h --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -548,6 +548,9 @@ EXCMD(CMD_echoconsole, "echoconsole", ex EXCMD(CMD_echon, "echon", ex_echo, EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), +EXCMD(CMD_echowindow, "echowindow", ex_execute, + EX_EXTRA|EX_NOTRLCOM|EX_EXPR_ARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_else, "else", ex_else, EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -3872,6 +3872,8 @@ redrawcmdprompt(void) void redrawcmd(void) { + int save_in_echowindow = in_echowindow; + if (cmd_silent) return; @@ -3883,6 +3885,9 @@ redrawcmd(void) return; } + // Do not put this in the message window. + in_echowindow = FALSE; + sb_text_restart_cmdline(); msg_start(); redrawcmdprompt(); @@ -3906,6 +3911,8 @@ redrawcmd(void) // Typing ':' at the more prompt may set skip_redraw. We don't want this // in cmdline mode skip_redraw = FALSE; + + in_echowindow = save_in_echowindow; } void diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -236,6 +236,7 @@ EXTERN int uncaught_emsg; // number EXTERN int did_emsg_syntax; // did_emsg set because of a // syntax error EXTERN int called_emsg; // always incremented by emsg() +EXTERN int in_echowindow; // executing ":echowindow" EXTERN int ex_exitval INIT(= 0); // exit value for ex mode EXTERN int emsg_on_display INIT(= FALSE); // there is an error message EXTERN int rc_did_emsg INIT(= FALSE); // vim_regcomp() called emsg() diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -1438,7 +1438,8 @@ use_message_window(void) #ifdef HAS_MESSAGE_WINDOW // TRUE if there is no command line showing ('cmdheight' is zero and not // already editing or showing a message) use a popup window for messages. - return p_ch == 0 && cmdline_row >= Rows; + // Also when using ":echowindow". + return (p_ch == 0 && cmdline_row >= Rows) || in_echowindow; #else return FALSE; #endif @@ -1484,8 +1485,9 @@ msg_start(void) #ifdef HAS_MESSAGE_WINDOW if (use_message_window()) { - if (popup_message_win_visible() && msg_col > 0 - && (msg_scroll || !full_screen)) + if (popup_message_win_visible() + && ((msg_col > 0 && (msg_scroll || !full_screen)) + || in_echowindow)) { win_T *wp = popup_get_message_win(); diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -1302,7 +1302,8 @@ popup_adjust_position(win_T *wp) } if (wp->w_popup_pos == POPPOS_BOTTOM) // assume that each buffer line takes one screen line - wp->w_winrow = MAX(Rows - wp->w_buffer->b_ml.ml_line_count - 1, 0); + wp->w_winrow = MAX(cmdline_row + - wp->w_buffer->b_ml.ml_line_count - 1, 0); if (!use_wantcol) center_hor = TRUE; diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -2606,7 +2606,7 @@ typedef enum { POPPOS_BOTRIGHT, POPPOS_TOPRIGHT, POPPOS_CENTER, - POPPOS_BOTTOM, // bottom of popup at bottom of screen + POPPOS_BOTTOM, // bottom of popup just above the command line POPPOS_NONE } poppos_T; diff --git a/src/testdir/dumps/Test_echowindow_1.dump b/src/testdir/dumps/Test_echowindow_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_1.dump @@ -0,0 +1,8 @@ +>s+0&#ffffff0|o|m|e| |t|e|x|t| @65 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|═+0#e000002&@74 +|f|i|r|s|t| |l|i|n|e| @64 +| +0#0000000&@56|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_echowindow_2.dump b/src/testdir/dumps/Test_echowindow_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_2.dump @@ -0,0 +1,8 @@ +>s+0&#ffffff0|o|m|e| |t|e|x|t| @65 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|═+0#e000002&@74 +|f|i|r|s|t| |l|i|n|e| @64 +|s|e|c|o|n|d| |l|i|n|e| @63 +| +0#0000000&@56|1|,|1| @10|A|l@1| diff --git a/src/testdir/dumps/Test_echowindow_3.dump b/src/testdir/dumps/Test_echowindow_3.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_echowindow_3.dump @@ -0,0 +1,8 @@ +>s+0&#ffffff0|o|m|e| |t|e|x|t| @65 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +| +0#0000000&@56|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 @@ -537,5 +537,30 @@ func Test_cmdheight_zero_shell() set cmdheight& endfunc +func Test_echowindow() + CheckScreendump + + let lines =<< trim END + call setline(1, 'some text') + func ShowMessage(arg) + echowindow a:arg + endfunc + echowindow 'first line' + END + call writefile(lines, 'XtestEchowindow') + let buf = RunVimInTerminal('-S XtestEchowindow', #{rows: 8}) + call VerifyScreenDump(buf, 'Test_echowindow_1', {}) + + call term_sendkeys(buf, ":call ShowMessage('second line')\") + call VerifyScreenDump(buf, 'Test_echowindow_2', {}) + + call term_sendkeys(buf, ":call popup_clear()\") + call VerifyScreenDump(buf, 'Test_echowindow_3', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestEchowindow') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -708,6 +708,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 321, +/**/ 320, /**/ 319,