mirror of
https://github.com/folke/snacks.nvim
synced 2025-08-06 19:58:22 +00:00
feat(scroll): added spamming detection and disable animations when user is spamming keys :)
This commit is contained in:
parent
a986851a74
commit
c58605f8b3
1 changed files with 22 additions and 4 deletions
|
@ -25,6 +25,7 @@ local defaults = {
|
||||||
duration = { step = 15, total = 250 },
|
duration = { step = 15, total = 250 },
|
||||||
easing = "linear",
|
easing = "linear",
|
||||||
},
|
},
|
||||||
|
spamming = 10, -- threshold for spamming detection
|
||||||
-- what buffers to animate
|
-- what buffers to animate
|
||||||
filter = function(buf)
|
filter = function(buf)
|
||||||
return vim.g.snacks_scroll ~= false and vim.b[buf].snacks_scroll ~= false and vim.bo[buf].buftype ~= "terminal"
|
return vim.g.snacks_scroll ~= false and vim.b[buf].snacks_scroll ~= false and vim.bo[buf].buftype ~= "terminal"
|
||||||
|
@ -40,9 +41,12 @@ local mouse_scrolling = false
|
||||||
M.enabled = false
|
M.enabled = false
|
||||||
|
|
||||||
local states = {} ---@type table<number, snacks.scroll.State>
|
local states = {} ---@type table<number, snacks.scroll.State>
|
||||||
local stats = { targets = 0, animating = 0, reset = 0, skipped = 0, mousescroll = 0 }
|
local stats =
|
||||||
|
{ targets = 0, animating = 0, reset = 0, skipped = 0, mousescroll = 0, scrolls = 0, spamming_rate = 0, spamming = 0 }
|
||||||
local config = Snacks.config.get("scroll", defaults)
|
local config = Snacks.config.get("scroll", defaults)
|
||||||
local debug_timer = assert((vim.uv or vim.loop).new_timer())
|
local debug_timer = assert((vim.uv or vim.loop).new_timer())
|
||||||
|
local spamming = false
|
||||||
|
local spammer_timer = assert((vim.uv or vim.loop).new_timer())
|
||||||
|
|
||||||
-- get the state for a window.
|
-- get the state for a window.
|
||||||
-- when the state doesn't exist, its target is the current view
|
-- when the state doesn't exist, its target is the current view
|
||||||
|
@ -84,6 +88,14 @@ function M.enable()
|
||||||
get_state(win)
|
get_state(win)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local current, delta, ema, ms, alpha = 0, 0, 0, 100, 0.3
|
||||||
|
spammer_timer:start(ms, ms, function()
|
||||||
|
delta, current = stats.scrolls - current, stats.scrolls
|
||||||
|
ema = alpha * delta * 1000 / ms + (1 - alpha) * ema
|
||||||
|
spamming = ema > config.spamming
|
||||||
|
stats.spamming_rate = math.floor(ema)
|
||||||
|
end)
|
||||||
|
|
||||||
local group = vim.api.nvim_create_augroup("snacks_scroll", { clear = true })
|
local group = vim.api.nvim_create_augroup("snacks_scroll", { clear = true })
|
||||||
|
|
||||||
-- track mouse scrolling
|
-- track mouse scrolling
|
||||||
|
@ -193,17 +205,23 @@ function M.check(win)
|
||||||
stats.skipped = stats.skipped + 1
|
stats.skipped = stats.skipped + 1
|
||||||
state.current = vim.deepcopy(state.view)
|
state.current = vim.deepcopy(state.view)
|
||||||
return
|
return
|
||||||
elseif mouse_scrolling then
|
elseif mouse_scrolling or spamming then
|
||||||
if state.anim then
|
if state.anim then
|
||||||
state.anim:stop()
|
state.anim:stop()
|
||||||
state.anim = nil
|
state.anim = nil
|
||||||
virtualedit(state) -- restore virtualedit
|
virtualedit(state) -- restore virtualedit
|
||||||
end
|
end
|
||||||
mouse_scrolling = false
|
if mouse_scrolling then
|
||||||
stats.mousescroll = stats.mousescroll + 1
|
mouse_scrolling = false
|
||||||
|
stats.mousescroll = stats.mousescroll + 1
|
||||||
|
else -- spamming
|
||||||
|
stats.spamming = stats.spamming + 1
|
||||||
|
stats.scrolls = stats.scrolls + 1
|
||||||
|
end
|
||||||
state.current = vim.deepcopy(state.view)
|
state.current = vim.deepcopy(state.view)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
stats.scrolls = stats.scrolls + 1
|
||||||
|
|
||||||
-- new target
|
-- new target
|
||||||
stats.targets = stats.targets + 1
|
stats.targets = stats.targets + 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue