summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-11-30 18:25:08 +0000
committerBram Moolenaar <Bram@vim.org>2021-11-30 18:25:08 +0000
commiteba3b7f6645c8f856132b4c06a009a3b0a44e21c (patch)
tree020a6f90c5d1d78881e237b5339e63a59b266769
parentab36e6ae7b87b0295fb19270e4339a734875c6b1 (diff)
downloadvim-git-eba3b7f6645c8f856132b4c06a009a3b0a44e21c.tar.gz
patch 8.2.3705: cannot pass a lambda name to function() or funcref()v8.2.3705
Problem: Cannot pass a lambda name to function() or funcref(). (Yegappan Lakshmanan) Solution: Handle a lambda name differently.
-rw-r--r--src/evalfunc.c5
-rw-r--r--src/proto/userfunc.pro1
-rw-r--r--src/testdir/test_expr.vim7
-rw-r--r--src/userfunc.c42
-rw-r--r--src/version.c2
5 files changed, 44 insertions, 13 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index e04052b8a..d0b80bea8 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3955,9 +3955,8 @@ common_function(typval_T *argvars, typval_T *rettv, int is_funcref)
if ((use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL) || is_funcref)
{
name = s;
- trans_name = trans_function_name(&name, &is_global, FALSE,
- TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF,
- NULL, NULL, NULL);
+ trans_name = save_function_name(&name, &is_global, FALSE,
+ TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF, NULL);
if (*name != NUL)
s = NULL;
}
diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro
index 08dedae0a..dcc5b34d0 100644
--- a/src/proto/userfunc.pro
+++ b/src/proto/userfunc.pro
@@ -33,6 +33,7 @@ int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typva
char_u *printable_func_name(ufunc_T *fp);
char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial, type_T **type);
char_u *untrans_function_name(char_u *name);
+char_u *save_function_name(char_u **name, int *is_global, int skip, int flags, funcdict_T *fudi);
void list_functions(regmatch_T *regmatch);
ufunc_T *define_function(exarg_T *eap, char_u *name_arg);
void ex_function(exarg_T *eap);
diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim
index 323ce2626..46d718612 100644
--- a/src/testdir/test_expr.vim
+++ b/src/testdir/test_expr.vim
@@ -547,6 +547,13 @@ func Test_function_with_funcref()
call assert_fails("call function('foo()')", 'E475:')
call assert_fails("call function('foo()')", 'foo()')
call assert_fails("function('')", 'E129:')
+
+ let Len = {s -> strlen(s)}
+ call assert_equal(6, Len('foobar'))
+ let name = string(Len)
+ " can evaluate "function('<lambda>99')"
+ call execute('let Ref = ' .. name)
+ call assert_equal(4, Ref('text'))
endfunc
func Test_funcref()
diff --git a/src/userfunc.c b/src/userfunc.c
index c961115e0..3edbf891e 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -3811,6 +3811,36 @@ untrans_function_name(char_u *name)
}
/*
+ * Call trans_function_name(), except that a lambda is returned as-is.
+ * Returns the name in allocated memory.
+ */
+ char_u *
+save_function_name(
+ char_u **name,
+ int *is_global,
+ int skip,
+ int flags,
+ funcdict_T *fudi)
+{
+ char_u *p = *name;
+ char_u *saved;
+
+ if (STRNCMP(p, "<lambda>", 8) == 0)
+ {
+ p += 8;
+ (void)getdigits(&p);
+ saved = vim_strnsave(*name, p - *name);
+ if (fudi != NULL)
+ CLEAR_POINTER(fudi);
+ }
+ else
+ saved = trans_function_name(&p, is_global, skip,
+ flags, fudi, NULL, NULL);
+ *name = p;
+ return saved;
+}
+
+/*
* List functions. When "regmatch" is NULL all of then.
* Otherwise functions matching "regmatch".
*/
@@ -3950,16 +3980,8 @@ define_function(exarg_T *eap, char_u *name_arg)
}
else
{
- if (STRNCMP(p, "<lambda>", 8) == 0)
- {
- p += 8;
- (void)getdigits(&p);
- name = vim_strnsave(eap->arg, p - eap->arg);
- CLEAR_FIELD(fudi);
- }
- else
- name = trans_function_name(&p, &is_global, eap->skip,
- TFN_NO_AUTOLOAD, &fudi, NULL, NULL);
+ name = save_function_name(&p, &is_global, eap->skip,
+ TFN_NO_AUTOLOAD, &fudi);
paren = (vim_strchr(p, '(') != NULL);
if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
{
diff --git a/src/version.c b/src/version.c
index 32efc5c83..570cd2174 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3705,
+/**/
3704,
/**/
3703,