Problem: Vim9: cannot call autoload function in :def function.
Solution: Load the autoload script. (closes #6690)
if (scriptname == NULL)
return NULL;
STRCPY(scriptname, "autoload/");
- STRCAT(scriptname, name);
+ STRCAT(scriptname, name[0] == 'g' && name[1] == ':' ? name + 2: name);
for (p = scriptname + 9; (p = vim_strchr(p, AUTOLOAD_CHAR)) != NULL;
q = p, ++p)
*p = '/';
"vim9script",
"let x = substitute ('x', 'x', 'x', 'x')"
], 'E121:')
+
+ let auto_lines =<< trim END
+ def g:some#func(): string
+ return 'found'
+ enddef
+ END
+ mkdir('Xruntime/autoload', 'p')
+ writefile(auto_lines, 'Xruntime/autoload/some.vim')
+ let save_rtp = &rtp
+ &rtp = getcwd() .. '/Xruntime,' .. &rtp
+ assert_equal('found', g:some#func())
+ assert_equal('found', some#func())
+
+ &rtp = save_rtp
+ delete('Xruntime', 'rf')
enddef
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1426,
/**/
1425,
/**/
int error = FCERR_NONE;
ufunc_T *ufunc;
int res = FAIL;
+ int is_autoload;
// we can evaluate "has('name')" at compile time
if (varlen == 3 && STRNCMP(*arg, "has", 3) == 0)
if (compile_arguments(arg, cctx, &argcount) == FAIL)
goto theend;
- if (ASCII_ISLOWER(*name) && name[1] != ':')
+ is_autoload = vim_strchr(name, '#') != NULL;
+ if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
{
int idx;
// If the name is a variable, load it and use PCALL.
// Not for g:Func(), we don't know if it is a variable or not.
+ // Not for eome#Func(), it will be loaded later.
p = namebuf;
- if (STRNCMP(namebuf, "g:", 2) != 0
+ if (STRNCMP(namebuf, "g:", 2) != 0 && !is_autoload
&& compile_load(&p, namebuf + varlen, cctx, FALSE) == OK)
{
garray_T *stack = &cctx->ctx_type_stack;
// A global function may be defined only later. Need to figure out at
// runtime. Also handles a FuncRef at runtime.
- if (STRNCMP(namebuf, "g:", 2) == 0)
+ if (STRNCMP(namebuf, "g:", 2) == 0 || is_autoload)
res = generate_UCALL(cctx, name, argcount);
else
semsg(_(e_unknownfunc), namebuf);
return OK;
}
+/*
+ * Return TRUE if an error was given or CTRL-C was pressed.
+ */
+ static int
+vim9_aborting(int prev_called_emsg)
+{
+ return called_emsg > prev_called_emsg || got_int || did_throw;
+}
+
/*
* Execute a function by "name".
* This can be a builtin function or a user function.
}
ufunc = find_func(name, FALSE, NULL);
+
+ if (ufunc == NULL)
+ {
+ int called_emsg_before = called_emsg;
+
+ if (script_autoload(name, TRUE))
+ // loaded a package, search for the function again
+ ufunc = find_func(name, FALSE, NULL);
+ if (vim9_aborting(called_emsg_before))
+ return FAIL; // bail out if loading the script caused an error
+ }
+
if (ufunc != NULL)
return call_ufunc(ufunc, argcount, ectx, iptr);