changeset 30025:d269dd3cd31d v9.0.0350

patch 9.0.0350: :echowindow does not work in a compiled function Commit: https://github.com/vim/vim/commit/7d7ad7b2e8c6403033fbdb083f092321c0ccbfaf Author: Bram Moolenaar <Bram@vim.org> Date: Thu Sep 1 16:00:53 2022 +0100 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.
author Bram Moolenaar <Bram@vim.org>
date Thu, 01 Sep 2022 17:15:04 +0200
parents 7cb41447c659
children 139557ff6c5b
files src/channel.c src/ex_docmd.c src/popupwin.c src/proto/ex_docmd.pro src/proto/popupwin.pro src/testdir/test_vim9_disassemble.vim src/testdir/test_vim9_script.vim src/version.c src/vim9.h src/vim9cmds.c src/vim9compile.c src/vim9execute.c
diffstat 12 files changed, 84 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/channel.c
+++ b/src/channel.c
@@ -2731,12 +2731,8 @@ channel_exe_cmd(channel_T *channel, ch_p
     }
     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);
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -8349,11 +8349,20 @@ ex_redir(exarg_T *eap)
 }
 
 /*
- * ":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 @@ ex_redraw(exarg_T *eap)
     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))
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -4529,6 +4529,31 @@ popup_hide_message_win(void)
 	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
 
 /*
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -55,6 +55,7 @@ void ex_cd(exarg_T *eap);
 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);
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -67,6 +67,8 @@ win_T *popup_get_message_win(void);
 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);
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -2274,6 +2274,8 @@ def s:Echomsg()
   echomsg 'some' 'message'
   echoconsole 'nothing'
   echoerr 'went' .. 'wrong'
+  var local = 'window'
+  echowin 'in' local
 enddef
 
 def Test_disassemble_echomsg()
@@ -2289,7 +2291,14 @@ def Test_disassemble_echomsg()
         "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
 
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2011,6 +2011,13 @@ def Test_echoconsole_cmd()
   # 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
--- 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 */
 /**/
+    350,
+/**/
     349,
 /**/
     348,
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -25,6 +25,7 @@ typedef enum {
     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
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -1735,6 +1735,10 @@ compile_mult_expr(char_u *arg, int cmdid
 	    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
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -3251,10 +3251,13 @@ compile_def_function(
 
 	    case CMD_echo:
 	    case CMD_echon:
-	    case CMD_execute:
+	    case CMD_echoconsole:
+	    case CMD_echoerr:
 	    case CMD_echomsg:
-	    case CMD_echoerr:
-	    case CMD_echoconsole:
+#ifdef HAS_MESSAGE_WINDOW
+	    case CMD_echowindow:
+#endif
+	    case CMD_execute:
 		    line = compile_mult_expr(p, ea.cmdidx, &cctx);
 		    break;
 
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2858,10 +2858,12 @@ exec_instructions(ectx_T *ectx)
 
 	    // :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 @@ exec_instructions(ectx_T *ectx)
 				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 @@ list_instructions(char *pfx, isn_T *inst
 		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));