diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-11-05 15:30:54 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-11-07 08:24:48 +0800 |
commit | b3e9010f4783a51407ec5a5ad9fda1216d4db3fe (patch) | |
tree | 9b7fb38eeafcec8a1fc19d13aff75b286f9cc3d9 | |
parent | 900dd2bdab85b25237cec638265d44c2174154ed (diff) | |
download | rneovim-b3e9010f4783a51407ec5a5ad9fda1216d4db3fe.tar.gz rneovim-b3e9010f4783a51407ec5a5ad9fda1216d4db3fe.tar.bz2 rneovim-b3e9010f4783a51407ec5a5ad9fda1216d4db3fe.zip |
vim-patch:8.2.3705: cannot pass a lambda name to function() or funcref()
Problem: Cannot pass a lambda name to function() or funcref(). (Yegappan
Lakshmanan)
Solution: Handle a lambda name differently.
https://github.com/vim/vim/commit/eba3b7f6645c8f856132b4c06a009a3b0a44e21c
Co-authored-by: Bram Moolenaar <Bram@vim.org>
-rw-r--r-- | src/nvim/eval.c | 5 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 30 | ||||
-rw-r--r-- | src/nvim/testdir/test_expr.vim | 7 |
3 files changed, 31 insertions, 11 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index fe4ae92834..c983388450 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5029,9 +5029,8 @@ void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref) if ((use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL) || is_funcref) { name = s; - trans_name = (char *)trans_function_name(&name, false, - TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD - | TFN_NO_DEREF, NULL, NULL); + trans_name = save_function_name(&name, false, + TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF, NULL); if (*name != NUL) { s = NULL; } diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index ef74ca58e3..e6b038a335 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -1886,6 +1886,27 @@ theend: return (char_u *)name; } +/// Call trans_function_name(), except that a lambda is returned as-is. +/// Returns the name in allocated memory. +char *save_function_name(char **name, bool skip, int flags, funcdict_T *fudi) +{ + char *p = *name; + char *saved; + + if (strncmp(p, "<lambda>", 8) == 0) { + p += 8; + (void)getdigits(&p, false, 0); + saved = xstrndup(*name, (size_t)(p - *name)); + if (fudi != NULL) { + CLEAR_POINTER(fudi); + } + } else { + saved = (char *)trans_function_name(&p, skip, flags, fudi, NULL); + } + *name = p; + return saved; +} + #define MAX_FUNC_NESTING 50 /// List functions. @@ -2000,14 +2021,7 @@ void ex_function(exarg_T *eap) // s:func script-local function name // g:func global function name, same as "func" p = eap->arg; - if (strncmp(p, "<lambda>", 8) == 0) { - p += 8; - (void)getdigits(&p, false, 0); - name = xstrndup(eap->arg, (size_t)(p - eap->arg)); - CLEAR_FIELD(fudi); - } else { - name = (char *)trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL); - } + name = save_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi); paren = (vim_strchr(p, '(') != NULL); if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) { // Return on an invalid expression in braces, unless the expression diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index ea874cc398..9dbc923b96 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -496,6 +496,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() |