0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 8.1.0619: :echomsg and :echoerr do not handle List and Dict

Problem:    :echomsg and :echoerr do not handle List and Dict like :echo does.
            (Daniel Hahler)
Solution:   Be more tolerant about the expression result type.
This commit is contained in:
Bram Moolenaar 2018-12-22 13:28:07 +01:00
parent 528ccfbaa1
commit 461a7fcfce
8 changed files with 73 additions and 9 deletions

View File

@ -9233,7 +9233,8 @@ test_ignore_error({expr}) *test_ignore_error()*
error with try/catch cannot be used (because it skips over error with try/catch cannot be used (because it skips over
following code). following code).
{expr} is used literally, not as a pattern. {expr} is used literally, not as a pattern.
There is currently no way to revert this. When the {expr} is the string "RESET" then the list of ignored
errors is made empty.
test_null_channel() *test_null_channel()* test_null_channel() *test_null_channel()*
Return a Channel that is null. Only useful for testing. Return a Channel that is null. Only useful for testing.
@ -10999,8 +11000,8 @@ This does NOT work: >
The parsing works slightly different from |:echo|, The parsing works slightly different from |:echo|,
more like |:execute|. All the expressions are first more like |:execute|. All the expressions are first
evaluated and concatenated before echoing anything. evaluated and concatenated before echoing anything.
The expressions must evaluate to a Number or String, a If expressions does not evaluate to a Number or
Dictionary or List causes an error. String, string() is used to turn it into a string.
Uses the highlighting set by the |:echohl| command. Uses the highlighting set by the |:echohl| command.
Example: > Example: >
:echomsg "It's a Zizzer Zazzer Zuzz, as you can plainly see." :echomsg "It's a Zizzer Zazzer Zuzz, as you can plainly see."
@ -11011,7 +11012,7 @@ This does NOT work: >
message in the |message-history|. When used in a message in the |message-history|. When used in a
script or function the line number will be added. script or function the line number will be added.
Spaces are placed between the arguments as with the Spaces are placed between the arguments as with the
:echo command. When used inside a try conditional, |:echomsg| command. When used inside a try conditional,
the message is raised as an error exception instead the message is raised as an error exception instead
(see |try-echoerr|). (see |try-echoerr|).
Example: > Example: >

View File

@ -7162,6 +7162,30 @@ tv_get_string_buf_chk(typval_T *varp, char_u *buf)
return NULL; return NULL;
} }
/*
* Turn a typeval into a string. Similar to tv_get_string_buf() but uses
* string() on Dict, List, etc.
*/
char_u *
tv_stringify(typval_T *varp, char_u *buf)
{
if (varp->v_type == VAR_LIST
|| varp->v_type == VAR_DICT
|| varp->v_type == VAR_FUNC
|| varp->v_type == VAR_PARTIAL
|| varp->v_type == VAR_FLOAT)
{
typval_T tmp;
f_string(varp, &tmp);
tv_get_string_buf(&tmp, buf);
clear_tv(varp);
*varp = tmp;
return tmp.vval.v_string;
}
return tv_get_string_buf(varp, buf);
}
/* /*
* Find variable "name" in the list of variables. * Find variable "name" in the list of variables.
* Return a pointer to it if found, NULL if not found. * Return a pointer to it if found, NULL if not found.
@ -8142,7 +8166,12 @@ ex_execute(exarg_T *eap)
if (!eap->skip) if (!eap->skip)
{ {
p = tv_get_string(&rettv); char_u buf[NUMBUFLEN];
if (eap->cmdidx == CMD_execute)
p = tv_get_string_buf(&rettv, buf);
else
p = tv_stringify(&rettv, buf);
len = (int)STRLEN(p); len = (int)STRLEN(p);
if (ga_grow(&ga, len + 2) == FAIL) if (ga_grow(&ga, len + 2) == FAIL)
{ {

View File

@ -396,7 +396,6 @@ static void f_strftime(typval_T *argvars, typval_T *rettv);
#endif #endif
static void f_strgetchar(typval_T *argvars, typval_T *rettv); static void f_strgetchar(typval_T *argvars, typval_T *rettv);
static void f_stridx(typval_T *argvars, typval_T *rettv); static void f_stridx(typval_T *argvars, typval_T *rettv);
static void f_string(typval_T *argvars, typval_T *rettv);
static void f_strlen(typval_T *argvars, typval_T *rettv); static void f_strlen(typval_T *argvars, typval_T *rettv);
static void f_strcharpart(typval_T *argvars, typval_T *rettv); static void f_strcharpart(typval_T *argvars, typval_T *rettv);
static void f_strpart(typval_T *argvars, typval_T *rettv); static void f_strpart(typval_T *argvars, typval_T *rettv);
@ -12475,7 +12474,7 @@ f_stridx(typval_T *argvars, typval_T *rettv)
/* /*
* "string()" function * "string()" function
*/ */
static void void
f_string(typval_T *argvars, typval_T *rettv) f_string(typval_T *argvars, typval_T *rettv)
{ {
char_u *tofree; char_u *tofree;

View File

@ -553,6 +553,9 @@ ignore_error_for_testing(char_u *error)
if (ignore_error_list.ga_itemsize == 0) if (ignore_error_list.ga_itemsize == 0)
ga_init2(&ignore_error_list, sizeof(char_u *), 1); ga_init2(&ignore_error_list, sizeof(char_u *), 1);
if (STRCMP("RESET", error) == 0)
ga_clear_strings(&ignore_error_list);
else
ga_add_string(&ignore_error_list, error); ga_add_string(&ignore_error_list, error);
} }

