Skip to content

Commit efa9444

Browse files
committed
patch 8.2.1399: Vim9: may find imported item in wrong script
Problem: Vim9: may find imported item in wrong script. Solution: When looking up script-local function use the embedded script ID. (issue #6644)
1 parent daa2f36 commit efa9444

5 files changed

Lines changed: 45 additions & 9 deletions

File tree

src/proto/vim9compile.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ char *vartype_name(vartype_T type);
1212
char *type_name(type_T *type, char **tofree);
1313
int get_script_item_idx(int sid, char_u *name, int check_writable);
1414
imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
15+
imported_T *find_imported_in_script(char_u *name, size_t len, int sid);
1516
int vim9_comment_start(char_u *p);
1617
char_u *peek_next_line_from_context(cctx_T *cctx);
1718
char_u *next_line_from_context(cctx_T *cctx, int skip_comment);

src/testdir/test_vim9_script.vim

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,31 @@ def Test_import_in_filetype()
14301430
&rtp = save_rtp
14311431
enddef
14321432

1433+
def Test_use_import_in_mapping()
1434+
let lines =<< trim END
1435+
vim9script
1436+
export def Funcx()
1437+
g:result = 42
1438+
enddef
1439+
END
1440+
writefile(lines, 'XsomeExport.vim')
1441+
lines =<< trim END
1442+
vim9script
1443+
import Funcx from './XsomeExport.vim'
1444+
nnoremap <C-B> :call <sid>Funcx()<cr>
1445+
END
1446+
writefile(lines, 'Xmapscript.vim')
1447+
1448+
source Xmapscript.vim
1449+
feedkeys("\<c-b>", "xt")
1450+
assert_equal(42, g:result)
1451+
1452+
unlet g:result
1453+
delete('XsomeExport.vim')
1454+
delete('Xmapscript.vim')
1455+
nunmap <C-B>
1456+
enddef
1457+
14331458
def Test_vim9script_fails()
14341459
CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
14351460
CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')

src/userfunc.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ find_func_even_dead(char_u *name, int is_global, cctx_T *cctx)
791791
{
792792
int vim9script = in_vim9script();
793793
char_u *after_script = NULL;
794+
long sid = 0;
794795

795796
if (vim9script)
796797
{
@@ -800,27 +801,27 @@ find_func_even_dead(char_u *name, int is_global, cctx_T *cctx)
800801
return func;
801802
}
802803

803-
if (!vim9script
804-
&& name[0] == K_SPECIAL
804+
if (name[0] == K_SPECIAL
805805
&& name[1] == KS_EXTRA
806806
&& name[2] == KE_SNR)
807807
{
808-
long sid;
809-
810808
// Caller changes s: to <SNR>99_name.
811809

812810
after_script = name + 3;
813811
sid = getdigits(&after_script);
814-
if (sid == current_sctx.sc_sid && *after_script == '_')
812+
if (*after_script == '_')
815813
++after_script;
816814
else
817815
after_script = NULL;
818816
}
819817
if (vim9script || after_script != NULL)
820818
{
821819
// Find imported function before global one.
822-
imported = find_imported(
823-
after_script == NULL ? name : after_script, 0, cctx);
820+
if (after_script != NULL && sid != current_sctx.sc_sid)
821+
imported = find_imported_in_script(after_script, 0, sid);
822+
else
823+
imported = find_imported(after_script == NULL
824+
? name : after_script, 0, cctx);
824825
if (imported != NULL && imported->imp_funcname != NULL)
825826
{
826827
hi = hash_find(&func_hashtab, imported->imp_funcname);

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+
1399,
757759
/**/
758760
1398,
759761
/**/

src/vim9compile.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,12 +2548,10 @@ get_script_item_idx(int sid, char_u *name, int check_writable)
25482548
imported_T *
25492549
find_imported(char_u *name, size_t len, cctx_T *cctx)
25502550
{
2551-
scriptitem_T *si;
25522551
int idx;
25532552

25542553
if (current_sctx.sc_sid <= 0)
25552554
return NULL;
2556-
si = SCRIPT_ITEM(current_sctx.sc_sid);
25572555
if (cctx != NULL)
25582556
for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx)
25592557
{
@@ -2566,6 +2564,15 @@ find_imported(char_u *name, size_t len, cctx_T *cctx)
25662564
return import;
25672565
}
25682566

2567+
return find_imported_in_script(name, len, current_sctx.sc_sid);
2568+
}
2569+
2570+
imported_T *
2571+
find_imported_in_script(char_u *name, size_t len, int sid)
2572+
{
2573+
scriptitem_T *si = SCRIPT_ITEM(sid);
2574+
int idx;
2575+
25692576
for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
25702577
{
25712578
imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;

0 commit comments

Comments
 (0)