mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
Merge eeb236de7e
into 9f15a18fa5
This commit is contained in:
commit
4b6087315f
@ -1867,7 +1867,9 @@ nvim_create_user_command({name}, {command}, {*opts})
|
||||
|nvim_buf_create_user_command()| instead).
|
||||
• "complete" |:command-complete| also accepts a Lua
|
||||
function which works like
|
||||
|:command-completion-customlist|.
|
||||
|:command-completion-customlist| if it returns a table,
|
||||
or like |:command-completion-custom| if it returns a
|
||||
string.
|
||||
• Other parameters:
|
||||
• desc: (string) Used for listing the command when a Lua
|
||||
function is used for {command}.
|
||||
|
4
runtime/lua/vim/_meta/api.lua
generated
4
runtime/lua/vim/_meta/api.lua
generated
@ -948,7 +948,9 @@ function vim.api.nvim_create_namespace(name) end
|
||||
--- `nvim_buf_create_user_command()` instead).
|
||||
--- • "complete" `:command-complete` also accepts a Lua
|
||||
--- function which works like
|
||||
--- `:command-completion-customlist`.
|
||||
--- `:command-completion-customlist` if it returns a table,
|
||||
--- or like `:command-completion-custom` if it returns a
|
||||
--- string.
|
||||
--- • Other parameters:
|
||||
--- • desc: (string) Used for listing the command when a Lua
|
||||
--- function is used for {command}.
|
||||
|
@ -885,7 +885,8 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin
|
||||
/// - Set boolean attributes such as |:command-bang| or |:command-bar| to true (but
|
||||
/// not |:command-buffer|, use |nvim_buf_create_user_command()| instead).
|
||||
/// - "complete" |:command-complete| also accepts a Lua function which works like
|
||||
/// |:command-completion-customlist|.
|
||||
/// |:command-completion-customlist| if it returns a table, or like
|
||||
/// |:command-completion-custom| if it returns a string.
|
||||
/// - Other parameters:
|
||||
/// - desc: (string) Used for listing the command when a Lua function is used for
|
||||
/// {command}.
|
||||
|
@ -2759,8 +2759,13 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM
|
||||
if (xp->xp_context == EXPAND_USER_LIST) {
|
||||
return ExpandUserList(xp, matches, numMatches);
|
||||
}
|
||||
char *expand_user_lua_string = NULL;
|
||||
if (xp->xp_context == EXPAND_USER_LUA) {
|
||||
return ExpandUserLua(xp, numMatches, matches);
|
||||
ret = ExpandUserLua(xp, numMatches, matches, &expand_user_lua_string);
|
||||
|
||||
if (ret != NOTDONE) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (xp->xp_context == EXPAND_PACKADD) {
|
||||
return ExpandPackAddDir(pat, numMatches, matches);
|
||||
@ -2808,6 +2813,8 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM
|
||||
ret = expand_argopt(pat, xp, ®match, matches, numMatches);
|
||||
} else if (xp->xp_context == EXPAND_USER_DEFINED) {
|
||||
ret = ExpandUserDefined(pat, xp, ®match, matches, numMatches);
|
||||
} else if (xp->xp_context == EXPAND_USER_LUA) {
|
||||
ret = ExpandUserLuaList(pat, xp, ®match, matches, numMatches, expand_user_lua_string);
|
||||
} else {
|
||||
ret = ExpandOther(pat, xp, ®match, matches, numMatches);
|
||||
}
|
||||
@ -2815,6 +2822,7 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM
|
||||
if (!fuzzy) {
|
||||
vim_regfree(regmatch.regprog);
|
||||
}
|
||||
xfree(expand_user_lua_string);
|
||||
xfree(tofree);
|
||||
|
||||
return ret;
|
||||
@ -3208,10 +3216,16 @@ static int ExpandUserList(expand_T *xp, char ***matches, int *numMatches)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int ExpandUserLua(expand_T *xp, int *num_file, char ***file)
|
||||
static int ExpandUserLua(expand_T *xp, int *num_file, char ***file, char **ret_string)
|
||||
{
|
||||
typval_T rettv;
|
||||
nlua_call_user_expand_func(xp, &rettv);
|
||||
|
||||
if (rettv.v_type == VAR_STRING) {
|
||||
*ret_string = rettv.vval.v_string;
|
||||
return NOTDONE;
|
||||
}
|
||||
|
||||
if (rettv.v_type != VAR_LIST) {
|
||||
tv_clear(&rettv);
|
||||
return FAIL;
|
||||
@ -3237,6 +3251,78 @@ static int ExpandUserLua(expand_T *xp, int *num_file, char ***file)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int ExpandUserLuaList(const char *const pat, expand_T *xp, regmatch_T *regmatch,
|
||||
char ***matches, int *numMatches, char *retstr)
|
||||
{
|
||||
const bool fuzzy = cmdline_fuzzy_complete(pat);
|
||||
*matches = NULL;
|
||||
*numMatches = 0;
|
||||
|
||||
if (retstr == NULL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
garray_T ga;
|
||||
if (!fuzzy) {
|
||||
ga_init(&ga, (int)sizeof(char *), 3);
|
||||
} else {
|
||||
ga_init(&ga, (int)sizeof(fuzmatch_str_T), 3);
|
||||
}
|
||||
|
||||
for (char *s = retstr, *e; *s != NUL; s = e) {
|
||||
e = vim_strchr(s, '\n');
|
||||
if (e == NULL) {
|
||||
e = s + strlen(s);
|
||||
}
|
||||
const char keep = *e;
|
||||
*e = NUL;
|
||||
|
||||
bool match;
|
||||
int score = 0;
|
||||
if (xp->xp_pattern[0] != NUL) {
|
||||
if (!fuzzy) {
|
||||
match = vim_regexec(regmatch, s, 0);
|
||||
} else {
|
||||
score = fuzzy_match_str(s, pat);
|
||||
match = (score != 0);
|
||||
}
|
||||
} else {
|
||||
match = true; // match everything
|
||||
}
|
||||
|
||||
*e = keep;
|
||||
|
||||
if (match) {
|
||||
if (!fuzzy) {
|
||||
GA_APPEND(char *, &ga, xmemdupz(s, (size_t)(e - s)));
|
||||
} else {
|
||||
GA_APPEND(fuzmatch_str_T, &ga, ((fuzmatch_str_T){
|
||||
.idx = ga.ga_len,
|
||||
.str = xmemdupz(s, (size_t)(e - s)),
|
||||
.score = score,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if (*e != NUL) {
|
||||
e++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ga.ga_len == 0) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (!fuzzy) {
|
||||
*matches = ga.ga_data;
|
||||
*numMatches = ga.ga_len;
|
||||
} else {
|
||||
fuzzymatches_to_strmatches(ga.ga_data, matches, ga.ga_len, false);
|
||||
*numMatches = ga.ga_len;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Expand `file` for all comma-separated directories in `path`.
|
||||
/// Adds matches to `ga`.
|
||||
/// If "dirs" is true only expand directory names.
|
||||
|
@ -675,6 +675,22 @@ describe('nvim_create_user_command', function()
|
||||
eq('Test bbb', fn.getcmdline())
|
||||
end)
|
||||
|
||||
it('can use a Lua complete function which returns string instead of a list', function()
|
||||
exec_lua [[
|
||||
vim.api.nvim_create_user_command('Test', '', {
|
||||
nargs = "*",
|
||||
complete = function(arg, cmdline, pos)
|
||||
return "aaa\nbbb\nccc"
|
||||
end,
|
||||
})
|
||||
]]
|
||||
|
||||
feed(':Test a<Tab>')
|
||||
eq('Test aaa', fn.getcmdline())
|
||||
feed('<C-U>Test b<Tab>')
|
||||
eq('Test bbb', fn.getcmdline())
|
||||
end)
|
||||
|
||||
it('does not allow invalid command names', function()
|
||||
eq(
|
||||
"Invalid command name (must start with uppercase): 'test'",
|
||||
|
Loading…
Reference in New Issue
Block a user