patch 8.2.4260: Vim9: can still use a global function without g:
Problem: Vim9: can still use a global function without g: at the script
level.
Solution: Also check for g: at the script level. (issue #9637)
diff --git a/src/userfunc.c b/src/userfunc.c
index 097d4f1..d930951 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -1902,7 +1902,7 @@
char_u buffer[200];
scriptitem_T *si;
- if (vim_strchr(name, AUTOLOAD_CHAR) != 0)
+ if (vim_strchr(name, AUTOLOAD_CHAR) != NULL)
return NULL; // already has the prefix
if (!SCRIPT_ID_VALID(sid))
return NULL; // not in a script
@@ -2005,6 +2005,17 @@
}
/*
+ * Return TRUE if "ufunc" must be called with a g: prefix in Vim9 script.
+ */
+ int
+func_requires_g_prefix(ufunc_T *ufunc)
+{
+ return ufunc->uf_name[0] != K_SPECIAL
+ && (ufunc->uf_flags & FC_LAMBDA) == 0
+ && vim_strchr(ufunc->uf_name, AUTOLOAD_CHAR) == NULL;
+}
+
+/*
* Copy the function name of "fp" to buffer "buf".
* "buf" must be able to hold the function name plus three bytes.
* Takes care of script-local function names.
@@ -3442,7 +3453,14 @@
* User defined function.
*/
if (fp == NULL)
+ {
fp = find_func(rfname, is_global);
+ if (fp != NULL && !is_global && in_vim9script()
+ && func_requires_g_prefix(fp))
+ // In Vim9 script g: is required to find a global
+ // non-autoload function.
+ fp = NULL;
+ }
// Trigger FuncUndefined event, may load the function.
if (fp == NULL
@@ -3672,6 +3690,7 @@
char_u sid_buf[20];
int len;
int extra = 0;
+ int prefix_g = FALSE;
lval_T lv;
int vim9script;
@@ -3837,8 +3856,20 @@
// skip over "s:" and "g:"
if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':'))
{
- if (is_global != NULL && lv.ll_name[0] == 'g')
- *is_global = TRUE;
+ if (lv.ll_name[0] == 'g')
+ {
+ if (is_global != NULL)
+ {
+ *is_global = TRUE;
+ }
+ else
+ {
+ // dropping "g:" without setting "is_global" won't work in
+ // Vim9script, put it back later
+ prefix_g = TRUE;
+ extra = 2;
+ }
+ }
lv.ll_name += 2;
}
len = (int)(end - lv.ll_name);
@@ -3919,6 +3950,11 @@
if (vim9script || lead > 3) // If it's "<SID>"
STRCPY(name + 3, sid_buf);
}
+ else if (prefix_g)
+ {
+ name[0] = 'g';
+ name[1] = ':';
+ }
mch_memmove(name + lead + extra, lv.ll_name, (size_t)len);
name[lead + extra + len] = NUL;
}