aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-07-06 22:25:35 +0800
committerGitHub <noreply@github.com>2024-07-06 22:25:35 +0800
commitbdc6e38781321895331057cbcfb099f8ad31e6db (patch)
tree94df4cf7cae8e7b347f798e7435fc55845d66d03
parent34fa54355a50baefe443a00ec4b0d60188445b36 (diff)
downloadrneovim-bdc6e38781321895331057cbcfb099f8ad31e6db.tar.gz
rneovim-bdc6e38781321895331057cbcfb099f8ad31e6db.tar.bz2
rneovim-bdc6e38781321895331057cbcfb099f8ad31e6db.zip
fix(lua): don't include text after cursor in completion pattern (#29587)
-rw-r--r--src/nvim/cmdexpand.c7
-rw-r--r--src/nvim/insexpand.c2
-rw-r--r--src/nvim/lua/executor.c11
-rw-r--r--test/functional/editor/completion_spec.lua10
4 files changed, 22 insertions, 8 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
index db27e464a8..d98293f84b 100644
--- a/src/nvim/cmdexpand.c
+++ b/src/nvim/cmdexpand.c
@@ -241,7 +241,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
if (xp->xp_numfiles == -1) {
set_expand_context(xp);
if (xp->xp_context == EXPAND_LUA) {
- nlua_expand_pat(xp, xp->xp_pattern);
+ nlua_expand_pat(xp);
}
cmd_showtail = expand_showtail(xp);
}
@@ -1059,7 +1059,7 @@ int showmatches(expand_T *xp, bool wildmenu)
if (xp->xp_numfiles == -1) {
set_expand_context(xp);
if (xp->xp_context == EXPAND_LUA) {
- nlua_expand_pat(xp, xp->xp_pattern);
+ nlua_expand_pat(xp);
}
int i = expand_cmdline(xp, ccline->cmdbuff, ccline->cmdpos,
&numMatches, &matches);
@@ -3610,7 +3610,8 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
theend:
if (xpc.xp_context == EXPAND_LUA) {
- nlua_expand_pat(&xpc, xpc.xp_pattern);
+ xpc.xp_col = (int)strlen(xpc.xp_line);
+ nlua_expand_pat(&xpc);
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
}
char *pat;
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 2c9b2ca141..104e5f61b8 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -4146,7 +4146,7 @@ static int get_cmdline_compl_info(char *line, colnr_T curs_col)
compl_patternlen = (size_t)curs_col;
set_cmd_context(&compl_xp, compl_pattern, (int)compl_patternlen, curs_col, false);
if (compl_xp.xp_context == EXPAND_LUA) {
- nlua_expand_pat(&compl_xp, compl_xp.xp_pattern);
+ nlua_expand_pat(&compl_xp);
}
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
|| compl_xp.xp_context == EXPAND_NOTHING) {
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index bac6f4ca9a..c29e670c33 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -1928,7 +1928,7 @@ static garray_T expand_result_array = GA_EMPTY_INIT_VALUE;
/// Finds matches for Lua cmdline completion and advances xp->xp_pattern after prefix.
/// This should be called before xp->xp_pattern is first used.
-void nlua_expand_pat(expand_T *xp, const char *pat)
+void nlua_expand_pat(expand_T *xp)
{
lua_State *const lstate = global_lstate;
int status = FAIL;
@@ -1941,7 +1941,10 @@ void nlua_expand_pat(expand_T *xp, const char *pat)
luaL_checktype(lstate, -1, LUA_TFUNCTION);
// [ vim, vim._expand_pat, pat ]
- lua_pushstring(lstate, pat);
+ const char *pat = xp->xp_pattern;
+ assert(xp->xp_line + xp->xp_col >= pat);
+ ptrdiff_t patlen = xp->xp_line + xp->xp_col - pat;
+ lua_pushlstring(lstate, pat, (size_t)patlen);
if (nlua_pcall(lstate, 1, 2) != 0) {
nlua_error(lstate, _("Error executing vim._expand_pat: %.*s"));
@@ -1951,8 +1954,8 @@ void nlua_expand_pat(expand_T *xp, const char *pat)
Error err = ERROR_INIT;
Arena arena = ARENA_EMPTY;
- int prefix_len = (int)nlua_pop_Integer(lstate, &arena, &err);
- if (ERROR_SET(&err)) {
+ ptrdiff_t prefix_len = nlua_pop_Integer(lstate, &arena, &err);
+ if (ERROR_SET(&err) || prefix_len > patlen) {
goto cleanup;
}
diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua
index 405af5fcfd..9d5bda0acc 100644
--- a/test/functional/editor/completion_spec.lua
+++ b/test/functional/editor/completion_spec.lua
@@ -854,6 +854,16 @@ describe('completion', function()
]])
end)
+ it('works when cursor is in the middle of cmdline #29586', function()
+ feed(':lua math.a(); 1<Left><Left><Left><Left><Left><Tab>')
+ screen:expect([[
+ |
+ {1:~ }|*5
+ {100:abs}{3: acos asin atan atan2 }|
+ :lua math.abs^(); 1 |
+ ]])
+ end)
+
it('provides completion from `getcompletion()`', function()
eq({ 'vim' }, fn.getcompletion('vi', 'lua'))
eq({ 'api' }, fn.getcompletion('vim.ap', 'lua'))