diff options
| author | bfredl <bjorn.linse@gmail.com> | 2025-09-09 20:53:31 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-09 20:53:31 +0200 |
| commit | b95aedeae4e57f3900410678f47e6ddd69a5357d (patch) | |
| tree | 758725fc1f91ff683ac68f67bce6b23ab4c17180 /src/nvim/lua | |
| parent | d15936f6ef9b6d225b92d93369efaf2b1bb37474 (diff) | |
| parent | 5119c03be7a9d440ae1ab027c3879d2ad7e71bba (diff) | |
| download | rneovim-b95aedeae4e57f3900410678f47e6ddd69a5357d.tar.gz rneovim-b95aedeae4e57f3900410678f47e6ddd69a5357d.tar.bz2 rneovim-b95aedeae4e57f3900410678f47e6ddd69a5357d.zip | |
Merge pull request #35536 from bfredl/skipahead
perf(highlight): allow decoration providers to skip ranges without data
fixes #35644
Diffstat (limited to 'src/nvim/lua')
| -rw-r--r-- | src/nvim/lua/executor.c | 42 | ||||
| -rw-r--r-- | src/nvim/lua/executor.h | 5 |
2 files changed, 33 insertions, 14 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index e3b7abde46..1cedc73e92 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -181,12 +181,9 @@ int nlua_pcall(lua_State *lstate, int nargs, int nresults) lua_remove(lstate, -2); } else { if (nresults == LUA_MULTRET) { - int new_top = lua_gettop(lstate); - int actual_nres = new_top - pre_top + nargs + 1; - lua_remove(lstate, -1 - actual_nres); - } else { - lua_remove(lstate, -1 - nresults); + nresults = lua_gettop(lstate) - (pre_top - nargs - 1); } + lua_remove(lstate, -1 - nresults); } return status; } @@ -1551,6 +1548,7 @@ Object nlua_exec(const String str, const char *chunkname, const Array args, LuaR { lua_State *const lstate = global_lstate; + int top = lua_gettop(lstate); const char *name = (chunkname && chunkname[0]) ? chunkname : "<nvim>"; if (luaL_loadbuffer(lstate, str.data, str.size, name)) { size_t len; @@ -1570,7 +1568,7 @@ Object nlua_exec(const String str, const char *chunkname, const Array args, LuaR return NIL; } - return nlua_call_pop_retval(lstate, mode, arena, err); + return nlua_call_pop_retval(lstate, mode, arena, top, err); } bool nlua_ref_is_function(LuaRef ref) @@ -1601,10 +1599,16 @@ Object nlua_call_ref(LuaRef ref, const char *name, Array args, LuaRetMode mode, return nlua_call_ref_ctx(false, ref, name, args, mode, arena, err); } +static int mode_ret(LuaRetMode mode) +{ + return mode == kRetMulti ? LUA_MULTRET : 1; +} + Object nlua_call_ref_ctx(bool fast, LuaRef ref, const char *name, Array args, LuaRetMode mode, Arena *arena, Error *err) { lua_State *const lstate = global_lstate; + int top = lua_gettop(lstate); nlua_pushref(lstate, ref); int nargs = (int)args.size; if (name != NULL) { @@ -1616,12 +1620,12 @@ Object nlua_call_ref_ctx(bool fast, LuaRef ref, const char *name, Array args, Lu } if (fast) { - if (nlua_fast_cfpcall(lstate, nargs, 1, -1) < 0) { + if (nlua_fast_cfpcall(lstate, nargs, mode_ret(mode), -1) < 0) { // error is already scheduled, set anyways to convey failure. api_set_error(err, kErrorTypeException, "fast context failure"); return NIL; } - } else if (nlua_pcall(lstate, nargs, 1)) { + } else if (nlua_pcall(lstate, nargs, mode_ret(mode))) { // if err is passed, the caller will deal with the error. if (err) { size_t len; @@ -1633,16 +1637,18 @@ Object nlua_call_ref_ctx(bool fast, LuaRef ref, const char *name, Array args, Lu return NIL; } - return nlua_call_pop_retval(lstate, mode, arena, err); + return nlua_call_pop_retval(lstate, mode, arena, top, err); } -static Object nlua_call_pop_retval(lua_State *lstate, LuaRetMode mode, Arena *arena, Error *err) +static Object nlua_call_pop_retval(lua_State *lstate, LuaRetMode mode, Arena *arena, int pretop, + Error *err) { - if (lua_isnil(lstate, -1)) { + if (mode != kRetMulti && lua_isnil(lstate, -1)) { lua_pop(lstate, 1); return NIL; } Error dummy = ERROR_INIT; + Error *perr = err ? err : &dummy; switch (mode) { case kRetNilBool: { @@ -1658,7 +1664,19 @@ static Object nlua_call_pop_retval(lua_State *lstate, LuaRetMode mode, Arena *ar return LUAREF_OBJ(ref); } case kRetObject: - return nlua_pop_Object(lstate, false, arena, err ? err : &dummy); + return nlua_pop_Object(lstate, false, arena, perr); + case kRetMulti: + ; + int nres = lua_gettop(lstate) - pretop; + Array res = arena_array(arena, (size_t)nres); + for (int i = 0; i < nres; i++) { + res.items[nres - i - 1] = nlua_pop_Object(lstate, false, arena, perr); + if (ERROR_SET(err)) { + return NIL; + } + } + res.size = (size_t)nres; + return ARRAY_OBJ(res); } UNREACHABLE; } diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index 9493015d10..c73b704a22 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -38,10 +38,11 @@ typedef struct { } while (0) typedef enum { - kRetObject, ///< any object, but doesn't preserve nested luarefs + kRetObject, ///< any object, but doesn't preserve nested luarefs kRetNilBool, ///< NIL preserved as such, other values return their booleanness ///< Should also be used when return value is ignored, as it is allocation-free - kRetLuaref, ///< return value becomes a single Luaref, regardless of type (except NIL) + kRetLuaref, ///< return value becomes a single Luaref, regardless of type (except NIL) + kRetMulti, ///< like kRetObject but return muliple return values as an Array } LuaRetMode; /// Maximum number of errors in vim.ui_attach() and decor provider callbacks. |