View File

@ -89,6 +89,7 @@ char_u *tv_get_string(typval_T *varp);
char_u *tv_get_string_buf(typval_T *varp, char_u *buf); char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
char_u *tv_get_string_chk(typval_T *varp); char_u *tv_get_string_chk(typval_T *varp);
char_u *tv_get_string_buf_chk(typval_T *varp, char_u *buf); char_u *tv_get_string_buf_chk(typval_T *varp, char_u *buf);
char_u *tv_stringify(typval_T *varp, char_u *buf);
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload); dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload); dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
hashtab_T *find_var_ht(char_u *name, char_u **varname); hashtab_T *find_var_ht(char_u *name, char_u **varname);

View File

@ -9,6 +9,7 @@ void execute_redir_str(char_u *value, int value_len);
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv); void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
float_T vim_round(float_T f); float_T vim_round(float_T f);
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
void f_string(typval_T *argvars, typval_T *rettv);
char_u *get_callback(typval_T *arg, partial_T **pp); char_u *get_callback(typval_T *arg, partial_T **pp);
void free_callback(char_u *callback, partial_T *partial); void free_callback(char_u *callback, partial_T *partial);
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@ -1,4 +1,4 @@
" Tests for :messages " Tests for :messages, :echomsg, :echoerr
function Test_messages() function Test_messages()
let oldmore = &more let oldmore = &more
@ -64,3 +64,31 @@ func Test_message_completion()
call feedkeys(":message \<C-A>\<C-B>\"\<CR>", 'tx') call feedkeys(":message \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"message clear', @:) call assert_equal('"message clear', @:)
endfunc endfunc
func Test_echomsg()
call assert_equal("\nhello", execute(':echomsg "hello"'))
call assert_equal("\n", execute(':echomsg ""'))
call assert_equal("\n12345", execute(':echomsg 12345'))
call assert_equal("\n[]", execute(':echomsg []'))
call assert_equal("\n[1, 2, 3]", execute(':echomsg [1, 2, 3]'))
call assert_equal("\n{}", execute(':echomsg {}'))
call assert_equal("\n{'a': 1, 'b': 2}", execute(':echomsg {"a": 1, "b": 2}'))
if has('float')
call assert_equal("\n1.23", execute(':echomsg 1.23'))
endif
call assert_match("function('<lambda>\\d*')", execute(':echomsg {-> 1234}'))
endfunc
func Test_echoerr()
call test_ignore_error('IgNoRe')
call assert_equal("\nIgNoRe hello", execute(':echoerr "IgNoRe hello"'))
call assert_equal("\n12345 IgNoRe", execute(':echoerr 12345 "IgNoRe"'))
call assert_equal("\n[1, 2, 'IgNoRe']", execute(':echoerr [1, 2, "IgNoRe"]'))
call assert_equal("\n{'IgNoRe': 2, 'a': 1}", execute(':echoerr {"a": 1, "IgNoRe": 2}'))
if has('float')
call assert_equal("\n1.23 IgNoRe", execute(':echoerr 1.23 "IgNoRe"'))
endif
call test_ignore_error('<lambda>')
call assert_match("function('<lambda>\\d*')", execute(':echoerr {-> 1234}'))
call test_ignore_error('RESET')
endfunc

View File

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