fix: fix lua invoke c function use main event loop

This commit is contained in:
JuanZoran 2023-03-15 22:12:44 +08:00
parent 53f1998261
commit 3981167d38
8 changed files with 76 additions and 70 deletions

View File

@ -34,7 +34,6 @@ function M.query(data)
data.result.offline = res and M.formatter(res) or false
return data
end
-- this is a awesome plugin

View File

@ -4,6 +4,7 @@ local Trans = require('Trans')
---@class TransBackend
---@field query fun(data: TransData)---@async
---@field no_wait? boolean whether need to wait for the result
---@field all_name string[] @all backend name
---@field name string @backend name
@ -22,7 +23,9 @@ end
---@class Trans
---@field backend table<string, TransBackend>
return setmetatable({}, {
return setmetatable({
all_name = vim.tbl_keys(result),
}, {
__index = function(self, name)
---@type TransBackend
local backend = require('Trans.backend.' .. name)

View File

@ -1,4 +1,5 @@
local api, fn = vim.api, vim.fn
local Trans = require('Trans')
---@class TransBuffer
---@field bufnr integer buffer handle
@ -7,19 +8,22 @@ local buffer = {}
-- INFO : corountine can't invoke C function
---Clear all content in buffer
-- function buffer:wipe()
-- print('begin')
-- api.nvim_buf_set_lines(self.bufnr, 0, -1, false, {})
-- print('end')
-- end
function buffer:wipe()
Trans.util.main_loop(function()
api.nvim_buf_set_lines(self.bufnr, 0, -1, false, {})
end)
end
---Delete buffer [_start, _end] line content [one index]
---@param _start? integer start line index
---@param _end? integer end line index
function buffer:del(_start, _end)
---@diagnostic disable-next-line: cast-local-type
_start = _start or '$'
fn.deletebufline(self.bufnr, _start, _end)
function buffer:deleteline(_start, _end)
Trans.util.main_loop(function()
---@diagnostic disable-next-line: cast-local-type
_start = _start and _start - 1 or self:line_count() - 1
_end = _end and _end - 1 or _start + 1
api.nvim_buf_set_lines(self.bufnr, _start, _end, false, {})
end)
end
---Set buffer option
@ -113,37 +117,36 @@ end
---@param nodes string|table|table[] string -> as line content | table -> as a node | table[] -> as node[]
---@param one_index number? line number should be set[one index] or let it be nil to append
function buffer:setline(nodes, one_index)
self:set('modifiable', true)
one_index = one_index or self:line_count() + 1
if one_index == 2 and self[1] == '' then one_index = 1 end
if type(nodes) == 'string' then
fn.setbufline(self.bufnr, one_index, nodes)
else
-- FIXME :set [nodes] type as node
if type(nodes[1]) == 'string' then
---@diagnostic disable-next-line: assign-type-mismatch, param-type-mismatch
fn.setbufline(self.bufnr, one_index, nodes[1])
nodes:render(self, one_index, 0)
else
local strs = {}
local num = #nodes
for i = 1, num do
strs[i] = nodes[i][1]
end
fn.setbufline(self.bufnr, one_index, table.concat(strs))
local col = 0
for i = 1, num do
local node = nodes[i]
node:render(self, one_index, col)
col = col + #node[1]
end
end
return
end
self:set('modifiable', false)
-- FIXME :set [nodes] type as node
if type(nodes[1]) == 'string' then
---@diagnostic disable-next-line: assign-type-mismatch, param-type-mismatch
fn.setbufline(self.bufnr, one_index, nodes[1])
nodes:render(self, one_index, 0)
return
end
local strs = {}
local num = #nodes
for i = 1, num do
strs[i] = nodes[i][1]
end
fn.setbufline(self.bufnr, one_index, table.concat(strs))
local col = 0
for i = 1, num do
local node = nodes[i]
node:render(self, one_index, col)
col = col + #node[1]
end
end
buffer.__index = function(self, key)
@ -171,7 +174,6 @@ end
---@param bufnr? integer buffer handle
function buffer:init(bufnr)
self.bufnr = bufnr or api.nvim_create_buf(false, false)
self:set('modifiable', false)
self:set('filetype', 'Trans')
self:set('buftype', 'nofile')
end

View File

@ -9,10 +9,10 @@ return {
'visual',
'input',
},
backends = {
'offline',
'baidu',
},
-- backends = {
-- 'offline',
-- 'baidu',
-- },
frontends = {
'hover',
}

View File

@ -3,7 +3,7 @@ local Trans = require('Trans')
local function set_strategy_opts(conf)
local define = Trans.define
local all_modes = define.modes
local all_backends = define.backends
local all_backends = Trans.backend.all_name
local function parse_backend(backend)
if type(backend) == 'string' then

View File

@ -17,16 +17,14 @@ end
local strategy = {
fallback = function(data, update)
local result = data.result
for _, backend in ipairs(data.backends) do
---@cast backend TransBackend
local name = backend.name
backend.query(data)
if not backend.no_wait then
while result[name] == nil do
update()
end
while result[name] == nil do
update()
end
if type(result[name]) == 'table' then
@ -55,13 +53,19 @@ local function process(opts)
end
local data = Trans.data.new(opts)
local frontend = data.frontend
Trans.backend.offline.query(data)
local result = data.result['offline']
if not result then
result = strategy[Trans.conf.query](data, data.frontend:wait())
if not result then
-- data.frontend:fallback()
return
end
end
local result = strategy[Trans.conf.query](data, frontend:wait())
if not result then return end
Trans.cache[data.str] = data
frontend:process(data, result)
data.frontend:process(data, result)
end

View File

@ -115,6 +115,17 @@ function M.display_size(lines, width)
return { height = ds_height, width = ds_width }
end
---Execute function in main loop
---@param func function function to be executed
function M.main_loop(func)
local co = coroutine.running()
vim.defer_fn(function()
func()
coroutine.resume(co)
end, 0)
coroutine.yield()
end
---@class Trans
---@field util TransUtil
return M

View File

@ -26,6 +26,7 @@ function M.new()
}
M.queue[#M.queue + 1] = new_instance
new_instance.buffer:deleteline(1)
return setmetatable(new_instance, M)
end
@ -120,7 +121,6 @@ function M:wait()
end
-- -- FIXME :
-- -- buffer:wipe()
-- -- vim.api.nvim_buf_set_lines(buffer.bufnr, 1, -1, true, {})
-- -- print('jklajsdk')
-- -- print(vim.fn.deletebufline(buffer.bufnr, 1))
@ -132,16 +132,17 @@ end
---@param result TransResult
---@overload fun(result:TransResult)
function M:process(data, result)
local buffer = self.buffer
print(vim.fn.deletebufline(buffer.bufnr, 1))
-- buffer[1] = ''
-- local node = Trans.util.node
-- local it, t, f = node.item, node.text, node.format
-- self.buffer:setline(it('hello', 'MoreMsg'))
if self.pin then return end
local opts = self.opts
if self.pin then return end
local buffer = self.buffer
if not buffer:is_valid() then buffer:init() end
buffer:deleteline(1)
if opts.auto_play then
(data.from == 'en' and data.str or result.definition[1]):play()
@ -170,6 +171,7 @@ function M:process(data, result)
end
window:set('wrap', true)
buffer:set('modifiable', false)
local auto_close_events = opts.auto_close_events
@ -182,21 +184,6 @@ function M:process(data, result)
end,
})
end
-- vim.api.nvim_create_autocmd('User', {
-- pattern = 'TransHoverReady',
-- callback = function(opts)
-- vim.print(opts)
-- ---@type TransHover
-- local hover = opts.data
-- end,
-- desc = 'Auto Close Hover Window',
-- })
-- vim.api.nvim_exec_autocmds('User', {
-- pattern = 'TransHoverReady',
-- data = self,
-- })
end
---Check if hover window and buffer are valid