diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/proto/vim9execute.pro | 1 | ||||
-rw-r--r-- | src/scriptfile.c | 14 | ||||
-rw-r--r-- | src/term.c | 23 | ||||
-rw-r--r-- | src/testdir/test_vim9_import.vim | 36 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 38 |
6 files changed, 96 insertions, 18 deletions
diff --git a/src/proto/vim9execute.pro b/src/proto/vim9execute.pro index bd6709291..80afb8536 100644 --- a/src/proto/vim9execute.pro +++ b/src/proto/vim9execute.pro @@ -6,6 +6,7 @@ int set_ref_in_funcstacks(int copyID); char_u *char_from_string(char_u *str, varnumber_T index); char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive); int fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, ectx_T *ectx); +int may_load_script(int sid, int *loaded); typval_T *lookup_debug_var(char_u *name); int may_break_in_function(ufunc_T *ufunc); int exe_typval_instr(typval_T *tv, typval_T *rettv); diff --git a/src/scriptfile.c b/src/scriptfile.c index 7e14cdc6e..2a1f84a50 100644 --- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -117,7 +117,7 @@ estack_pop(void) } /* - * Get the current value for <sfile> in allocated memory. + * Get the current value for "which" in allocated memory. * "which" is ESTACK_SFILE for <sfile>, ESTACK_STACK for <stack> or * ESTACK_SCRIPT for <script>. */ @@ -2468,6 +2468,18 @@ script_autoload( int i; int ret_sid; + // If the name starts with "<SNR>123_" then "123" is the script ID. + if (name[0] == K_SPECIAL && name[1] == KS_EXTRA && name[2] == KE_SNR) + { + p = name + 3; + ret_sid = (int)getdigits(&p); + if (*p == '_' && SCRIPT_ID_VALID(ret_sid)) + { + may_load_script(ret_sid, &ret); + return ret; + } + } + // If there is no '#' after name[0] there is no package name. p = vim_strchr(name, AUTOLOAD_CHAR); if (p == NULL || p == name) diff --git a/src/term.c b/src/term.c index 8709cd365..e51134f16 100644 --- a/src/term.c +++ b/src/term.c @@ -6010,8 +6010,11 @@ replace_termcodes( { #ifdef FEAT_EVAL /* - * Replace <SID> by K_SNR <script-nr> _. + * Change <SID>Func to K_SNR <script-nr> _Func. This name is used + * for script-locla user functions. * (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14) + * Also change <SID>name.Func to K_SNR <import-script-nr> _Func. + * Only if "name" is recognized as an import. */ if (STRNICMP(src, "<SID>", 5) == 0) { @@ -6019,12 +6022,26 @@ replace_termcodes( emsg(_(e_using_sid_not_in_script_context)); else { + char_u *dot; + long sid = current_sctx.sc_sid; + src += 5; + if (in_vim9script() + && (dot = vim_strchr(src, '.')) != NULL) + { + imported_T *imp = find_imported(src, dot - src, FALSE); + + if (imp != NULL) + { + sid = imp->imp_sid; + src = dot + 1; + } + } + result[dlen++] = K_SPECIAL; result[dlen++] = (int)KS_EXTRA; result[dlen++] = (int)KE_SNR; - sprintf((char *)result + dlen, "%ld", - (long)current_sctx.sc_sid); + sprintf((char *)result + dlen, "%ld", sid); dlen += (int)STRLEN(result + dlen); result[dlen++] = '_'; continue; diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim index 2c3792f84..94cb76033 100644 --- a/src/testdir/test_vim9_import.vim +++ b/src/testdir/test_vim9_import.vim @@ -642,8 +642,8 @@ enddef def Test_use_import_in_mapping() var lines =<< trim END vim9script - export def Funcx() - g:result = 42 + export def Funcx(nr: number) + g:result = nr enddef END writefile(lines, 'XsomeExport.vim') @@ -651,18 +651,48 @@ def Test_use_import_in_mapping() vim9script import './XsomeExport.vim' as some var Funcy = some.Funcx - nnoremap <F3> :call <sid>Funcy()<cr> + nnoremap <F3> :call <sid>Funcy(42)<cr> + nnoremap <F4> :call <sid>some.Funcx(44)<cr> END writefile(lines, 'Xmapscript.vim') source Xmapscript.vim feedkeys("\<F3>", "xt") assert_equal(42, g:result) + feedkeys("\<F4>", "xt") + assert_equal(44, g:result) unlet g:result delete('XsomeExport.vim') delete('Xmapscript.vim') nunmap <F3> + nunmap <F4> +enddef + +def Test_use_autoload_import_in_mapping() + var lines =<< trim END + vim9script + export def Func() + g:result = 42 + enddef + END + writefile(lines, 'XautoloadExport.vim') + lines =<< trim END + vim9script + import autoload './XautoloadExport.vim' as some + nnoremap <F3> :call <SID>some.Func()<CR> + END + writefile(lines, 'Xmapscript.vim') + + source Xmapscript.vim + assert_match('\d\+ A: .*XautoloadExport.vim', execute('scriptnames')->split("\n")[-1]) + feedkeys("\<F3>", "xt") + assert_equal(42, g:result) + + unlet g:result + delete('XautoloadExport.vim') + delete('Xmapscript.vim') + nunmap <F3> enddef def Test_use_import_in_command_completion() diff --git a/src/version.c b/src/version.c index 9f9917726..e1a5bbd66 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4748, +/**/ 4747, /**/ 4746, diff --git a/src/vim9execute.c b/src/vim9execute.c index 0e8a1dd95..da2822c1b 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -1658,6 +1658,29 @@ exec_command(isn_T *iptr) return OK; } +/* + * If script "sid" is not loaded yet then load it now. + * Caller must make sure "sid" is a valid script ID. + * "loaded" is set to TRUE if the script had to be loaded. + * Returns FAIL if loading fails, OK if already loaded or loaded now. + */ + int +may_load_script(int sid, int *loaded) +{ + scriptitem_T *si = SCRIPT_ITEM(sid); + + if (si->sn_state == SN_STATE_NOT_LOADED) + { + *loaded = TRUE; + if (do_source(si->sn_name, FALSE, DOSO_NONE, NULL) == FAIL) + { + semsg(_(e_cant_open_file_str), si->sn_name); + return FAIL; + } + } + return OK; +} + // used for v_instr of typval of VAR_INSTR struct instr_S { ectx_T *instr_ectx; @@ -2632,18 +2655,11 @@ exec_instructions(ectx_T *ectx) case ISN_SOURCE: { - scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.number); - - if (si->sn_state == SN_STATE_NOT_LOADED) - { - SOURCING_LNUM = iptr->isn_lnum; - if (do_source(si->sn_name, FALSE, DOSO_NONE, NULL) + int notused; + SOURCING_LNUM = iptr->isn_lnum; + if (may_load_script((int)iptr->isn_arg.number, ¬used) == FAIL) - { - semsg(_(e_cant_open_file_str), si->sn_name); - goto on_error; - } - } + goto on_error; } break; |