patch 8.2.4030: a script local funcref is not found from a mapping
Problem: A script local funcref is not found from a mapping.
Solution: When looking for a function, also find a script-local funcref.
(closes #9485)
diff --git a/src/evalvars.c b/src/evalvars.c
index 730c7d1..965b204 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -2690,7 +2690,7 @@
{
if ((flags & EVAL_VAR_IMPORT) == 0)
{
- if (sid != 0 && SCRIPT_ID_VALID(sid))
+ if (SCRIPT_ID_VALID(sid))
{
ht = &SCRIPT_VARS(sid);
if (ht != NULL)
@@ -2878,6 +2878,35 @@
}
/*
+ * Like find_var() but if the name starts with <SNR>99_ then look in the
+ * referenced script (used for a funcref).
+ */
+ dictitem_T *
+find_var_also_in_script(char_u *name, hashtab_T **htp, int no_autoload)
+{
+ if (STRNCMP(name, "<SNR>", 5) == 0 && isdigit(name[5]))
+ {
+ char_u *p = name + 5;
+ int sid = getdigits(&p);
+
+ if (SCRIPT_ID_VALID(sid) && *p == '_')
+ {
+ hashtab_T *ht = &SCRIPT_VARS(sid);
+
+ if (ht != NULL)
+ {
+ dictitem_T *di = find_var_in_ht(ht, 0, p + 1, no_autoload);
+
+ if (di != NULL)
+ return di;
+ }
+ }
+ }
+
+ return find_var(name, htp, no_autoload);
+}
+
+/*
* Find variable "varname" in hashtab "ht" with name "htname".
* When "varname" is empty returns curwin/curtab/etc vars dictionary.
* Returns NULL if not found.
diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro
index de1f7a1..487f88b 100644
--- a/src/proto/evalvars.pro
+++ b/src/proto/evalvars.pro
@@ -60,6 +60,7 @@
int eval_variable(char_u *name, int len, scid_T sid, typval_T *rettv, dictitem_T **dip, int flags);
void check_vars(char_u *name, int len);
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
+dictitem_T *find_var_also_in_script(char_u *name, hashtab_T **htp, int no_autoload);
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
hashtab_T *get_script_local_ht(void);
int lookup_scriptitem(char_u *name, size_t len, int cmd, cctx_T *dummy);
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index faa2671..b6dcf36 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1662,32 +1662,31 @@
&rtp = save_rtp
enddef
-" FIXME
-"def Test_use_import_in_mapping()
-" var lines =<< trim END
-" vim9script
-" export def Funcx()
-" g:result = 42
-" enddef
-" END
-" writefile(lines, 'XsomeExport.vim')
-" lines =<< trim END
-" vim9script
-" import './XsomeExport.vim' as some
-" var Funcy = some.Funcx
-" nnoremap <F3> :call <sid>Funcy()<cr>
-" END
-" writefile(lines, 'Xmapscript.vim')
-"
-" source Xmapscript.vim
-" feedkeys("\<F3>", "xt")
-" assert_equal(42, g:result)
-"
-" unlet g:result
-" delete('XsomeExport.vim')
-" delete('Xmapscript.vim')
-" nunmap <F3>
-"enddef
+def Test_use_import_in_mapping()
+ var lines =<< trim END
+ vim9script
+ export def Funcx()
+ g:result = 42
+ enddef
+ END
+ writefile(lines, 'XsomeExport.vim')
+ lines =<< trim END
+ vim9script
+ import './XsomeExport.vim' as some
+ var Funcy = some.Funcx
+ nnoremap <F3> :call <sid>Funcy()<cr>
+ END
+ writefile(lines, 'Xmapscript.vim')
+
+ source Xmapscript.vim
+ feedkeys("\<F3>", "xt")
+ assert_equal(42, g:result)
+
+ unlet g:result
+ delete('XsomeExport.vim')
+ delete('Xmapscript.vim')
+ nunmap <F3>
+enddef
def Test_vim9script_mix()
var lines =<< trim END
diff --git a/src/userfunc.c b/src/userfunc.c
index 7446d6e..6821569 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -1589,7 +1589,7 @@
cc = name[*lenp];
name[*lenp] = NUL;
- v = find_var(name, &ht, no_autoload);
+ v = find_var_also_in_script(name, &ht, no_autoload);
name[*lenp] = cc;
if (v != NULL)
{
diff --git a/src/version.c b/src/version.c
index 5bd5f83..5658467 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4030,
+/**/
4029,
/**/
4028,