0
0
mirror of https://github.com/vim/vim.git synced 2025-08-29 20:33:37 -04:00

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.
This commit is contained in:
Bram Moolenaar 2022-09-01 16:00:53 +01:00
parent be807d5824
commit 7d7ad7b2e8
12 changed files with 84 additions and 11 deletions

View 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);

View 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))

View 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
/*

View 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);

View 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);

View 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

View 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

View File

@ -707,6 +707,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
350,
/**/
349,
/**/

View 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

View 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

View 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;

View 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));