# HG changeset patch # User Bram Moolenaar # Date 1610485206 -3600 # Node ID d3e064f548908906741d78c0f550c9360a92ba80 # Parent 934ad0b3ba7b06c56a4fb5ff9513412346ad4f03 patch 8.2.2339: cannot get the type of a value as a string Commit: https://github.com/vim/vim/commit/a47e05f04a5a5c0369c949157c24d09cbe64ad6a Author: Bram Moolenaar Date: Tue Jan 12 21:49:00 2021 +0100 patch 8.2.2339: cannot get the type of a value as a string Problem: Cannot get the type of a value as a string. Solution: Add typename(). diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -3016,7 +3016,8 @@ tr({src}, {fromstr}, {tostr}) String tra trim({text} [, {mask} [, {dir}]]) String trim characters in {mask} from {text} trunc({expr}) Float truncate Float {expr} -type({name}) Number type of variable {name} +type({expr}) Number type of value {expr} +typename({expr}) String representation of the type of {expr} undofile({name}) String undo file name for {name} undotree() List undo file tree uniq({list} [, {func} [, {dict}]]) @@ -11129,6 +11130,14 @@ type({expr}) The result is a Number repr < Can also be used as a |method|: > mylist->type() + +typename({expr}) *typename()* + Return a string representation of the type of {expr}. + Example: > + echo typename([1, 2, 3]) + list + + undofile({name}) *undofile()* Return the name of the undo file that would be used for a file with name {name} when writing. This uses the 'undodir' diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -720,7 +720,8 @@ Other computation: *bitwise-function srand() initialize seed used by rand() Variables: *var-functions* - type() type of a variable + type() type of a variable as a number + typename() type of a variable as text islocked() check if a variable is locked funcref() get a Funcref for a function reference function() get a Funcref for a function name diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -1742,6 +1742,8 @@ static funcentry_T global_functions[] = ret_float, FLOAT_FUNC(f_trunc)}, {"type", 1, 1, FEARG_1, NULL, ret_number, f_type}, + {"typename", 1, 1, FEARG_1, NULL, + ret_string, f_typename}, {"undofile", 1, 1, FEARG_1, NULL, ret_string, f_undofile}, {"undotree", 0, 0, 0, NULL, diff --git a/src/proto/vim9type.pro b/src/proto/vim9type.pro --- a/src/proto/vim9type.pro +++ b/src/proto/vim9type.pro @@ -24,4 +24,5 @@ void common_type(type_T *type1, type_T * type_T *get_member_type_from_stack(type_T **stack_top, int count, int skip, garray_T *type_gap); char *vartype_name(vartype_T type); char *type_name(type_T *type, char **tofree); +void f_typename(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -318,8 +318,8 @@ def Test_job_info_return_type() if has('job') job_start(&shell) var jobs = job_info() - assert_equal(v:t_list, type(jobs)) - assert_equal(v:t_dict, type(job_info(jobs[0]))) + assert_equal('list', typename(jobs)) + assert_equal('dict', typename(job_info(jobs[0]))) job_stop(jobs[0]) endif enddef diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim --- a/src/testdir/test_vimscript.vim +++ b/src/testdir/test_vimscript.vim @@ -6600,6 +6600,14 @@ func Test_type() call ChangeYourMind() endfunc +func Test_typename() + call assert_equal('number', typename(123)) + call assert_equal('string', typename('x')) + call assert_equal('list', typename([123])) + call assert_equal('dict', typename(#{key: 123})) + call assert_equal('list>', typename([#{key: 123}])) +endfunc + "------------------------------------------------------------------------------- " Test 92: skipping code {{{1 "------------------------------------------------------------------------------- diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2339, +/**/ 2338, /**/ 2337, diff --git a/src/vim9type.c b/src/vim9type.c --- a/src/vim9type.c +++ b/src/vim9type.c @@ -1170,4 +1170,29 @@ type_name(type_T *type, char **tofree) return name; } +/* + * "typename(expr)" function + */ + void +f_typename(typval_T *argvars, typval_T *rettv) +{ + garray_T type_list; + type_T *type; + char *tofree; + char *name; + + rettv->v_type = VAR_STRING; + ga_init2(&type_list, sizeof(type_T *), 10); + type = typval2type(argvars, &type_list); + name = type_name(type, &tofree); + if (tofree != NULL) + rettv->vval.v_string = (char_u *)tofree; + else + { + rettv->vval.v_string = vim_strsave((char_u *)name); + vim_free(tofree); + } + clear_type_list(&type_list); +} + #endif // FEAT_EVAL