summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-01-12 21:49:00 +0100
committerBram Moolenaar <Bram@vim.org>2021-01-12 21:49:00 +0100
commita47e05f04a5a5c0369c949157c24d09cbe64ad6a (patch)
tree7d6a27b717ed6c478f4642fd7af13913a4c07f3b
parent64ed4d4398e92ac56a9bbd66d5ec992dd4c335f7 (diff)
patch 8.2.2339: cannot get the type of a value as a stringv8.2.2339
Problem: Cannot get the type of a value as a string. Solution: Add typename().
-rw-r--r--runtime/doc/eval.txt11
-rw-r--r--runtime/doc/usr_41.txt3
-rw-r--r--src/evalfunc.c2
-rw-r--r--src/proto/vim9type.pro1
-rw-r--r--src/testdir/test_vim9_builtin.vim4
-rw-r--r--src/testdir/test_vimscript.vim8
-rw-r--r--src/version.c2
-rw-r--r--src/vim9type.c25
8 files changed, 52 insertions, 4 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index d31ba2d362..76c5548532 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -3016,7 +3016,8 @@ tr({src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
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 representing the type of {expr}.
< 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<number>
+
+
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
index 624bb934f5..5f9c8e1bdc 100644
--- 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
index 65cb59f8d4..0e6d759c66 100644
--- 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
index bc306687f8..316c650115 100644
--- a/src/proto/vim9type.pro
+++ b/src/proto/vim9type.pro
@@ -24,4 +24,5 @@ void common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap
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
index 83b9931f24..a84b7f6210 100644
--- 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<job>', typename(jobs))
+ assert_equal('dict<any>', 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
index dba8c73fc8..0ba933b7cb 100644
--- 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<number>', typename([123]))
+ call assert_equal('dict<number>', typename(#{key: 123}))
+ call assert_equal('list<dict<number>>', typename([#{key: 123}]))
+endfunc
+
"-------------------------------------------------------------------------------
" Test 92: skipping code {{{1
"-------------------------------------------------------------------------------
diff --git a/src/version.c b/src/version.c
index 1b63a5e9c7..fe41ec27a0 100644
--- 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
index c65f747483..85f9bd8347 100644
--- 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