summaryrefslogtreecommitdiff
path: root/src/userfunc.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-01-11 15:24:05 +0000
committerBram Moolenaar <Bram@vim.org>2022-01-11 15:24:05 +0000
commitb8822442d716df0230c79531132e530e95cc17e3 (patch)
treeb3ef7369be4f32805e8fcf04aee960d38d45e2e5 /src/userfunc.c
parent0bbca540f7377889e2154aa5731f6eeffcb5c0cc (diff)
downloadvim-git-8.2.4063.tar.gz
patch 8.2.4063: Vim9: exported function in autoload script not foundv8.2.4063
Problem: Vim9: exported function in autoload script not found. (Yegappan Lakshmanan) Solution: Use the autoload prefix to search for the function.
Diffstat (limited to 'src/userfunc.c')
-rw-r--r--src/userfunc.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/src/userfunc.c b/src/userfunc.c
index 48f5890e8..4516a48aa 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -1871,9 +1871,13 @@ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
static ufunc_T *
find_func_with_sid(char_u *name, int sid)
{
- hashitem_T *hi;
- char_u buffer[200];
+ hashitem_T *hi;
+ char_u buffer[200];
+
+ if (!SCRIPT_ID_VALID(sid))
+ return NULL; // not in a script
+ // A script-local function is stored as "<SNR>99_name".
buffer[0] = K_SPECIAL;
buffer[1] = KS_EXTRA;
buffer[2] = (int)KE_SNR;
@@ -1882,6 +1886,46 @@ find_func_with_sid(char_u *name, int sid)
hi = hash_find(&func_hashtab, buffer);
if (!HASHITEM_EMPTY(hi))
return HI2UF(hi);
+ return NULL;
+}
+
+/*
+ * Find a function "name" in script "sid" prefixing the autoload prefix.
+ */
+ static ufunc_T *
+find_func_with_prefix(char_u *name, int sid)
+{
+ hashitem_T *hi;
+ char_u buffer[200];
+ scriptitem_T *si;
+
+ if (vim_strchr(name, AUTOLOAD_CHAR) != 0)
+ return NULL; // already has the prefix
+ if (!SCRIPT_ID_VALID(sid))
+ return NULL; // not in a script
+ si = SCRIPT_ITEM(sid);
+ if (si->sn_autoload_prefix != NULL)
+ {
+ size_t len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1;
+ char_u *auto_name;
+
+ // An exported function in an autoload script is stored as
+ // "dir#path#name".
+ if (len < sizeof(buffer))
+ auto_name = buffer;
+ else
+ auto_name = alloc(len);
+ if (auto_name != NULL)
+ {
+ vim_snprintf((char *)auto_name, len, "%s%s",
+ si->sn_autoload_prefix, name);
+ hi = hash_find(&func_hashtab, auto_name);
+ if (auto_name != buffer)
+ vim_free(auto_name);
+ if (!HASHITEM_EMPTY(hi))
+ return HI2UF(hi);
+ }
+ }
return NULL;
}
@@ -1917,7 +1961,9 @@ find_func_even_dead(char_u *name, int is_global, cctx_T *cctx UNUSED)
if (!HASHITEM_EMPTY(hi))
return HI2UF(hi);
- return NULL;
+ // Find autoload function if this is an autoload script.
+ return find_func_with_prefix(name[0] == 's' && name[1] == ':'
+ ? name + 2 : name, current_sctx.sc_sid);
}
/*