To: vim_dev@googlegroups.com Subject: Patch 8.2.4748 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4748 Problem: Cannot use an imported function in a mapping. Solution: Recognize name.Func. Files: runtime/doc/vim9.txt, src/term.c, src/vim9execute.c, src/proto/vim9execute.pro, src/scriptfile.c, src/testdir/test_vim9_import.vim *** ../vim-8.2.4747/runtime/doc/vim9.txt 2022-04-10 11:26:00.941539608 +0100 --- runtime/doc/vim9.txt 2022-04-14 12:55:06.633007990 +0100 *************** *** 1542,1548 **** name # Error! echo that .name # Error! ! < *:import-cycle* The `import` commands are executed when encountered. If script A imports script B, and B (directly or indirectly) imports A, this will be skipped over. At this point items in A after "import B" will not have been processed and --- 1720,1734 ---- name # Error! echo that .name # Error! ! ! To refer to a function in an imported script in a mapping, || can be ! used: > ! noremap ,a :call name.Function() ! ! When the mapping is defined "name." will be replaced with and the ! script ID of the imported script. ! ! *:import-cycle* The `import` commands are executed when encountered. If script A imports script B, and B (directly or indirectly) imports A, this will be skipped over. At this point items in A after "import B" will not have been processed and *** ../vim-8.2.4747/src/term.c 2022-03-09 13:00:50.776824777 +0000 --- src/term.c 2022-04-14 12:07:46.058053594 +0100 *************** *** 6010,6017 **** { #ifdef FEAT_EVAL /* ! * Replace by K_SNR _. * (room: 5 * 6 = 30 bytes; needed: 3 + + 1 <= 14) */ if (STRNICMP(src, "", 5) == 0) { --- 6010,6020 ---- { #ifdef FEAT_EVAL /* ! * Change Func to K_SNR _Func. This name is used ! * for script-locla user functions. * (room: 5 * 6 = 30 bytes; needed: 3 + + 1 <= 14) + * Also change name.Func to K_SNR _Func. + * Only if "name" is recognized as an import. */ if (STRNICMP(src, "", 5) == 0) { *************** *** 6019,6030 **** emsg(_(e_using_sid_not_in_script_context)); else { src += 5; result[dlen++] = K_SPECIAL; result[dlen++] = (int)KS_EXTRA; result[dlen++] = (int)KE_SNR; ! sprintf((char *)result + dlen, "%ld", ! (long)current_sctx.sc_sid); dlen += (int)STRLEN(result + dlen); result[dlen++] = '_'; continue; --- 6022,6047 ---- 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", sid); dlen += (int)STRLEN(result + dlen); result[dlen++] = '_'; continue; *** ../vim-8.2.4747/src/vim9execute.c 2022-04-05 21:40:32.107458262 +0100 --- src/vim9execute.c 2022-04-14 12:39:01.904659075 +0100 *************** *** 1658,1663 **** --- 1658,1686 ---- 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,2649 **** 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) == FAIL) ! { ! semsg(_(e_cant_open_file_str), si->sn_name); ! goto on_error; ! } ! } } break; --- 2655,2665 ---- case ISN_SOURCE: { ! int notused; ! SOURCING_LNUM = iptr->isn_lnum; ! if (may_load_script((int)iptr->isn_arg.number, ¬used) == FAIL) ! goto on_error; } break; *** ../vim-8.2.4747/src/proto/vim9execute.pro 2022-03-15 15:57:00.426428445 +0000 --- src/proto/vim9execute.pro 2022-04-14 12:38:23.248578404 +0100 *************** *** 6,11 **** --- 6,12 ---- 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); *** ../vim-8.2.4747/src/scriptfile.c 2022-04-09 21:41:22.266689586 +0100 --- src/scriptfile.c 2022-04-14 12:39:08.148671284 +0100 *************** *** 117,123 **** } /* ! * Get the current value for in allocated memory. * "which" is ESTACK_SFILE for , ESTACK_STACK for or * ESTACK_SCRIPT for