]> granicus.if.org Git - vim/commitdiff
patch 9.0.0350: :echowindow does not work in a compiled function v9.0.0350
authorBram Moolenaar <Bram@vim.org>
Thu, 1 Sep 2022 15:00:53 +0000 (16:00 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 1 Sep 2022 15:00:53 +0000 (16:00 +0100)
Problem:    :echowindow does not work in a compiled function.
Solution:   Handle the expression at compile time.

12 files changed:
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

index 89776861d85aaa7cea5b4cbb59bef3d085ae9173..80fe4c4be8f9f414581355b2ea8a2544f2f97e89 100644 (file)
@@ -2731,12 +2731,8 @@ channel_exe_cmd(channel_T *channel, ch_part_T part, typval_T *argv)
     }
     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);
index 9f7875f5eb904a9430cc97b7e74353e4460c00fd..ae1f1959b715ae1a219f97b247626087ffbfabed 100644 (file)
@@ -8349,10 +8349,19 @@ 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))
index 8292dba32e238c68f3a6af2fca9c91371448cc01..72d3878799b4dc48da94eac9d2ae2c6c9ce515a2 100644 (file)
@@ -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
 
 /*
index 28f4c43dc5e352fc39a7dde68e0288fe99d9d650..f5d7a488a719c47e9fa0b51dcf9e2ce9472a3050 100644 (file)
@@ -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);
index dcc14de09190fb894f5285b8515666d792b822df..12be54f1f8056d4d32f06f9a64615b143794c84b 100644 (file)
@@ -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);
index be40088d3bace19156f5f30cd01378bd447e6c1a..12be15648326ee5e8cda11c16e34d7b74f73f77d 100644 (file)
@@ -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
 
index 5aec8ffc8619879412ae87e9edf62a8530b48413..bdefc8756a75ea25b289ca2cb2277814eb63b85c 100644 (file)
@@ -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
index f885aa1e886acae7477643130a02cf92a994f564..f7d7d6203d707f01f7374dc1c5df32516e037cfe 100644 (file)
@@ -707,6 +707,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    350,
 /**/
     349,
 /**/
index 3ab1c5aa96d8748e8e30f1062f81a9785694b30b..b32dbeab44f8094f91abb4074ef6d6d338ea040c 100644 (file)
@@ -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
index 93032d6bf154e303a72c0589b7ae1d8dcc7a44a7..4ad87bc2645e295d6914dfefab45a469234677a9 100644 (file)
@@ -1735,6 +1735,10 @@ compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
            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
index bf7390b6fa64978cd8ad9c49d222183ddcdf86ea..20366752cfad3e7b9248cfc36fa0a34e6d959ed3 100644 (file)
@@ -3251,10 +3251,13 @@ compile_def_function(
 
            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;
 
index 2f94f05c54a7107050067da48a0b17eeb0f156c9..a1311ee177e46643c627c956cb804792dc0a428e 100644 (file)
@@ -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 *instr, int instr_count, ufunc_T *ufunc)
                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));