mirror of
https://github.com/neovim/neovim.git
synced 2025-10-21 09:12:07 +00:00
libluv: use luv_set_callback to control callback execution
Disable the use of deferred API functions in a fast lua callback Correctly display error messages from a fast lua callback
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
-- Test suite for testing interactions with API bindings
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local funcs = helpers.funcs
|
||||
local meths = helpers.meths
|
||||
local clear = helpers.clear
|
||||
local sleep = helpers.sleep
|
||||
local feed = helpers.feed
|
||||
local eq = helpers.eq
|
||||
local eval = helpers.eval
|
||||
local matches = helpers.matches
|
||||
local exec_lua = helpers.exec_lua
|
||||
|
||||
before_each(clear)
|
||||
|
||||
@@ -17,7 +21,7 @@ describe('vim.loop', function()
|
||||
end)
|
||||
|
||||
it('timer', function()
|
||||
meths.execute_lua('vim.api.nvim_set_var("coroutine_cnt", 0)', {})
|
||||
exec_lua('vim.api.nvim_set_var("coroutine_cnt", 0)', {})
|
||||
|
||||
local code=[[
|
||||
local loop = vim.loop
|
||||
@@ -27,14 +31,14 @@ describe('vim.loop', function()
|
||||
local this = coroutine.running()
|
||||
assert(this)
|
||||
local timer = loop.new_timer()
|
||||
timer:start(ms, 0, function ()
|
||||
timer:start(ms, 0, vim.schedule_wrap(function ()
|
||||
timer:close()
|
||||
touch = touch + 1
|
||||
coroutine.resume(this)
|
||||
touch = touch + 1
|
||||
assert(touch==3)
|
||||
vim.api.nvim_set_var("coroutine_cnt_1", touch)
|
||||
end)
|
||||
end))
|
||||
coroutine.yield()
|
||||
touch = touch + 1
|
||||
return touch
|
||||
@@ -47,9 +51,95 @@ describe('vim.loop', function()
|
||||
]]
|
||||
|
||||
eq(0, meths.get_var('coroutine_cnt'))
|
||||
meths.execute_lua(code, {})
|
||||
sleep(20)
|
||||
exec_lua(code)
|
||||
sleep(50)
|
||||
eq(2, meths.get_var('coroutine_cnt'))
|
||||
eq(3, meths.get_var('coroutine_cnt_1'))
|
||||
end)
|
||||
|
||||
it('is API safe', function()
|
||||
local screen = Screen.new(50,10)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids({
|
||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||
[2] = {bold = true, reverse = true},
|
||||
[3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
|
||||
[4] = {bold = true, foreground = Screen.colors.SeaGreen4},
|
||||
[5] = {bold = true},
|
||||
})
|
||||
|
||||
-- deferred API functions are disabled, as their safety can't be guaranteed
|
||||
exec_lua([[
|
||||
local timer = vim.loop.new_timer()
|
||||
timer:start(20, 0, function ()
|
||||
timer:close()
|
||||
vim.api.nvim_set_var("valid", true)
|
||||
vim.api.nvim_command("echomsg 'howdy'")
|
||||
end)
|
||||
]])
|
||||
|
||||
screen:expect([[
|
||||
|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{2: }|
|
||||
{3:Error executing luv callback:} |
|
||||
{3:[string "<nvim>"]:4: E5560: nvim_set_var must not }|
|
||||
{3:be called in a lua loop callback} |
|
||||
{4:Press ENTER or type command to continue}^ |
|
||||
]])
|
||||
feed('<cr>')
|
||||
eq(false, eval("get(g:, 'valid', v:false)"))
|
||||
|
||||
-- callbacks can be scheduled to be executed in the main event loop
|
||||
-- where the entire API is available
|
||||
exec_lua([[
|
||||
local timer = vim.loop.new_timer()
|
||||
timer:start(20, 0, vim.schedule_wrap(function ()
|
||||
timer:close()
|
||||
vim.api.nvim_set_var("valid", true)
|
||||
vim.api.nvim_command("echomsg 'howdy'")
|
||||
end))
|
||||
]])
|
||||
|
||||
screen:expect([[
|
||||
^ |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
howdy |
|
||||
]])
|
||||
eq(true, eval("get(g:, 'valid', v:false)"))
|
||||
|
||||
-- fast (not deferred) API functions are allowed to be called directly
|
||||
exec_lua([[
|
||||
local timer = vim.loop.new_timer()
|
||||
timer:start(20, 0, function ()
|
||||
timer:close()
|
||||
-- input is queued for processing after the callback returns
|
||||
vim.api.nvim_input("isneaky")
|
||||
_G.mode = vim.api.nvim_get_mode()
|
||||
end)
|
||||
]])
|
||||
screen:expect([[
|
||||
sneaky^ |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
eq({blocking=false, mode='n'}, exec_lua("return _G.mode"))
|
||||
end)
|
||||
end)
|
||||
|
Reference in New Issue
Block a user