# HG changeset patch # User Bram Moolenaar # Date 1662045304 -7200 # Node ID d269dd3cd31df4b33fa2c5ecedd800a623b732f1 # Parent 7cb41447c65974c37fd2024ceda33ec41b911168 patch 9.0.0350: :echowindow does not work in a compiled function Commit: https://github.com/vim/vim/commit/7d7ad7b2e8c6403033fbdb083f092321c0ccbfaf Author: Bram Moolenaar 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. diff --git a/src/channel.c b/src/channel.c --- 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); diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- 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)) diff --git a/src/popupwin.c b/src/popupwin.c --- 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 /* diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro --- 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); diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro --- 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); diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim --- 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 diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- 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 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 */ /**/ + 350, +/**/ 349, /**/ 348, diff --git a/src/vim9.h b/src/vim9.h --- 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 diff --git a/src/vim9cmds.c b/src/vim9cmds.c --- 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 diff --git a/src/vim9compile.c b/src/vim9compile.c --- 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; diff --git a/src/vim9execute.c b/src/vim9execute.c --- 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));