summaryrefslogtreecommitdiffstats
path: root/plugin/50-smooth_scroll.lua
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-05-18 22:37:45 +0200
committerThomas Vanbesien <tvanbesi@proton.me>2026-05-18 22:37:45 +0200
commit0f0812fd82d2a511f994b93271e0348b44903035 (patch)
tree0ffba6a7e1d2d71faf9937d206f618cba84cf947 /plugin/50-smooth_scroll.lua
parent046cdfd0a047fcca41a7e3d8b4f89cb2e2f8a0e7 (diff)
downloadnvim-config-0f0812fd82d2a511f994b93271e0348b44903035.tar.gz
nvim-config-0f0812fd82d2a511f994b93271e0348b44903035.zip
fix(nvim): smooth scroll ignores lines in closed folds
Diffstat (limited to 'plugin/50-smooth_scroll.lua')
-rw-r--r--plugin/50-smooth_scroll.lua39
1 files changed, 26 insertions, 13 deletions
diff --git a/plugin/50-smooth_scroll.lua b/plugin/50-smooth_scroll.lua
index 84824a3..3c2ef05 100644
--- a/plugin/50-smooth_scroll.lua
+++ b/plugin/50-smooth_scroll.lua
@@ -4,24 +4,37 @@ local Dir = {
}
local function smooth_scroll(dir)
- local view, start_pos, buf_line_count, win_height =
- vim.fn.winsaveview(),
- vim.api.nvim_win_get_cursor(0),
- vim.api.nvim_buf_line_count(0),
- vim.api.nvim_win_get_height(0)
+ local at_boundary
+ if dir == Dir.DOWN then
+ at_boundary = function()
+ return vim.fn.line("w$") == vim.api.nvim_buf_line_count(0)
+ end
+ else
+ at_boundary = function()
+ return vim.fn.line("w0") == 1
+ end
+ end
+ -- bail at boundaries: <C-e>/<C-y> would no-op but j/k would still walk the cursor
+ if at_boundary() then
+ return
+ end
+ local win_height = vim.api.nvim_win_get_height(0)
local duration, sleep_duration = 100, 16 -- 60 fps
- local max_distance = dir == Dir.DOWN and buf_line_count - start_pos[1] or start_pos[1] - 1
- local distance = math.min(max_distance, math.floor(win_height / 2))
+ local distance = math.floor(win_height / 2)
local steps_number = math.ceil(duration / sleep_duration) -- We want a movement every `sleep_duration` msec
local step = distance / steps_number
+ local keys = dir == Dir.DOWN and "\\<C-e>j" or "\\<C-y>k"
+ local prev = 0
for i = 1, steps_number do
+ local cur = math.ceil(step * i)
+ local delta = cur - prev
+ prev = cur
vim.defer_fn(function()
- local offset = math.ceil(step * i) * (dir == Dir.DOWN and 1 or -1)
- local new_pos = { start_pos[1] + offset, start_pos[2] }
- vim.api.nvim_win_set_cursor(0, new_pos)
- local new_topline = math.max(1, view.topline + offset)
- if buf_line_count - new_topline >= win_height then -- don't move viewport beyond eof (DOWN) or first line (UP)
- vim.fn.winrestview({ lnum = view.lnum + offset, topline = new_topline }) -- move viewport
+ for _ = 1, delta do
+ if at_boundary() then
+ return
+ end
+ vim.cmd('exec "normal! ' .. keys .. '"')
end
end, sleep_duration * i)
end