diff options
Diffstat (limited to 'src/evalvars.c')
-rw-r--r-- | src/evalvars.c | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/src/evalvars.c b/src/evalvars.c index 70bb6da2ce..b70a3cd394 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -3340,12 +3340,31 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload) } } + // and finally try + return find_var_autoload_prefix(name, 0, htp, NULL); +} + +/* + * Find variable "name" with sn_autoload_prefix. + * Return a pointer to it if found, NULL if not found. + * When "sid" > 0, use it otherwise use "current_sctx.sc_sid". + * When "htp" is not NULL set "htp" to the hashtab_T used. + * When "namep" is not NULL set "namep" to the generated name, and + * then the caller gets ownership and is responsible for freeing the name. + */ + dictitem_T * +find_var_autoload_prefix(char_u *name, int sid, hashtab_T **htp, + char_u **namep) +{ + hashtab_T *ht; + dictitem_T *ret = NULL; // When using "vim9script autoload" script-local items are prefixed but can // be used with s:name. - if (SCRIPT_ID_VALID(current_sctx.sc_sid) + int check_sid = sid > 0 ? sid : current_sctx.sc_sid; + if (SCRIPT_ID_VALID(check_sid) && (in_vim9script() || (name[0] == 's' && name[1] == ':'))) { - scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); + scriptitem_T *si = SCRIPT_ITEM(check_sid); if (si->sn_autoload_prefix != NULL) { @@ -3355,20 +3374,26 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload) if (auto_name != NULL) { + int free_auto_name = TRUE; ht = &globvarht; ret = find_var_in_ht(ht, 'g', auto_name, TRUE); - vim_free(auto_name); if (ret != NULL) { if (htp != NULL) *htp = ht; - return ret; + if (namep != NULL) + { + free_auto_name = FALSE; + *namep = auto_name; + } } + if (free_auto_name) + vim_free(auto_name); } } } - return NULL; + return ret; } /* @@ -3508,7 +3533,11 @@ lookup_scriptitem( hi = hash_find(ht, p); res = HASHITEM_EMPTY(hi) ? FAIL : OK; - // if not script-local, then perhaps imported + // if not script-local, then perhaps autoload-exported + if (res == FAIL && find_var_autoload_prefix(p, 0, NULL, NULL) != NULL) + res = OK; + + // if not script-local or autoload, then perhaps imported if (res == FAIL && find_imported(p, 0, FALSE) != NULL) res = OK; if (p != buffer) @@ -3904,23 +3933,40 @@ set_var_const( if (sid != 0) { + varname = NULL; if (SCRIPT_ID_VALID(sid)) - ht = &SCRIPT_VARS(sid); - varname = name; + { + char_u *auto_name = NULL; + if (find_var_autoload_prefix(name, sid, &ht, &auto_name) != NULL) + { + var_in_autoload = TRUE; + varname = auto_name; + name_tofree = varname; + } + else + ht = &SCRIPT_VARS(sid); + } + if (varname == NULL) + varname = name; } else { - scriptitem_T *si; + scriptitem_T *si; + char_u *auto_name = NULL; - if (in_vim9script() && is_export - && SCRIPT_ID_VALID(current_sctx.sc_sid) - && (si = SCRIPT_ITEM(current_sctx.sc_sid)) - ->sn_autoload_prefix != NULL) + if (in_vim9script() + && SCRIPT_ID_VALID(current_sctx.sc_sid) + && (si = SCRIPT_ITEM(current_sctx.sc_sid)) + ->sn_autoload_prefix != NULL + && (is_export + || find_var_autoload_prefix(name, 0, NULL, &auto_name) + != NULL)) { // In a vim9 autoload script an exported variable is put in the // global namespace with the autoload prefix. var_in_autoload = TRUE; - varname = concat_str(si->sn_autoload_prefix, name); + varname = auto_name != NULL ? auto_name + : concat_str(si->sn_autoload_prefix, name); if (varname == NULL) goto failed; name_tofree = varname; |