summaryrefslogtreecommitdiffstatshomepage
path: root/test/functional/lua
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2026-04-17 19:10:20 -0400
committerGitHub <noreply@github.com>2026-04-17 19:10:20 -0400
commit0d4d285bd2c19697164175280b32bf93e3a7b1da (patch)
tree0aa20f3e342279e9cba36e5c8daa0d38b2507c8d /test/functional/lua
parent03193e2963a6f9333afc3090ad2c8002b648fe11 (diff)
perf(vim.fn): call Lua-implemented vim.fn.xx() directly #39166
Problem: - Builtin "Vimscript" functions (f_xx) are mostly implemented in C. Partly that's because there is some boilerplate required to call out to Lua. - Calls to `vim.fn.foo()` always marshall over the Lua <=> Vimscript ("typval") bridge, even if `fn.foo()` is implemented entirely in Lua: ``` Lua => typval => Object => Lua => Object => typval => Lua. ``` Solution: Functions declared in eval.lua with `func_lua` are implemented in entirely in Lua (`_core/vimfn.lua`). - `gen_eval.lua` wires `func_lua` entries to `lua_wrapper`, which handles the typval conversion for Vimscript callers (slow path). - `nlua_call()` detects `func_lua` functions and calls the Lua implementation directly. This eliminates all conversion overhead for Lua callers (fast path). - Validate at build-time that `func`, `func_float`, and `func_lua` are mutually exclusive. - Migrate `hostname()` as a toy example, to show the idea.
Diffstat (limited to 'test/functional/lua')
-rw-r--r--test/functional/lua/vim_spec.lua29
1 files changed, 19 insertions, 10 deletions
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 2fde79a806..00ac46eb88 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -1391,6 +1391,15 @@ describe('lua stdlib', function()
)
end)
+ it('vim.fn `func_lua` (fast path for Lua-implemented builtins)', function()
+ -- hostname() is implemented via func_lua, calling Lua directly when invoked from Lua.
+ local lua_result = exec_lua([[return vim.fn.hostname()]])
+ eq(type(lua_result), 'string')
+ assert(#lua_result > 0, 'hostname() should return a non-empty string')
+ -- VimScript path (lua_wrapper) should return the same result.
+ eq(lua_result, eval('hostname()'))
+ end)
+
it('vim.call fails in fast context', function()
local screen = Screen.new(120, 10)
exec_lua([[
@@ -2003,14 +2012,14 @@ describe('lua stdlib', function()
local errmsg = api.nvim_get_vvar('errmsg')
matches(
- [[
-^vim%.on%_key%(%) callbacks:.*
-With ns%_id %d+: .*: Dumb Error
-stack traceback:
-.*: in function 'error'
-.*: in function 'ErrF2'
-.*: in function 'ErrF1'
-.*]],
+ t.dedent [[
+ ^vim%.on%_key%(%) callbacks:.*
+ With ns%_id %d+: .*: Dumb Error
+ stack traceback:
+ .*: in function 'error'
+ .*: in function 'ErrF2'
+ .*: in function 'ErrF1'
+ .*]],
errmsg
)
end)
@@ -3268,8 +3277,8 @@ describe('vim.keymap', function()
end)
end)
-describe('Vimscript function exists()', function()
- it('can check a lua function', function()
+describe('vim.fn.exists()', function()
+ it('can check a Lua function', function()
eq(
1,
exec_lua [[