mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.4171: cannot invoke option function using autoload import
Problem: Cannot invoke option function using autoload import. Solution: Expand the import to an autoload function name. (closes #9578)
This commit is contained in:
@@ -3382,22 +3382,20 @@ set_var_const(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_vim9script() && SCRIPT_ID_VALID(current_sctx.sc_sid)
|
||||
&& SCRIPT_ITEM(current_sctx.sc_sid)->sn_autoload_prefix != NULL
|
||||
&& is_export)
|
||||
{
|
||||
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
|
||||
size_t len = STRLEN(name) + STRLEN(si->sn_autoload_prefix) + 1;
|
||||
scriptitem_T *si;
|
||||
|
||||
if (in_vim9script() && is_export
|
||||
&& SCRIPT_ID_VALID(current_sctx.sc_sid)
|
||||
&& (si = SCRIPT_ITEM(current_sctx.sc_sid))
|
||||
->sn_autoload_prefix != NULL)
|
||||
{
|
||||
// In a vim9 autoload script an exported variable is put in the
|
||||
// global namespace with the autoload prefix.
|
||||
var_in_autoload = TRUE;
|
||||
varname = alloc(len);
|
||||
varname = concat_str(si->sn_autoload_prefix, name);
|
||||
if (varname == NULL)
|
||||
goto failed;
|
||||
name_tofree = varname;
|
||||
vim_snprintf((char *)varname, len, "%s%s",
|
||||
si->sn_autoload_prefix, name);
|
||||
ht = &globvarht;
|
||||
}
|
||||
else
|
||||
@@ -4630,6 +4628,40 @@ copy_callback(callback_T *dest, callback_T *src)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When a callback refers to an autoload import, change the function name to
|
||||
* the "path#name" form. Uses the current script context.
|
||||
* Only works when the name is allocated.
|
||||
*/
|
||||
void
|
||||
expand_autload_callback(callback_T *cb)
|
||||
{
|
||||
char_u *p;
|
||||
imported_T *import;
|
||||
|
||||
if (!in_vim9script() || cb->cb_name == NULL || !cb->cb_free_name)
|
||||
return;
|
||||
p = vim_strchr(cb->cb_name, '.');
|
||||
if (p == NULL)
|
||||
return;
|
||||
import = find_imported(cb->cb_name, p - cb->cb_name, FALSE, NULL);
|
||||
if (import != NULL && SCRIPT_ID_VALID(import->imp_sid))
|
||||
{
|
||||
scriptitem_T *si = SCRIPT_ITEM(import->imp_sid);
|
||||
|
||||
if (si->sn_autoload_prefix != NULL)
|
||||
{
|
||||
char_u *name = concat_str(si->sn_autoload_prefix, p + 1);
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
vim_free(cb->cb_name);
|
||||
cb->cb_name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unref/free "callback" returned by get_callback() or set_callback().
|
||||
*/
|
||||
|
@@ -7238,6 +7238,11 @@ option_set_callback_func(char_u *optval UNUSED, callback_T *optcb UNUSED)
|
||||
free_callback(optcb);
|
||||
set_callback(optcb, &cb);
|
||||
free_tv(tv);
|
||||
|
||||
// when using Vim9 style "import.funcname" it needs to be expanded to
|
||||
// "import#funcname".
|
||||
expand_autload_callback(optcb);
|
||||
|
||||
return OK;
|
||||
#else
|
||||
return FAIL;
|
||||
|
@@ -103,5 +103,6 @@ callback_T get_callback(typval_T *arg);
|
||||
void put_callback(callback_T *cb, typval_T *tv);
|
||||
void set_callback(callback_T *dest, callback_T *src);
|
||||
void copy_callback(callback_T *dest, callback_T *src);
|
||||
void expand_autload_callback(callback_T *cb);
|
||||
void free_callback(callback_T *callback);
|
||||
/* vim: set ft=c : */
|
||||
|
@@ -609,7 +609,7 @@ def Test_use_import_in_mapping()
|
||||
nunmap <F3>
|
||||
enddef
|
||||
|
||||
def Test_use_import_in_completion()
|
||||
def Test_use_import_in_command_completion()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
export def Complete(..._): list<string>
|
||||
@@ -632,6 +632,47 @@ def Test_use_import_in_completion()
|
||||
delete('Xscript.vim')
|
||||
enddef
|
||||
|
||||
def Test_use_autoload_import_in_insert_completion()
|
||||
mkdir('Xdir/autoload', 'p')
|
||||
var save_rtp = &rtp
|
||||
exe 'set rtp^=' .. getcwd() .. '/Xdir'
|
||||
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
export def ThesaurusFunc(findbase: bool, _): any
|
||||
if findbase
|
||||
return 1
|
||||
endif
|
||||
return [
|
||||
'check',
|
||||
'experiment',
|
||||
'test',
|
||||
'verification'
|
||||
]
|
||||
enddef
|
||||
g:completion_loaded = 'yes'
|
||||
END
|
||||
writefile(lines, 'Xdir/autoload/completion.vim')
|
||||
|
||||
new
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
g:completion_loaded = 'no'
|
||||
import autoload 'completion.vim'
|
||||
set thesaurusfunc=completion.ThesaurusFunc
|
||||
assert_equal('no', g:completion_loaded)
|
||||
feedkeys("i\<C-X>\<C-T>\<C-N>\<Esc>", 'xt')
|
||||
assert_equal('experiment', getline(1))
|
||||
assert_equal('yes', g:completion_loaded)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
set thesaurusfunc=
|
||||
bwipe!
|
||||
delete('Xdir', 'rf')
|
||||
&rtp = save_rtp
|
||||
enddef
|
||||
|
||||
def Test_export_fails()
|
||||
CheckScriptFailure(['export var some = 123'], 'E1042:')
|
||||
CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
|
||||
|
@@ -3262,7 +3262,7 @@ call_callback_retnr(
|
||||
typval_T rettv;
|
||||
varnumber_T retval;
|
||||
|
||||
if (call_callback(callback, 0, &rettv, argcount, argvars) == FAIL)
|
||||
if (call_callback(callback, -1, &rettv, argcount, argvars) == FAIL)
|
||||
return -2;
|
||||
|
||||
retval = tv_get_number_chk(&rettv, NULL);
|
||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
4171,
|
||||
/**/
|
||||
4170,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user