From fe6bee5ca3811ca6703d8687ae9800691c982bda Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Tue, 19 May 2026 14:31:11 +0200 Subject: fix(nvim): smooth scroll cursor at boundaries --- plugin/50-smooth_scroll.lua | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'plugin') diff --git a/plugin/50-smooth_scroll.lua b/plugin/50-smooth_scroll.lua index 3c2ef05..6b31bf4 100644 --- a/plugin/50-smooth_scroll.lua +++ b/plugin/50-smooth_scroll.lua @@ -4,18 +4,25 @@ local Dir = { } local function smooth_scroll(dir) - local at_boundary + local scroll_at_boundary, cursor_at_boundary if dir == Dir.DOWN then - at_boundary = function() + scroll_at_boundary = function() return vim.fn.line("w$") == vim.api.nvim_buf_line_count(0) end + cursor_at_boundary = function() + return vim.fn.line(".") == vim.api.nvim_buf_line_count(0) + end else - at_boundary = function() + scroll_at_boundary = function() return vim.fn.line("w0") == 1 end + cursor_at_boundary = function() + return vim.fn.line(".") == 1 + end end - -- bail at boundaries: / would no-op but j/k would still walk the cursor - if at_boundary() then + -- bail only when the cursor itself can't move further; at the viewport + -- boundary / no-op but we still want j/k to walk the cursor + if cursor_at_boundary() then return end local win_height = vim.api.nvim_win_get_height(0) @@ -23,7 +30,8 @@ local function smooth_scroll(dir) 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 "\\j" or "\\k" + local scroll_keys = dir == Dir.DOWN and "\\j" or "\\k" + local cursor_keys = dir == Dir.DOWN and "j" or "k" local prev = 0 for i = 1, steps_number do local cur = math.ceil(step * i) @@ -31,9 +39,11 @@ local function smooth_scroll(dir) prev = cur vim.defer_fn(function() for _ = 1, delta do - if at_boundary() then + if cursor_at_boundary() then return end + -- past the viewport boundary / no-op; just walk the cursor + local keys = scroll_at_boundary() and cursor_keys or scroll_keys vim.cmd('exec "normal! ' .. keys .. '"') end end, sleep_duration * i) -- cgit v1.3.1