mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 12:45:17 -07:00
feat(options): allow setting function values to vim.o/go/bo
Problem: Assigning function values to options is tedious. Solution: Allow setting function values to options directly.
This commit is contained in:
parent
d27bbebf8e
commit
6fb4d0050a
@ -746,8 +746,11 @@ formatexpr({opts}) *vim.lsp.formatexpr()*
|
|||||||
|
|
||||||
Currently only supports a single client. This can be set via
|
Currently only supports a single client. This can be set via
|
||||||
`setlocal formatexpr=v:lua.vim.lsp.formatexpr()` or (more typically) in
|
`setlocal formatexpr=v:lua.vim.lsp.formatexpr()` or (more typically) in
|
||||||
`on_attach` via
|
`on_attach` via: >lua
|
||||||
`vim.bo[bufnr].formatexpr = 'v:lua.vim.lsp.formatexpr(#{timeout_ms:250})'`.
|
vim.bo[bufnr].formatexpr = function()
|
||||||
|
return vim.lsp.formatexpr({ timeout_ms = 250 })
|
||||||
|
end
|
||||||
|
<
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {opts} (`table?`) A table with the following fields:
|
• {opts} (`table?`) A table with the following fields:
|
||||||
|
@ -1293,6 +1293,14 @@ window-scoped options. Note that this must NOT be confused with
|
|||||||
|local-options| and |:setlocal|. There is also |vim.go| that only accesses the
|
|local-options| and |:setlocal|. There is also |vim.go| that only accesses the
|
||||||
global value of a |global-local| option, see |:setglobal|.
|
global value of a |global-local| option, see |:setglobal|.
|
||||||
|
|
||||||
|
Unlike |nvim_set_option_value()|, |vim.o|, |vim.go|, |vim.bo|
|
||||||
|
and |vim.wo| can be assigned function values.
|
||||||
|
|
||||||
|
Example: >lua
|
||||||
|
vim.bo.tagfunc = vim.lsp.tagfunc
|
||||||
|
vim.wo[1000].foldexpr = vim.treesitter.foldexpr
|
||||||
|
<
|
||||||
|
|
||||||
|
|
||||||
*vim.opt_local*
|
*vim.opt_local*
|
||||||
*vim.opt_global*
|
*vim.opt_global*
|
||||||
|
@ -134,6 +134,145 @@ local function get_options_info(name)
|
|||||||
return info
|
return info
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local func_opts = {
|
||||||
|
-- Options that can be set as a function
|
||||||
|
func = {
|
||||||
|
completefunc = true,
|
||||||
|
findfunc = true,
|
||||||
|
omnifunc = true,
|
||||||
|
operatorfunc = true,
|
||||||
|
quickfixtextfunc = true,
|
||||||
|
tagfunc = true,
|
||||||
|
thesaurusfunc = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Options that can be set as an expression
|
||||||
|
expr = {
|
||||||
|
diffexpr = true,
|
||||||
|
foldexpr = true,
|
||||||
|
formatexpr = true,
|
||||||
|
includeexpr = true,
|
||||||
|
indentexpr = true,
|
||||||
|
modelineexpr = true,
|
||||||
|
patchexpr = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Options that can be set as an expression with a prefix of '%!'
|
||||||
|
pct_bang_expr = {
|
||||||
|
statuscolumn = true,
|
||||||
|
statusline = true,
|
||||||
|
tabline = true,
|
||||||
|
winbar = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Options that can be set as an ex command if prefixed with ':'
|
||||||
|
ex_cmd_expr = {
|
||||||
|
keywordprg = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @param v integer?
|
||||||
|
--- @return integer
|
||||||
|
local function resolve_win(v)
|
||||||
|
return assert((not v or v == 0) and api.nvim_get_current_win() or v)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @type table<string,boolean>
|
||||||
|
local all_func_opts = {}
|
||||||
|
for _, v in pairs(func_opts) do
|
||||||
|
for k in pairs(v) do
|
||||||
|
all_func_opts[k] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @type table<string,function?>
|
||||||
|
vim._func_opts = setmetatable({}, { __mode = 'v' })
|
||||||
|
|
||||||
|
--- If the option name is a function option convert it to a string
|
||||||
|
--- format and store the function value.
|
||||||
|
--- @param name string
|
||||||
|
--- @param value any
|
||||||
|
--- @param info vim.api.keyset.get_option_info
|
||||||
|
--- @param opts vim.api.keyset.option
|
||||||
|
local function apply_func_opt(name, value, info, opts)
|
||||||
|
local idxs --- @type any[]
|
||||||
|
|
||||||
|
-- Find a table keep a references to the function value for an option.
|
||||||
|
-- We store a strong reference to the function in vim.g/b/w so it can be correctly garbage
|
||||||
|
-- collected when the buffer/window is closed. However because `v:lua` does not support
|
||||||
|
-- indexing with [], we need to store a weak reference to the function in another table under a
|
||||||
|
-- single string key.
|
||||||
|
if info.scope == 'global' or info.global_local and opts.scope == 'global' then
|
||||||
|
idxs = { 'g', '_func_opts' }
|
||||||
|
elseif info.scope == 'buf' then
|
||||||
|
idxs = { 'b', vim._resolve_bufnr(opts.buf), '_func_opts' }
|
||||||
|
else
|
||||||
|
assert(info.scope == 'win')
|
||||||
|
idxs = { 'w', resolve_win(opts.win), '_func_opts' }
|
||||||
|
if opts.scope == 'local' then
|
||||||
|
idxs[#idxs + 1] = vim._resolve_bufnr(opts.buf)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local fvalue = type(value) == 'function' and value or nil
|
||||||
|
|
||||||
|
-- If we have a function value, ensure the table for the strong references exists
|
||||||
|
if fvalue then
|
||||||
|
local t = vim --- @type table<string,any>
|
||||||
|
for _, k in ipairs(idxs) do
|
||||||
|
t[k] = t[k] or {}
|
||||||
|
t = t[k]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @type table<string,function?>
|
||||||
|
local t = vim.tbl_get(vim, unpack(idxs))
|
||||||
|
if t then
|
||||||
|
-- Note fvalue as nil is used to GC
|
||||||
|
t[name] = fvalue
|
||||||
|
end
|
||||||
|
|
||||||
|
if not fvalue then
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
local vlua_key_parts = {} --- @type string[]
|
||||||
|
for _, k in ipairs(idxs) do
|
||||||
|
vlua_key_parts[#vlua_key_parts + 1] = k ~= '_func_opts' and k or nil
|
||||||
|
end
|
||||||
|
vlua_key_parts[#vlua_key_parts + 1] = name
|
||||||
|
|
||||||
|
local vlua_key = table.concat(vlua_key_parts, '_')
|
||||||
|
|
||||||
|
vim._func_opts[vlua_key] = fvalue
|
||||||
|
|
||||||
|
local expr_pfx = (
|
||||||
|
func_opts.pct_bang_expr[name] and '%!'
|
||||||
|
or func_opts.ex_cmd_expr[name] and ':call '
|
||||||
|
or ''
|
||||||
|
)
|
||||||
|
|
||||||
|
local call_sfx = func_opts.func[name] and '' or '()'
|
||||||
|
|
||||||
|
return ('%sv:lua.vim._func_opts.%s%s'):format(expr_pfx, vlua_key, call_sfx)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param name string
|
||||||
|
--- @param value any
|
||||||
|
--- @param opts vim.api.keyset.option
|
||||||
|
local function set_option_value(name, value, opts)
|
||||||
|
local info = api.nvim_get_option_info2(name, {})
|
||||||
|
|
||||||
|
-- Resolve name if it is a short name
|
||||||
|
name = info.name
|
||||||
|
|
||||||
|
if all_func_opts[name] then
|
||||||
|
value = apply_func_opt(name, value, info, opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
api.nvim_set_option_value(name, value, opts)
|
||||||
|
end
|
||||||
|
|
||||||
--- Environment variables defined in the editor session.
|
--- Environment variables defined in the editor session.
|
||||||
--- See |expand-env| and |:let-environment| for the Vimscript behavior.
|
--- See |expand-env| and |:let-environment| for the Vimscript behavior.
|
||||||
--- Invalid or unset key returns `nil`.
|
--- Invalid or unset key returns `nil`.
|
||||||
@ -158,6 +297,7 @@ vim.env = setmetatable({}, {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
--- @param bufnr? integer
|
||||||
local function new_buf_opt_accessor(bufnr)
|
local function new_buf_opt_accessor(bufnr)
|
||||||
return setmetatable({}, {
|
return setmetatable({}, {
|
||||||
__index = function(_, k)
|
__index = function(_, k)
|
||||||
@ -167,8 +307,10 @@ local function new_buf_opt_accessor(bufnr)
|
|||||||
return api.nvim_get_option_value(k, { buf = bufnr or 0 })
|
return api.nvim_get_option_value(k, { buf = bufnr or 0 })
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
--- @param k string
|
||||||
|
--- @param v any
|
||||||
__newindex = function(_, k, v)
|
__newindex = function(_, k, v)
|
||||||
return api.nvim_set_option_value(k, v, { buf = bufnr or 0 })
|
return set_option_value(k, v, { buf = bufnr or 0 })
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -196,7 +338,7 @@ local function new_win_opt_accessor(winid, bufnr)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
__newindex = function(_, k, v)
|
__newindex = function(_, k, v)
|
||||||
return api.nvim_set_option_value(k, v, {
|
return set_option_value(k, v, {
|
||||||
scope = bufnr and 'local' or nil,
|
scope = bufnr and 'local' or nil,
|
||||||
win = winid or 0,
|
win = winid or 0,
|
||||||
})
|
})
|
||||||
@ -227,6 +369,14 @@ end
|
|||||||
--- window-scoped options. Note that this must NOT be confused with
|
--- window-scoped options. Note that this must NOT be confused with
|
||||||
--- |local-options| and |:setlocal|. There is also |vim.go| that only accesses the
|
--- |local-options| and |:setlocal|. There is also |vim.go| that only accesses the
|
||||||
--- global value of a |global-local| option, see |:setglobal|.
|
--- global value of a |global-local| option, see |:setglobal|.
|
||||||
|
---
|
||||||
|
--- Unlike |nvim_set_option_value()|, |vim.o|, |vim.go|, |vim.bo|
|
||||||
|
--- and |vim.wo| can be assigned function values.
|
||||||
|
---
|
||||||
|
--- Example: >lua
|
||||||
|
--- vim.bo.tagfunc = vim.lsp.tagfunc
|
||||||
|
--- vim.wo[1000].foldexpr = vim.treesitter.foldexpr
|
||||||
|
--- <
|
||||||
--- </pre>
|
--- </pre>
|
||||||
|
|
||||||
--- Get or set |options|. Like `:set`. Invalid key is an error.
|
--- Get or set |options|. Like `:set`. Invalid key is an error.
|
||||||
@ -245,8 +395,10 @@ vim.o = setmetatable({}, {
|
|||||||
__index = function(_, k)
|
__index = function(_, k)
|
||||||
return api.nvim_get_option_value(k, {})
|
return api.nvim_get_option_value(k, {})
|
||||||
end,
|
end,
|
||||||
|
--- @param k string
|
||||||
|
--- @param v any
|
||||||
__newindex = function(_, k, v)
|
__newindex = function(_, k, v)
|
||||||
return api.nvim_set_option_value(k, v, {})
|
return set_option_value(k, v, {})
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -268,8 +420,10 @@ vim.go = setmetatable({}, {
|
|||||||
__index = function(_, k)
|
__index = function(_, k)
|
||||||
return api.nvim_get_option_value(k, { scope = 'global' })
|
return api.nvim_get_option_value(k, { scope = 'global' })
|
||||||
end,
|
end,
|
||||||
|
--- @param k string
|
||||||
|
--- @param v any
|
||||||
__newindex = function(_, k, v)
|
__newindex = function(_, k, v)
|
||||||
return api.nvim_set_option_value(k, v, { scope = 'global' })
|
return set_option_value(k, v, { scope = 'global' })
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1066,8 +1066,13 @@ end
|
|||||||
---
|
---
|
||||||
--- Currently only supports a single client. This can be set via
|
--- Currently only supports a single client. This can be set via
|
||||||
--- `setlocal formatexpr=v:lua.vim.lsp.formatexpr()` or (more typically) in `on_attach`
|
--- `setlocal formatexpr=v:lua.vim.lsp.formatexpr()` or (more typically) in `on_attach`
|
||||||
--- via `vim.bo[bufnr].formatexpr = 'v:lua.vim.lsp.formatexpr(#{timeout_ms:250})'`.
|
--- via:
|
||||||
---
|
---
|
||||||
|
--- ```lua
|
||||||
|
--- vim.bo[bufnr].formatexpr = function()
|
||||||
|
--- return vim.lsp.formatexpr({ timeout_ms = 250 })
|
||||||
|
--- end
|
||||||
|
--- ```
|
||||||
---@param opts? vim.lsp.formatexpr.Opts
|
---@param opts? vim.lsp.formatexpr.Opts
|
||||||
function lsp.formatexpr(opts)
|
function lsp.formatexpr(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
@ -149,7 +149,7 @@ describe('lua stdlib', function()
|
|||||||
vim.api.nvim_buf_set_var(0, 'nullvar', vim.NIL)
|
vim.api.nvim_buf_set_var(0, 'nullvar', vim.NIL)
|
||||||
vim.api.nvim_buf_set_var(0, 'to_delete', { hello = 'world' })
|
vim.api.nvim_buf_set_var(0, 'to_delete', { hello = 'world' })
|
||||||
_G.BUF = vim.api.nvim_create_buf(false, true)
|
_G.BUF = vim.api.nvim_create_buf(false, true)
|
||||||
vim.api.nvim_buf_set_var(BUF, 'testing', 'bye')
|
vim.api.nvim_buf_set_var(_G.BUF, 'testing', 'bye')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
eq('hi', fn.luaeval 'vim.b.testing')
|
eq('hi', fn.luaeval 'vim.b.testing')
|
||||||
@ -164,7 +164,10 @@ describe('lua stdlib', function()
|
|||||||
return { vim.b.nonexistent == vim.NIL, vim.b.nullvar == vim.NIL }
|
return { vim.b.nonexistent == vim.NIL, vim.b.nullvar == vim.NIL }
|
||||||
end)
|
end)
|
||||||
|
|
||||||
matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.b[BUF][0].testing'))
|
matches(
|
||||||
|
[[attempt to index .* nil value]],
|
||||||
|
pcall_err(exec_lua, 'return vim.b[BUF][0].testing')
|
||||||
|
)
|
||||||
|
|
||||||
eq({ hello = 'world' }, fn.luaeval 'vim.b.to_delete')
|
eq({ hello = 'world' }, fn.luaeval 'vim.b.to_delete')
|
||||||
exec_lua [[
|
exec_lua [[
|
||||||
@ -174,12 +177,18 @@ describe('lua stdlib', function()
|
|||||||
|
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
local counter = 0
|
local counter = 0
|
||||||
local function add_counter() counter = counter + 1 end
|
local function add_counter()
|
||||||
local function get_counter() return counter end
|
counter = counter + 1
|
||||||
|
end
|
||||||
|
local function get_counter()
|
||||||
|
return counter
|
||||||
|
end
|
||||||
vim.b.AddCounter = add_counter
|
vim.b.AddCounter = add_counter
|
||||||
vim.b.GetCounter = get_counter
|
vim.b.GetCounter = get_counter
|
||||||
vim.b.fn = {add = add_counter, get = get_counter}
|
vim.b.fn = { add = add_counter, get = get_counter }
|
||||||
vim.b.AddParens = function(s) return '(' .. s .. ')' end
|
vim.b.AddParens = function(s)
|
||||||
|
return '(' .. s .. ')'
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
eq(0, eval('b:GetCounter()'))
|
eq(0, eval('b:GetCounter()'))
|
||||||
@ -199,12 +208,18 @@ describe('lua stdlib', function()
|
|||||||
|
|
||||||
exec_lua(function()
|
exec_lua(function()
|
||||||
local counter = 0
|
local counter = 0
|
||||||
local function add_counter() counter = counter + 1 end
|
local function add_counter()
|
||||||
local function get_counter() return counter end
|
counter = counter + 1
|
||||||
|
end
|
||||||
|
local function get_counter()
|
||||||
|
return counter
|
||||||
|
end
|
||||||
vim.api.nvim_buf_set_var(0, 'AddCounter', add_counter)
|
vim.api.nvim_buf_set_var(0, 'AddCounter', add_counter)
|
||||||
vim.api.nvim_buf_set_var(0, 'GetCounter', get_counter)
|
vim.api.nvim_buf_set_var(0, 'GetCounter', get_counter)
|
||||||
vim.api.nvim_buf_set_var(0, 'fn', {add = add_counter, get = get_counter})
|
vim.api.nvim_buf_set_var(0, 'fn', { add = add_counter, get = get_counter })
|
||||||
vim.api.nvim_buf_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
|
vim.api.nvim_buf_set_var(0, 'AddParens', function(s)
|
||||||
|
return '(' .. s .. ')'
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
eq(0, eval('b:GetCounter()'))
|
eq(0, eval('b:GetCounter()'))
|
||||||
@ -261,7 +276,10 @@ describe('lua stdlib', function()
|
|||||||
eq(NIL, fn.luaeval 'vim.w.nonexistent')
|
eq(NIL, fn.luaeval 'vim.w.nonexistent')
|
||||||
eq(NIL, fn.luaeval 'vim.w[WIN].nonexistent')
|
eq(NIL, fn.luaeval 'vim.w[WIN].nonexistent')
|
||||||
|
|
||||||
matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.w[WIN][0].testing'))
|
matches(
|
||||||
|
[[attempt to index .* nil value]],
|
||||||
|
pcall_err(exec_lua, 'return vim.w[WIN][0].testing')
|
||||||
|
)
|
||||||
|
|
||||||
eq({ hello = 'world' }, fn.luaeval 'vim.w.to_delete')
|
eq({ hello = 'world' }, fn.luaeval 'vim.w.to_delete')
|
||||||
exec_lua [[
|
exec_lua [[
|
||||||
@ -456,7 +474,10 @@ describe('lua stdlib', function()
|
|||||||
eq({ 'one', 'two' }, eval('v:oldfiles'))
|
eq({ 'one', 'two' }, eval('v:oldfiles'))
|
||||||
exec_lua([[vim.v.oldfiles = {}]])
|
exec_lua([[vim.v.oldfiles = {}]])
|
||||||
eq({}, eval('v:oldfiles'))
|
eq({}, eval('v:oldfiles'))
|
||||||
eq('Setting v:oldfiles to value with wrong type', pcall_err(exec_lua, [[vim.v.oldfiles = 'a']]))
|
eq(
|
||||||
|
'Setting v:oldfiles to value with wrong type',
|
||||||
|
pcall_err(exec_lua, [[vim.v.oldfiles = 'a']])
|
||||||
|
)
|
||||||
eq({}, eval('v:oldfiles'))
|
eq({}, eval('v:oldfiles'))
|
||||||
|
|
||||||
feed('i foo foo foo<Esc>0/foo<CR>')
|
feed('i foo foo foo<Esc>0/foo<CR>')
|
||||||
@ -528,6 +549,13 @@ describe('lua stdlib', function()
|
|||||||
matches('Expected Lua string$', pcall_err(exec_lua, 'return vim.bo[0][0].autoread'))
|
matches('Expected Lua string$', pcall_err(exec_lua, 'return vim.bo[0][0].autoread'))
|
||||||
matches('Invalid buffer id: %-1$', pcall_err(exec_lua, 'return vim.bo[-1].filetype'))
|
matches('Invalid buffer id: %-1$', pcall_err(exec_lua, 'return vim.bo[-1].filetype'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('can set function values', function()
|
||||||
|
eq_exec_lua('v:lua.vim._func_opts.b_1_tagfunc', function()
|
||||||
|
vim.bo.tagfunc = function() end
|
||||||
|
return vim.bo.tagfunc
|
||||||
|
end)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('vim.wo', function()
|
describe('vim.wo', function()
|
||||||
@ -567,7 +595,26 @@ describe('lua stdlib', function()
|
|||||||
|
|
||||||
it('errors', function()
|
it('errors', function()
|
||||||
matches('only bufnr=0 is supported', pcall_err(exec_lua, 'vim.wo[0][10].signcolumn = "no"'))
|
matches('only bufnr=0 is supported', pcall_err(exec_lua, 'vim.wo[0][10].signcolumn = "no"'))
|
||||||
matches('only bufnr=0 is supported', pcall_err(exec_lua, 'local a = vim.wo[0][10].signcolumn'))
|
matches(
|
||||||
|
'only bufnr=0 is supported',
|
||||||
|
pcall_err(exec_lua, 'local a = vim.wo[0][10].signcolumn')
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('can set function values', function()
|
||||||
|
eq_exec_lua({ '%!v:lua.vim._func_opts.w_1000_statusline()', 'HELLO' }, function()
|
||||||
|
vim.wo.statusline = function()
|
||||||
|
return 'HELLO'
|
||||||
|
end
|
||||||
|
return { vim.wo.statusline, vim.api.nvim_eval_statusline(vim.wo.statusline, {}).str }
|
||||||
|
end)
|
||||||
|
|
||||||
|
eq_exec_lua('v:lua.vim._func_opts.w_1000_1_foldexpr()', function()
|
||||||
|
vim.wo[0][0].foldexpr = function()
|
||||||
|
return 'HELLO'
|
||||||
|
end
|
||||||
|
return vim.wo[0].foldexpr
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -1073,7 +1120,10 @@ describe('lua stdlib', function()
|
|||||||
)
|
)
|
||||||
matches(
|
matches(
|
||||||
"Invalid option type 'function' for 'listchars'",
|
"Invalid option type 'function' for 'listchars'",
|
||||||
pcall_err(exec_lua, [[vim.opt.listchars = function() return "eol:~,space:.,tab:>~" end]])
|
pcall_err(
|
||||||
|
exec_lua,
|
||||||
|
[[vim.opt.listchars = function() return "eol:~,space:.,tab:>~" end]]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -1198,5 +1248,4 @@ describe('lua stdlib', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
@ -86,7 +86,7 @@ function M.handler(bytecode, upvalues, ...)
|
|||||||
set_upvalues(f, upvalues)
|
set_upvalues(f, upvalues)
|
||||||
|
|
||||||
-- Run in pcall so we can return any print messages
|
-- Run in pcall so we can return any print messages
|
||||||
local ret = { pcall(f, ...) } --- @type any[]
|
local ret = { xpcall(f, debug.traceback, ...) } --- @type any[]
|
||||||
|
|
||||||
_G.print = orig_print
|
_G.print = orig_print
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user