Skip to content

Commit 95006e3

Browse files
committed
patch 8.2.1541: Vim9: cannot find function reference for s:Func
Problem: Vim9: cannot find function reference for s:Func. Solution: Recognize <SNR> prefix. (closes #6805)
1 parent 9894556 commit 95006e3

4 files changed

Lines changed: 31 additions & 4 deletions

File tree

src/testdir/test_vim9_script.vim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,10 @@ def Test_vim9script_reload_import()
16521652
delete('Ximport.vim')
16531653
enddef
16541654

1655+
def s:RetSome(): string
1656+
return 'some'
1657+
enddef
1658+
16551659
" Not exported function that is referenced needs to be accessed by the
16561660
" script-local name.
16571661
def Test_vim9script_funcref()
@@ -1683,6 +1687,9 @@ def Test_vim9script_funcref()
16831687
unlet g:result
16841688
delete('Xsort.vim')
16851689
delete('Xscript.vim')
1690+
1691+
let Funcref = function('s:RetSome')
1692+
assert_equal('some', Funcref())
16861693
enddef
16871694

16881695
" Check that when searching for "FilterFunc" it finds the import in the

src/userfunc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,12 @@ find_func_even_dead(char_u *name, int is_global, cctx_T *cctx)
808808

809809
if (!is_global)
810810
{
811-
int vim9script = in_vim9script();
812811
char_u *after_script = NULL;
813812
long sid = 0;
813+
int find_script_local = in_vim9script()
814+
&& eval_isnamec1(*name) && name[1] != ':';
814815

815-
if (vim9script)
816+
if (find_script_local)
816817
{
817818
// Find script-local function before global one.
818819
func = find_func_with_sid(name, current_sctx.sc_sid);
@@ -833,7 +834,7 @@ find_func_even_dead(char_u *name, int is_global, cctx_T *cctx)
833834
else
834835
after_script = NULL;
835836
}
836-
if (vim9script || after_script != NULL)
837+
if (find_script_local || after_script != NULL)
837838
{
838839
// Find imported function before global one.
839840
if (after_script != NULL && sid != current_sctx.sc_sid)

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ static char *(features[]) =
754754

755755
static int included_patches[] =
756756
{ /* Add new patch number below this line */
757+
/**/
758+
1541,
757759
/**/
758760
1540,
759761
/**/

src/vim9execute.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ call_partial(typval_T *tv, int argcount_arg, ectx_T *ectx)
614614
int argcount = argcount_arg;
615615
char_u *name = NULL;
616616
int called_emsg_before = called_emsg;
617+
int res;
617618

618619
if (tv->v_type == VAR_PARTIAL)
619620
{
@@ -650,7 +651,23 @@ call_partial(typval_T *tv, int argcount_arg, ectx_T *ectx)
650651
}
651652
else if (tv->v_type == VAR_FUNC)
652653
name = tv->vval.v_string;
653-
if (name == NULL || call_by_name(name, argcount, ectx, NULL) == FAIL)
654+
if (name != NULL)
655+
{
656+
char_u fname_buf[FLEN_FIXED + 1];
657+
char_u *tofree = NULL;
658+
int error = FCERR_NONE;
659+
char_u *fname;
660+
661+
// May need to translate <SNR>123_ to K_SNR.
662+
fname = fname_trans_sid(name, fname_buf, &tofree, &error);
663+
if (error != FCERR_NONE)
664+
res = FAIL;
665+
else
666+
res = call_by_name(fname, argcount, ectx, NULL);
667+
vim_free(tofree);
668+
}
669+
670+
if (name == NULL || res == FAIL)
654671
{
655672
if (called_emsg == called_emsg_before)
656673
semsg(_(e_unknownfunc),

0 commit comments

Comments
 (0)