Skip to content

Commit

Permalink
fix(throttle): fixed throttling so that it now only gets scheduled wh…
Browse files Browse the repository at this point in the history
…en there are pending args
  • Loading branch information
folke committed May 30, 2024
1 parent 094135f commit 0db2084
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 44 deletions.
81 changes: 40 additions & 41 deletions lua/trouble/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,9 @@ function M.camel(str, sep)
)
end

---@alias ThrottleOpts {ms:number, debounce?:boolean, is_running?:fun():boolean}

---@param opts? {ms?: number, debounce?: boolean}|number
---@param default ThrottleOpts
---@return ThrottleOpts
---@param default Throttle.opts
---@return Throttle.opts
function M.throttle_opts(opts, default)
opts = opts or {}
if type(opts) == "number" then
Expand All @@ -90,72 +88,73 @@ function M.throttle_opts(opts, default)
return vim.tbl_deep_extend("force", default, opts)
end

---@alias Throttle.opts {ms:number, debounce?:boolean, is_running?:fun():boolean}

-- throttle with trailing execution
---@generic T: fun()
---@param fn T
---@param opts? ThrottleOpts
---@param opts? Throttle.opts
---@return T
function M.throttle(fn, opts)
opts = opts or {}
opts.ms = opts.ms or 20
local timer = assert(vim.loop.new_timer())
local check = assert(vim.loop.new_check())
local last = 0
local args = {} ---@type any[]
local executing = false
local trailing = false

local throttle = {}

check:start(function()
if not throttle.is_running() and not timer:is_active() and trailing then
trailing = false
throttle.schedule()
end
end)
local args = nil ---@type {n?:number}?
local timer = assert(vim.loop.new_timer())
local pending = false -- from run() till end of fn
local running = false -- from run() till end of fn with is_running()

function throttle.is_running()
return executing or (opts.is_running and opts.is_running())
end
local t = {}

function throttle.run()
executing = true
last = vim.loop.now()
function t.run()
pending = true
running = true
timer:stop()
last = vim.uv.now()
vim.schedule(function()
xpcall(function()
local _args = vim.F.unpack_len(args)
-- FIXME:
if not trailing and not timer:is_active() then
args = {} -- clear args so they can be gc'd
if not args then
return M.debug("Empty args. This should not happen.")
end
fn(_args)
fn(vim.F.unpack_len(args))
args = nil
end, function(err)
vim.schedule(function()
M.error(err)
end)
end)
executing = false
pending = false
t.check()
end)
end

function throttle.schedule()
local now = vim.loop.now()
local delay = opts.ms - (now - last)
if opts.debounce then
delay = opts.ms
function t.schedule()
local now = vim.uv.now()
local delay = opts.debounce and opts.ms or (opts.ms - (now - last))
timer:stop()
timer:start(math.max(0, delay), 0, t.run)
end

function t.check()
if running and not pending and not (opts.is_running and opts.is_running()) then
running = false
if args then -- schedule if there are pending args
t.schedule()
end
end
timer:start(math.max(0, delay), 0, throttle.run)
end

local check = assert(vim.uv.new_check())
check:start(t.check)

return function(...)
args = vim.F.pack_len(...)

if timer:is_active() and not opts.debounce then
return
elseif throttle.is_running() then
trailing = true
return
elseif not running then
t.schedule()
end
throttle.schedule()
end
end

Expand Down
13 changes: 11 additions & 2 deletions lua/trouble/view/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,14 @@ function M:on_mount()

local _self = Util.weak(self)

local preview =
Util.throttle(M.preview, Util.throttle_opts(self.opts.throttle.preview, { ms = 100, debounce = true }))
local preview = Util.throttle(
M.preview,
Util.throttle_opts(self.opts.throttle.preview, {
ms = 100,
debounce = true,
})
)

self.win:on("CursorMoved", function()
local this = _self()
if not this then
Expand Down Expand Up @@ -461,6 +467,9 @@ end

-- When not in the trouble window, try to show the range
function M:follow()
if not self.win:valid() then
return
end
local current_win = vim.api.nvim_get_current_win()
---@type number[]|nil
local cursor = nil
Expand Down
2 changes: 1 addition & 1 deletion lua/trouble/view/section.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ function M.new(section, opts)
end

function M:refresh()
self.fetching = true
if self.on_refresh then
self:on_refresh()
end
self.fetching = true
local done = false
local complete = function()
if done then
Expand Down

0 comments on commit 0db2084

Please sign in to comment.