Skip to content

Commit

Permalink
feat: add optional debounce
Browse files Browse the repository at this point in the history
  • Loading branch information
willothy committed Jun 1, 2024
1 parent 724b3b6 commit 7689548
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
48 changes: 48 additions & 0 deletions lua/precognition/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,54 @@ function M.peek()
})
end

--- Enable automatic showing of hints when idle (CursorHold + optional delay)
function M.show_when_idle()
if visible then
return
end
visible = true

local defer = utils.debounce_trailing(display_marks, 2000)

-- clear the extmark entirely when leaving a buffer (hints should only show in current buffer)
vim.api.nvim_create_autocmd("BufLeave", {
group = au,
callback = on_buf_leave,
})

vim.api.nvim_create_autocmd("CursorMovedI", {
group = au,
callback = on_buf_edit,
})

-- clear the extmark when the cursor moves, or when insert mode is entered
--
vim.api.nvim_create_autocmd("CursorMoved", {
group = au,
callback = function(ev)
local buf = ev and ev.buf or vim.api.nvim_get_current_buf()
if extmark then
local ext = vim.api.nvim_buf_get_extmark_by_id(buf, ns, extmark, {
details = true,
})
if ext and ext[1] ~= vim.api.nvim_win_get_cursor(0)[1] - 1 then
vim.api.nvim_buf_del_extmark(0, ns, extmark)
extmark = nil
end
end
dirty = true
defer()
end,
})

vim.api.nvim_create_autocmd("InsertEnter", {
group = au,
callback = on_insert_enter,
})

defer()
end

--- Enable automatic showing of hints
function M.show()
if visible then
Expand Down
39 changes: 39 additions & 0 deletions lua/precognition/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,43 @@ function M.add_multibyte_padding(cur_line, extra_padding, line_len)
end
end

---Debounces calls to a function, and ensures it only runs once per delay
---even if called repeatedly.
---@param fn fun(...: any)
---@param delay integer
function M.debounce_trailing(fn, delay)
local running = false
local timer = assert(vim.uv.new_timer())

-- Ugly hack to ensure timer is closed when the function is garbage collected
-- unfortunate but necessary to avoid creating a new timer for each call.
--
-- In LuaJIT, only userdata can have finalizers. `newproxy` creates an opaque userdata
-- which we can attach a finalizer to and use as a "canary."
local proxy = newproxy(true)
getmetatable(proxy).__gc = function()
vim.print("GC")
if not timer:is_closing() then
timer:close()
end
end

return function(...)
local _ = proxy
if running then
return
end
running = true
local args = { ... }
timer:start(
delay,
0,
vim.schedule_wrap(function()
fn(unpack(args))
running = false
end)
)
end
end

return M

0 comments on commit 7689548

Please sign in to comment.