perf(scroll): combine all scrolling commands in one command + restore vim.v.count

This commit is contained in:
Folke Lemaitre 2025-10-27 17:02:27 +01:00
parent 9eafe00070
commit 0fbea13c9d
No known key found for this signature in database
GPG key ID: 9B52594D560070AB
2 changed files with 16 additions and 14 deletions

View file

@ -74,9 +74,9 @@ Animation.__index = Animation
function Animation.new(opts)
local id = opts and opts.id or next_id()
if active[id] then -- reuse existing animation
if active[id] then
active[id]:stop()
return active[id]
active[id] = nil
end
local self = setmetatable({}, Animation)

View file

@ -27,7 +27,7 @@ State.__index = State
---@field animate_repeat snacks.animate.Config|{}|{delay:number}
local defaults = {
animate = {
duration = { step = 10, total = 150 },
duration = { step = 10, total = 200 },
easing = "linear",
},
-- faster animation when repeating scroll after delay
@ -344,30 +344,32 @@ function M.check(win)
end
local count = vim.v.count -- backup count
local commands = {} ---@type string[]
-- scroll
local scroll_target = math.floor(value)
local scroll = scroll_target - scrolled --[[@as number]]
if scroll > 0 then
scrolled = scrolled + scroll
vim.cmd(("keepjumps normal! %d%s"):format(scroll, down and SCROLL_DOWN or SCROLL_UP))
commands[#commands + 1] = ("%d%s"):format(scroll, down and SCROLL_DOWN or SCROLL_UP)
end
-- move the cursor vertically
local move = math.floor(value * math.abs(move_to - move_from) / scrolls) -- delta to move this step
local move_target = move_from + ((move_to < move_from) and -1 or 1) * move -- target line
vim.cmd(("keepjumps normal! %dH"):format(move_target))
-- fix count
if vim.v.count ~= count then
vim.cmd(("keepjumps normal! %dzh"):format(count))
end
commands[#commands + 1] = ("%dH"):format(move_target)
-- move the cursor horizontally
local lnum = vim.api.nvim_win_get_cursor(win)[1]
local virtcol = math.floor(col_from + (col_to - col_from) * value / scrolls + 0.5)
local col = virtcol == 0 and 0 or vim.fn.virtcol2col(state.win, lnum, virtcol)
vim.fn.winrestview({ col = col, coladd = math.max(virtcol - col, 0) })
local virtcol = math.floor(col_from + (col_to - col_from) * value / scrolls)
commands[#commands + 1] = ("%d|"):format(virtcol + 1)
-- execute all commands in one go
vim.cmd(("keepjumps normal! %s"):format(table.concat(commands, "")))
-- restore count (see #1024)
local cursor = vim.api.nvim_win_get_cursor(win)
vim.cmd(("keepjumps normal! %dzh"):format(count))
vim.api.nvim_win_set_cursor(win, cursor)
state:update()
end)