diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-07-06 22:25:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-06 22:25:35 +0800 |
commit | bdc6e38781321895331057cbcfb099f8ad31e6db (patch) | |
tree | 94df4cf7cae8e7b347f798e7435fc55845d66d03 | |
parent | 34fa54355a50baefe443a00ec4b0d60188445b36 (diff) | |
download | rneovim-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.c | 7 | ||||
-rw-r--r-- | src/nvim/insexpand.c | 2 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 11 | ||||
-rw-r--r-- | test/functional/editor/completion_spec.lua | 10 |
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')) |