Regenerate nvim config
This commit is contained in:
98
config/neovim/store/lazy-plugins/promise-async/lua/async.lua
Normal file
98
config/neovim/store/lazy-plugins/promise-async/lua/async.lua
Normal file
@ -0,0 +1,98 @@
|
||||
local promise = require('promise')
|
||||
local utils = require('promise-async.utils')
|
||||
local compat = require('promise-async.compat')
|
||||
|
||||
local asyncId = {'promise-async'}
|
||||
|
||||
---@class Async
|
||||
local Async = setmetatable({_id = asyncId}, {
|
||||
__call = function(self, executor)
|
||||
return self.sync(executor)
|
||||
end
|
||||
})
|
||||
|
||||
local packedId = {}
|
||||
|
||||
local Packed = {_id = packedId}
|
||||
Packed.__index = Packed
|
||||
|
||||
local function wrapPacked(packed)
|
||||
return setmetatable(packed, Packed)
|
||||
end
|
||||
|
||||
local function hasPacked(o)
|
||||
return type(o) == 'table' and o._id == packedId
|
||||
end
|
||||
|
||||
local function injectENV(fn)
|
||||
compat.setfenv(fn, setmetatable({
|
||||
await = Async.wait,
|
||||
pcall = compat.pcall,
|
||||
xpcall = compat.xpcall
|
||||
}, {
|
||||
__index = compat.getfenv(fn)
|
||||
}))
|
||||
end
|
||||
|
||||
function Async.sync(executor)
|
||||
local typ = type(executor)
|
||||
local isCallable, fn = utils.getCallable(executor, typ)
|
||||
assert(isCallable, 'a callable table or function expected, got ' .. typ)
|
||||
injectENV(fn)
|
||||
return promise:new(function(resolve, reject)
|
||||
local co = coroutine.create(typ == 'function' and executor or function()
|
||||
return executor()
|
||||
end)
|
||||
|
||||
local function afterResume(status, ...)
|
||||
if not status then
|
||||
local reason = select(1, ...)
|
||||
reject(debug.traceback(co, reason))
|
||||
return
|
||||
elseif coroutine.status(co) == 'dead' then
|
||||
local value
|
||||
local n = select('#', ...)
|
||||
if n == 1 then
|
||||
value = select(1, ...)
|
||||
elseif n > 1 then
|
||||
value = wrapPacked({...})
|
||||
end
|
||||
resolve(value)
|
||||
return
|
||||
end
|
||||
local p = select(1, ...)
|
||||
return p
|
||||
end
|
||||
|
||||
local function next(err, res)
|
||||
local p = afterResume(coroutine.resume(co, err, res))
|
||||
if p then
|
||||
p:thenCall(function(value)
|
||||
next(false, value)
|
||||
end, function(reason)
|
||||
next(true, reason)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
next()
|
||||
end)
|
||||
end
|
||||
|
||||
---Export wait function to someone needs, wait function actually have injected as `await` into
|
||||
---the executor of async function
|
||||
---@param p Promise|any
|
||||
---@return ...
|
||||
function Async.wait(p)
|
||||
p = promise.resolve(p)
|
||||
local err, res = coroutine.yield(p)
|
||||
if err then
|
||||
error(res, 0)
|
||||
elseif hasPacked(res) then
|
||||
return compat.unpack(res)
|
||||
else
|
||||
return res
|
||||
end
|
||||
end
|
||||
|
||||
return Async
|
||||
Reference in New Issue
Block a user