summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-02-18 17:50:47 +0000
committerBram Moolenaar <Bram@vim.org>2022-02-18 17:50:47 +0000
commit1fca5f3e86f08e696058fc7e86dfe41b415a78e6 (patch)
tree533fd7d2f262b2d4238be66a00327b13e979e4cb
parentb8fb5bb68d45f3e52bb9ea201dc9e7dc6b6d2c6d (diff)
patch 8.2.4416: Vim9: using a script-local function requires using "s:"v8.2.4416
Problem: Vim9: using a script-local function requires using "s:" when setting 'completefunc'. Solution: Do not require "s:" in Vim9 script. (closes #9796)
-rw-r--r--runtime/doc/options.txt16
-rw-r--r--src/testdir/test_ins_complete.vim17
-rw-r--r--src/userfunc.c24
-rw-r--r--src/version.c2
4 files changed, 50 insertions, 9 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 1d3f76864b..8fcbc99c40 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -383,12 +383,22 @@ lambda it will be converted to the name, e.g. "<lambda>123". Examples:
set opfunc=function('MyOpFunc')
set opfunc=funcref('MyOpFunc')
set opfunc={a\ ->\ MyOpFunc(a)}
- " set using a funcref variable
+
+Set to a script-local function: >
+ set opfunc=s:MyLocalFunc
+ set opfunc=<SID>MyLocalFunc
+In |Vim9| script the "s:" and "<SID>" can be omitted if the function exists in
+the script: >
+ set opfunc=MyLocalFunc
+
+Set using a funcref variable: >
let Fn = function('MyTagFunc')
let &tagfunc = Fn
- " set using a lambda expression
+
+Set using a lambda expression: >
let &tagfunc = {t -> MyTagFunc(t)}
- " set using a variable with lambda expression
+
+Set using a variable with lambda expression: >
let L = {a, b, c -> MyTagFunc(a, b , c)}
let &tagfunc = L
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index 7e3fd296e2..cb643769ea 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -1455,6 +1455,23 @@ func Test_completefunc_callback()
bw!
delfunc s:CompleteFunc3
+ " In Vim9 script s: can be omitted
+ let lines =<< trim END
+ vim9script
+ var CompleteFunc4Args = []
+ def CompleteFunc4(findstart: bool, base: string): any
+ add(CompleteFunc4Args, [findstart, base])
+ return findstart ? 0 : []
+ enddef
+ set completefunc=CompleteFunc4
+ new
+ setline(1, 'script1')
+ feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
+ assert_equal([[1, ''], [0, 'script1']], CompleteFunc4Args)
+ bw!
+ END
+ call v9.CheckScriptSuccess(lines)
+
" invalid return value
let &completefunc = {a -> 'abc'}
call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
diff --git a/src/userfunc.c b/src/userfunc.c
index 10a529e03f..696320c3e9 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -4024,16 +4024,29 @@ untrans_function_name(char_u *name)
get_scriptlocal_funcname(char_u *funcname)
{
char sid_buf[25];
- int off;
+ int off = *funcname == 's' ? 2 : 5;
char_u *newname;
+ char_u *p = funcname;
if (funcname == NULL)
return NULL;
if (STRNCMP(funcname, "s:", 2) != 0
&& STRNCMP(funcname, "<SID>", 5) != 0)
- // The function name is not a script-local function name
- return NULL;
+ {
+ ufunc_T *ufunc;
+
+ // The function name does not have a script-local prefix. Try finding
+ // it when in a Vim9 script and there is no "g:" prefix.
+ if (!in_vim9script() || STRNCMP(funcname, "g:", 2) == 0)
+ return NULL;
+ ufunc = find_func(funcname, FALSE);
+ if (ufunc == NULL || func_is_global(ufunc)
+ || (p = vim_strchr(ufunc->uf_name, '_')) == NULL)
+ return NULL;
+ ++p;
+ off = 0;
+ }
if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
{
@@ -4043,12 +4056,11 @@ get_scriptlocal_funcname(char_u *funcname)
// Expand s: prefix into <SNR>nr_<name>
vim_snprintf(sid_buf, sizeof(sid_buf), "<SNR>%ld_",
(long)current_sctx.sc_sid);
- off = *funcname == 's' ? 2 : 5;
- newname = alloc(STRLEN(sid_buf) + STRLEN(funcname + off) + 1);
+ newname = alloc(STRLEN(sid_buf) + STRLEN(p + off) + 1);
if (newname == NULL)
return NULL;
STRCPY(newname, sid_buf);
- STRCAT(newname, funcname + off);
+ STRCAT(newname, p + off);
return newname;
}
diff --git a/src/version.c b/src/version.c
index f313448c2d..c9968125b8 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 */
/**/
+ 4416,
+/**/
4415,
/**/
4414,