mirror of
https://github.com/zoriya/telescope.nvim.git
synced 2026-08-16 02:45:09 +00:00
106 lines
2.0 KiB
Lua
106 lines
2.0 KiB
Lua
local co = coroutine
|
|
local uv = vim.loop
|
|
|
|
local LinkedList = require('telescope.algos.linked_list')
|
|
|
|
local modes = setmetatable({
|
|
init = "init",
|
|
next = "next",
|
|
done = "done",
|
|
}, { __index = function(_, k)
|
|
error(string.format("'%s' is not a valid mode", k))
|
|
end })
|
|
|
|
local is_dead = function(c)
|
|
return co.status(c) == "dead"
|
|
end
|
|
|
|
local Executor = {}
|
|
Executor.__index = Executor
|
|
|
|
-- TODO: I would like to make it so we just have one function for each task,
|
|
-- but I think it's fine for now to store both things.
|
|
function Executor:new(func)
|
|
return setmetatable({
|
|
func = func,
|
|
|
|
-- mode = modes.init,
|
|
-- tasks = LinkedList:new(),
|
|
|
|
-- Will be initialized at each run.
|
|
_idle = nil,
|
|
}, self)
|
|
end
|
|
|
|
function Executor:run()
|
|
if not self._idle then
|
|
self._idle = uv.new_idle()
|
|
-- self._idle = uv.new_check()
|
|
end
|
|
|
|
self._idle:start((function()
|
|
-- if self.tasks.size == 0 then
|
|
-- return self:stop()
|
|
-- end
|
|
self:step()
|
|
|
|
if true then return end
|
|
|
|
if self.mode == modes.init then
|
|
self:start()
|
|
end
|
|
|
|
if self.mode == modes.next then
|
|
self:step()
|
|
elseif self.mode == modes.done then
|
|
self:complete()
|
|
else
|
|
error(debug.traceback("Unknown mode: " .. tostring(self.mode)))
|
|
end
|
|
end))
|
|
end
|
|
|
|
function Executor:start()
|
|
self.mode = modes.next
|
|
end
|
|
|
|
function Executor:step()
|
|
co.resume(self.func)
|
|
if is_dead(self.func) then
|
|
print("DEAD")
|
|
-- self.tasks:shift()
|
|
return self:stop()
|
|
else
|
|
return self
|
|
end
|
|
|
|
if self.tasks.size == 0 then return end
|
|
|
|
local task = self.tasks.head.item
|
|
if task == nil then
|
|
error("Should not get step with no tasks left")
|
|
end
|
|
|
|
local task_co = task[1]
|
|
co.resume(task_co, unpack(task[2]))
|
|
if is_dead(task_co) then
|
|
print("DEAD")
|
|
self.tasks:shift()
|
|
end
|
|
end
|
|
|
|
function Executor:complete()
|
|
end
|
|
|
|
function Executor:stop()
|
|
if not self._idle then return end
|
|
|
|
self._idle:stop()
|
|
self._idle:close()
|
|
self._idle = nil
|
|
|
|
return self
|
|
end
|
|
|
|
return Executor
|