patch 9.0.0350: :echowindow does not work in a compiled function
Problem: :echowindow does not work in a compiled function.
Solution: Handle the expression at compile time.
diff --git a/src/channel.c b/src/channel.c
index 8977686..80fe4c4 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2731,12 +2731,8 @@
}
else if (STRCMP(cmd, "redraw") == 0)
{
- exarg_T ea;
-
ch_log(channel, "redraw");
- CLEAR_FIELD(ea);
- ea.forceit = *arg != NUL;
- ex_redraw(&ea);
+ redraw_cmd(*arg != NUL);
showruler(FALSE);
setcursor();
out_flush_cursor(TRUE, FALSE);
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 9f7875f..ae1f195 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -8349,11 +8349,20 @@
}
/*
- * ":redraw": force redraw
+ * ":redraw": force redraw, with clear for ":redraw!".
*/
void
ex_redraw(exarg_T *eap)
{
+ redraw_cmd(eap->forceit);
+}
+
+/*
+ * ":redraw": force redraw, with clear if "clear" is TRUE.
+ */
+ void
+redraw_cmd(int clear)
+{
int r = RedrawingDisabled;
int p = p_lz;
@@ -8361,7 +8370,7 @@
p_lz = FALSE;
validate_cursor();
update_topline();
- update_screen(eap->forceit ? UPD_CLEAR : VIsual_active ? UPD_INVERTED : 0);
+ update_screen(clear ? UPD_CLEAR : VIsual_active ? UPD_INVERTED : 0);
if (need_maketitle)
maketitle();
#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL))
diff --git a/src/popupwin.c b/src/popupwin.c
index 8292dba..72d38787 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -4529,6 +4529,31 @@
popup_hide(message_win);
}
+/*
+ * Invoked before outputting a message for ":echowindow".
+ */
+ void
+start_echowindow(void)
+{
+ in_echowindow = TRUE;
+}
+
+/*
+ * Invoked after outputting a message for ":echowindow".
+ */
+ void
+end_echowindow(void)
+{
+ // show the message window now
+ redraw_cmd(FALSE);
+
+ // do not overwrite messages
+ // TODO: only for message window
+ msg_didout = TRUE;
+ if (msg_col == 0)
+ msg_col = 1;
+ in_echowindow = FALSE;
+}
#endif
/*
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 28f4c43..f5d7a48 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -55,6 +55,7 @@
void do_sleep(long msec, int hide_cursor);
void ex_may_print(exarg_T *eap);
void ex_redraw(exarg_T *eap);
+void redraw_cmd(int clear);
int vim_mkdir_emsg(char_u *name, int prot);
FILE *open_exfile(char_u *fname, int forceit, char *mode);
void update_topline_cursor(void);
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index dcc14de..12be54f 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -67,6 +67,8 @@
void popup_show_message_win(void);
int popup_message_win_visible(void);
void popup_hide_message_win(void);
+void start_echowindow(void);
+void end_echowindow(void);
int popup_win_closed(win_T *win);
void popup_set_title(win_T *wp);
void popup_update_preview_title(void);
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index be40088..12be156 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -2274,6 +2274,8 @@
echomsg 'some' 'message'
echoconsole 'nothing'
echoerr 'went' .. 'wrong'
+ var local = 'window'
+ echowin 'in' local
enddef
def Test_disassemble_echomsg()
@@ -2289,7 +2291,14 @@
"echoerr 'went' .. 'wrong'\\_s*" ..
'\d PUSHS "wentwrong"\_s*' ..
'\d ECHOERR 1\_s*' ..
- '\d RETURN void',
+ "var local = 'window'\\_s*" ..
+ '\d\+ PUSHS "window"\_s*' ..
+ '\d\+ STORE $0\_s*' ..
+ "echowin 'in' local\\_s*" ..
+ '\d\+ PUSHS "in"\_s*' ..
+ '\d\+ LOAD $0\_s*' ..
+ '\d\+ ECHOWINDOW 2\_s*' ..
+ '\d\+ RETURN void',
res)
enddef
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 5aec8ff..bdefc87 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2011,6 +2011,13 @@
# output goes anywhere
enddef
+def Test_echowindow_cmd()
+ var local = 'local'
+ echowindow 'something' local # comment
+ # output goes in message window
+ popup_clear()
+enddef
+
def Test_for_outside_of_function()
var lines =<< trim END
vim9script
diff --git a/src/version.c b/src/version.c
index f885aa1..f7d7d62 100644
--- a/src/version.c
+++ b/src/version.c
@@ -708,6 +708,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 350,
+/**/
349,
/**/
348,
diff --git a/src/vim9.h b/src/vim9.h
index 3ab1c5a..b32dbea 100644
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -25,6 +25,7 @@
ISN_EXECUTE, // :execute with isn_arg.number items on top of stack
ISN_ECHOMSG, // :echomsg with isn_arg.number items on top of stack
ISN_ECHOCONSOLE, // :echoconsole with isn_arg.number items on top of stack
+ ISN_ECHOWINDOW, // :echowindow with isn_arg.number items on top of stack
ISN_ECHOERR, // :echoerr with isn_arg.number items on top of stack
ISN_RANGE, // compute range from isn_arg.string, push to stack
ISN_SUBSTITUTE, // :s command with expression
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index 93032d6..4ad87bc 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -1735,6 +1735,10 @@
generate_MULT_EXPR(cctx, ISN_EXECUTE, count);
else if (cmdidx == CMD_echomsg)
generate_MULT_EXPR(cctx, ISN_ECHOMSG, count);
+#ifdef HAS_MESSAGE_WINDOW
+ else if (cmdidx == CMD_echowindow)
+ generate_MULT_EXPR(cctx, ISN_ECHOWINDOW, count);
+#endif
else if (cmdidx == CMD_echoconsole)
generate_MULT_EXPR(cctx, ISN_ECHOCONSOLE, count);
else
diff --git a/src/vim9compile.c b/src/vim9compile.c
index bf7390b..2036675 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -3251,10 +3251,13 @@
case CMD_echo:
case CMD_echon:
- case CMD_execute:
- case CMD_echomsg:
- case CMD_echoerr:
case CMD_echoconsole:
+ case CMD_echoerr:
+ case CMD_echomsg:
+#ifdef HAS_MESSAGE_WINDOW
+ case CMD_echowindow:
+#endif
+ case CMD_execute:
line = compile_mult_expr(p, ea.cmdidx, &cctx);
break;
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 2f94f05..a1311ee 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2858,10 +2858,12 @@
// :execute {string} ...
// :echomsg {string} ...
+ // :echowindow {string} ...
// :echoconsole {string} ...
// :echoerr {string} ...
case ISN_EXECUTE:
case ISN_ECHOMSG:
+ case ISN_ECHOWINDOW:
case ISN_ECHOCONSOLE:
case ISN_ECHOERR:
{
@@ -2932,6 +2934,14 @@
msg_attr(ga.ga_data, echo_attr);
out_flush();
}
+#ifdef HAS_MESSAGE_WINDOW
+ else if (iptr->isn_type == ISN_ECHOWINDOW)
+ {
+ start_echowindow();
+ msg_attr(ga.ga_data, echo_attr);
+ end_echowindow();
+ }
+#endif
else if (iptr->isn_type == ISN_ECHOCONSOLE)
{
ui_write(ga.ga_data, (int)STRLEN(ga.ga_data),
@@ -5570,6 +5580,10 @@
smsg("%s%4d ECHOMSG %lld", pfx, current,
(varnumber_T)(iptr->isn_arg.number));
break;
+ case ISN_ECHOWINDOW:
+ smsg("%s%4d ECHOWINDOW %lld", pfx, current,
+ (varnumber_T)(iptr->isn_arg.number));
+ break;
case ISN_ECHOCONSOLE:
smsg("%s%4d ECHOCONSOLE %lld", pfx, current,
(varnumber_T)(iptr->isn_arg.number));