mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #18306 from lewis6991/fnfast
feat(lua): allow some viml functions to run in fast
This commit is contained in:
commit
30915cc8b0
@ -1038,6 +1038,8 @@ vim.fn.{func}({...}) *vim.fn*
|
||||
Note: vim.fn keys are generated lazily, thus `pairs(vim.fn)` only
|
||||
enumerates functions that were called at least once.
|
||||
|
||||
Note: The majority of functions cannot run in |api-fast| callbacks with some
|
||||
undocumented exceptions which are allowed.
|
||||
|
||||
*lua-vim-variables*
|
||||
The Vim editor global dictionaries |g:| |w:| |b:| |t:| |v:| can be accessed
|
||||
|
@ -10,6 +10,7 @@
|
||||
-- Defaults to BASE_NONE (function cannot be used as a method).
|
||||
-- func Name of the C function which implements the VimL function. Defaults to
|
||||
-- `f_{funcname}`.
|
||||
-- fast Function can run in |api-fast| events. Defaults to false.
|
||||
|
||||
local varargs = function(nr)
|
||||
return {nr}
|
||||
@ -205,7 +206,7 @@ return {
|
||||
hlID={args=1, base=1},
|
||||
hlexists={args=1, base=1},
|
||||
hostname={},
|
||||
iconv={args=3, base=1},
|
||||
iconv={args=3, base=1, fast=true},
|
||||
indent={args=1, base=1},
|
||||
index={args={2, 4}, base=1},
|
||||
input={args={1, 3}, base=1},
|
||||
|
@ -19,6 +19,7 @@ typedef struct {
|
||||
uint8_t min_argc; ///< Minimal number of arguments.
|
||||
uint8_t max_argc; ///< Maximal number of arguments.
|
||||
uint8_t base_arg; ///< Method base arg # (1-indexed), BASE_NONE or BASE_LAST.
|
||||
bool fast; ///< Can be run in |api-fast| events
|
||||
VimLFunc func; ///< Function implementation.
|
||||
FunPtr data; ///< Userdata for function implementation.
|
||||
} EvalFuncDef;
|
||||
|
@ -61,10 +61,11 @@ for _, name in ipairs(neworder) do
|
||||
local base = def.base or "BASE_NONE"
|
||||
local func = def.func or ('f_' .. name)
|
||||
local data = def.data or "NULL"
|
||||
hashpipe:write((' { "%s", %s, %s, %s, &%s, (FunPtr)%s },\n')
|
||||
:format(name, args[1], args[2], base, func, data))
|
||||
local fast = def.fast and 'true' or 'false'
|
||||
hashpipe:write((' { "%s", %s, %s, %s, %s, &%s, (FunPtr)%s },\n')
|
||||
:format(name, args[1], args[2], base, fast, func, data))
|
||||
end
|
||||
hashpipe:write(' { NULL, 0, 0, BASE_NONE, NULL, NULL },\n')
|
||||
hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, NULL },\n')
|
||||
hashpipe:write("};\n\n")
|
||||
hashpipe:write(hashfun)
|
||||
hashpipe:close()
|
||||
|
@ -914,12 +914,22 @@ int nlua_in_fast_event(lua_State *lstate)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool viml_func_is_fast(const char *name)
|
||||
{
|
||||
const EvalFuncDef *const fdef = find_internal_func((const char *)name);
|
||||
if (fdef) {
|
||||
return fdef->fast;
|
||||
}
|
||||
// Not a vimL function
|
||||
return false;
|
||||
}
|
||||
|
||||
int nlua_call(lua_State *lstate)
|
||||
{
|
||||
Error err = ERROR_INIT;
|
||||
size_t name_len;
|
||||
const char *name = luaL_checklstring(lstate, 1, &name_len);
|
||||
if (!nlua_is_deferred_safe()) {
|
||||
if (!nlua_is_deferred_safe() && !viml_func_is_fast(name)) {
|
||||
return luaL_error(lstate, e_luv_api_disabled, "vimL function");
|
||||
}
|
||||
|
||||
|
@ -794,6 +794,20 @@ describe('lua stdlib', function()
|
||||
pcall_err(exec_lua, "vim.fn.nvim_get_current_line()"))
|
||||
end)
|
||||
|
||||
it('vim.fn is allowed in "fast" context by some functions #18306', function()
|
||||
exec_lua([[
|
||||
local timer = vim.loop.new_timer()
|
||||
timer:start(0, 0, function()
|
||||
timer:close()
|
||||
assert(vim.in_fast_event())
|
||||
vim.g.fnres = vim.fn.iconv('hello', 'utf-8', 'utf-8')
|
||||
end)
|
||||
]])
|
||||
|
||||
helpers.poke_eventloop()
|
||||
eq('hello', exec_lua[[return vim.g.fnres]])
|
||||
end)
|
||||
|
||||
it('vim.rpcrequest and vim.rpcnotify', function()
|
||||
exec_lua([[
|
||||
chan = vim.fn.jobstart({'cat'}, {rpc=true})
|
||||
|
Loading…
Reference in New Issue
Block a user