diff options
author | Michael Smith <mikesmiffy128@gmail.com> | 2022-05-22 22:47:23 +0100 |
---|---|---|
committer | Michael Smith <mikesmiffy128@gmail.com> | 2022-05-22 22:47:23 +0100 |
commit | 95aea6b533e71e478d61d18fac71cca116c56a4d (patch) | |
tree | 1a1f42f723772258cc54551495826768f374474a /start/cmp/lua/cmp/utils/async.lua |
Add all the plugins I currently use
Diffstat (limited to 'start/cmp/lua/cmp/utils/async.lua')
-rw-r--r-- | start/cmp/lua/cmp/utils/async.lua | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/start/cmp/lua/cmp/utils/async.lua b/start/cmp/lua/cmp/utils/async.lua new file mode 100644 index 0000000..13f126b --- /dev/null +++ b/start/cmp/lua/cmp/utils/async.lua @@ -0,0 +1,127 @@ +local async = {} + +---@class cmp.AsyncThrottle +---@field public running boolean +---@field public timeout number +---@field public sync function(self: cmp.AsyncThrottle, timeout: number|nil) +---@field public stop function +---@field public __call function + +---@param fn function +---@param timeout number +---@return cmp.AsyncThrottle +async.throttle = function(fn, timeout) + local time = nil + local timer = vim.loop.new_timer() + return setmetatable({ + running = false, + timeout = timeout, + sync = function(self, timeout_) + vim.wait(timeout_ or 1000, function() + return not self.running + end) + end, + stop = function() + time = nil + timer:stop() + end, + }, { + __call = function(self, ...) + local args = { ... } + + if time == nil then + time = vim.loop.now() + end + + self.running = true + timer:stop() + timer:start(math.max(1, self.timeout - (vim.loop.now() - time)), 0, function() + vim.schedule(function() + time = nil + fn(unpack(args)) + self.running = false + end) + end) + end, + }) +end + +---Control async tasks. +async.step = function(...) + local tasks = { ... } + local next + next = function(...) + if #tasks > 0 then + table.remove(tasks, 1)(next, ...) + end + end + table.remove(tasks, 1)(next) +end + +---Timeout callback function +---@param fn function +---@param timeout number +---@return function +async.timeout = function(fn, timeout) + local timer + local done = false + local callback = function(...) + if not done then + done = true + timer:stop() + timer:close() + fn(...) + end + end + timer = vim.loop.new_timer() + timer:start(timeout, 0, function() + callback() + end) + return callback +end + +---@alias cmp.AsyncDedup fun(callback: function): function + +---Create deduplicated callback +---@return function +async.dedup = function() + local id = 0 + return function(callback) + id = id + 1 + + local current = id + return function(...) + if current == id then + callback(...) + end + end + end +end + +---Convert async process as sync +async.sync = function(runner, timeout) + local done = false + runner(function() + done = true + end) + vim.wait(timeout, function() + return done + end, 10, false) +end + +---Wait and callback for next safe state. +async.debounce_next_tick = function(callback) + local running = false + return function() + if running then + return + end + running = true + vim.schedule(function() + running = false + callback() + end) + end +end + +return async |