aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-02-18 19:11:44 +0800
committerGitHub <noreply@github.com>2024-02-18 19:11:44 +0800
commitb8c34efe3399b0786a0e00012cfa3a05a4aa4654 (patch)
tree5cf06572e1aa937f048faec77c63bc4e98837152
parent796df966f3cb83698035b85522504d40e7b5ab0b (diff)
downloadrneovim-b8c34efe3399b0786a0e00012cfa3a05a4aa4654.tar.gz
rneovim-b8c34efe3399b0786a0e00012cfa3a05a4aa4654.tar.bz2
rneovim-b8c34efe3399b0786a0e00012cfa3a05a4aa4654.zip
fix(eval): skip over v:lua properly (#27517)
Problem: Error when parsing v:lua in a ternary expression. Solution: Set rettv->v_type for v:lua even if not evaluating.
-rw-r--r--src/nvim/eval.c13
-rw-r--r--src/nvim/eval/funcs.c2
-rw-r--r--test/functional/lua/luaeval_spec.lua2
3 files changed, 15 insertions, 2 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 4734e46362..3d224bfa0f 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -3238,6 +3238,13 @@ static int eval7(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool wan
} else {
// skip the name
check_vars(s, (size_t)len);
+ // If evaluate is false rettv->v_type was not set, but it's needed
+ // in handle_subscript() to parse v:lua, so set it here.
+ if (rettv->v_type == VAR_UNKNOWN && !evaluate && strnequal(s, "v:lua.", 6)) {
+ rettv->v_type = VAR_PARTIAL;
+ rettv->vval.v_partial = vvlua_partial;
+ rettv->vval.v_partial->pt_refcount++;
+ }
ret = OK;
}
}
@@ -3442,7 +3449,7 @@ static int eval_method(char **const arg, typval_T *const rettv, evalarg_T *const
int len;
char *name = *arg;
char *lua_funcname = NULL;
- if (strncmp(name, "v:lua.", 6) == 0) {
+ if (strnequal(name, "v:lua.", 6)) {
lua_funcname = name + 6;
*arg = (char *)skip_luafunc_name(lua_funcname);
*arg = skipwhite(*arg); // to detect trailing whitespace later
@@ -7614,6 +7621,10 @@ int handle_subscript(const char **const arg, typval_T *rettv, evalarg_T *const e
const char *lua_funcname = NULL;
if (tv_is_luafunc(rettv)) {
+ if (!evaluate) {
+ tv_clear(rettv);
+ }
+
if (**arg != '.') {
tv_clear(rettv);
ret = FAIL;
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 28365e16df..8dbff8a7a6 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -1726,7 +1726,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
n = false; // Trailing garbage.
}
} else if (*p == '*') { // Internal or user defined function.
- n = strncmp(p, "*v:lua.", 7) == 0 ? nlua_func_exists(p + 7) : function_exists(p + 1, false);
+ n = strnequal(p, "*v:lua.", 7) ? nlua_func_exists(p + 7) : function_exists(p + 1, false);
} else if (*p == ':') {
n = cmd_exists(p + 1);
} else if (*p == '#') {
diff --git a/test/functional/lua/luaeval_spec.lua b/test/functional/lua/luaeval_spec.lua
index 171d37ba55..b28cfa4dd2 100644
--- a/test/functional/lua/luaeval_spec.lua
+++ b/test/functional/lua/luaeval_spec.lua
@@ -538,6 +538,8 @@ describe('v:lua', function()
eq('\tbadval', eval("v:lua.require'leftpad'('badval')"))
eq(9003, eval("v:lua.require'bar'.doit()"))
eq(9004, eval("v:lua.require'baz-quux'.doit()"))
+ eq(9003, eval("1 ? v:lua.require'bar'.doit() : v:lua.require'baz-quux'.doit()"))
+ eq(9004, eval("0 ? v:lua.require'bar'.doit() : v:lua.require'baz-quux'.doit()"))
end)
it('throw errors for invalid use', function()