refactor(util): unify debounce helpers into Debouncer class
This commit is contained in:
+55
-37
@@ -295,49 +295,67 @@ function Util.is_list_or_nil(val, t)
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a debounced function that delays execution of `fn` until after `delay` milliseconds have
|
||||
--- elapsed since the last time it was invoked.
|
||||
---@param fn fun(...) Function to be debounced
|
||||
---@param delay integer Debounce delay in milliseconds
|
||||
---@return fun(...) function Debounced function
|
||||
function Util.debounce(fn, delay)
|
||||
---@type uv.uv_timer_t?
|
||||
local timer = nil
|
||||
local NIL_KEY = {}
|
||||
|
||||
return function(...)
|
||||
local args = vim.F.pack_len(...)
|
||||
if timer then
|
||||
timer:stop()
|
||||
timer = nil
|
||||
end
|
||||
---@class ow.Util.Debouncer
|
||||
---@field private _fn fun(id: any, ...)
|
||||
---@field private _delay integer
|
||||
---@field private _timers table<any, uv.uv_timer_t>
|
||||
local Debouncer = {}
|
||||
Debouncer.__index = Debouncer
|
||||
|
||||
timer = vim.defer_fn(function()
|
||||
timer = nil
|
||||
fn(vim.F.unpack_len(args))
|
||||
end, delay)
|
||||
---@param fn fun(id: any, ...)
|
||||
---@param delay integer
|
||||
---@return ow.Util.Debouncer
|
||||
function Debouncer.new(fn, delay)
|
||||
return setmetatable({ _fn = fn, _delay = delay, _timers = {} }, Debouncer)
|
||||
end
|
||||
|
||||
---@param id? any
|
||||
---@param ... any
|
||||
function Debouncer:call(id, ...)
|
||||
local key = id == nil and NIL_KEY or id
|
||||
local args = vim.F.pack_len(...)
|
||||
self:cancel(id)
|
||||
self._timers[key] = vim.defer_fn(function()
|
||||
self._timers[key] = nil
|
||||
self._fn(id, vim.F.unpack_len(args))
|
||||
end, self._delay)
|
||||
end
|
||||
|
||||
---@param timer uv.uv_timer_t
|
||||
local function dispose(timer)
|
||||
timer:stop()
|
||||
timer:close()
|
||||
end
|
||||
|
||||
---@param id? any
|
||||
function Debouncer:cancel(id)
|
||||
local key = id == nil and NIL_KEY or id
|
||||
local timer = self._timers[key]
|
||||
if timer then
|
||||
dispose(timer)
|
||||
self._timers[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a debounced function that delays execution of `fn` until after `delay` milliseconds have
|
||||
--- elapsed since the last time it was invoked with the same unique identifier.
|
||||
---@param fn fun(...) Function to be debounced
|
||||
---@param delay integer Debounce delay in milliseconds
|
||||
---@return fun(id: any, ...) function Debounced function, where `id` is a unique identifier
|
||||
function Util.debounce_with_id(fn, delay)
|
||||
local map = {}
|
||||
|
||||
return function(id, ...)
|
||||
local args = vim.F.pack_len(...)
|
||||
if map[id] then
|
||||
map[id]:stop()
|
||||
map[id] = nil
|
||||
end
|
||||
|
||||
map[id] = vim.defer_fn(function()
|
||||
map[id] = nil
|
||||
fn(vim.F.unpack_len(args))
|
||||
end, delay)
|
||||
function Debouncer:cancel_all()
|
||||
for _, t in pairs(self._timers) do
|
||||
dispose(t)
|
||||
end
|
||||
self._timers = {}
|
||||
end
|
||||
|
||||
Util.Debouncer = Debouncer
|
||||
|
||||
--- Creates a debounced function that delays execution of `fn` until after `delay` milliseconds have
|
||||
--- elapsed since the last time it was invoked. Use `d:call(id, ...)` to debounce per-id, or
|
||||
--- `d:call(...)` for a single shared slot.
|
||||
---@param fn fun(id: any, ...) Function to be debounced
|
||||
---@param delay integer Debounce delay in milliseconds
|
||||
---@return ow.Util.Debouncer
|
||||
function Util.debounce(fn, delay)
|
||||
return Debouncer.new(fn, delay)
|
||||
end
|
||||
|
||||
function Util.get_hl_source(name)
|
||||
|
||||
Reference in New Issue
Block a user