vim-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.
461a7fcfce

Add lua functional tests for :echo,:echon,:echomsg,:echoerr
because nvim did not port "test_" functions from Vim
that modify internal state.

Testing :echoerr via try/catch is sufficient.
This commit is contained in:
Jan Edmund Lazo
2020-02-02 15:55:15 -05:00
parent 1656367b90
commit 3c12ee333a
5 changed files with 178 additions and 54 deletions

View File

@@ -9459,6 +9459,27 @@ void set_selfdict(typval_T *rettv, dict_T *selfdict)
}
}
// Turn a typeval into a string. Similar to tv_get_string_buf() but uses
// string() on Dict, List, etc.
static const char *tv_stringify(typval_T *varp, char *buf)
FUNC_ATTR_NONNULL_ALL
{
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, NULL);
const char *const res = tv_get_string_buf(&tmp, buf);
tv_clear(varp);
*varp = tmp;
return res;
}
return tv_get_string_buf(varp, buf);
}
// Find variable "name" in the list of variables.
// Return a pointer to it if found, NULL if not found.
// Careful: "a:0" variables don't have a name.
@@ -10349,7 +10370,10 @@ void ex_execute(exarg_T *eap)
}
if (!eap->skip) {
const char *const argstr = tv_get_string(&rettv);
char buf[NUMBUFLEN];
const char *const argstr = eap->cmdidx == CMD_execute
? tv_get_string_buf(&rettv, buf)
: tv_stringify(&rettv, buf);
const size_t len = strlen(argstr);
ga_grow(&ga, len + 2);
if (!GA_EMPTY(&ga)) {

View File

@@ -9558,7 +9558,7 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/*
* "string()" function
*/
static void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = (char_u *)encode_tv2string(&argvars[0], NULL);

View File

@@ -1,4 +1,4 @@
" Tests for :messages
" Tests for :messages, :echomsg, :echoerr
function Test_messages()
let oldmore = &more
@@ -65,6 +65,35 @@ func Test_message_completion()
call assert_equal('"message clear', @:)
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()
throw 'skipped: Nvim does not support test_ignore_error()'
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
func Test_echospace()
set noruler noshowcmd laststatus=1
call assert_equal(&columns - 1, v:echospace)