diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-18 22:37:45 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-18 22:37:45 +0200 |
| commit | ed19cb3f071953b2f08ebe0e7cf94c64e4a636cc (patch) | |
| tree | 54e430c9c52b08046c53e6273b45b1d2951656a4 | |
| parent | 5dc232d76732b6b7ba33b77054f6505e702fa505 (diff) | |
| download | dotfiles-ed19cb3f071953b2f08ebe0e7cf94c64e4a636cc.tar.gz dotfiles-ed19cb3f071953b2f08ebe0e7cf94c64e4a636cc.zip | |
fix(nvim): smooth scroll ignores lines in closed folds
| -rw-r--r-- | .config/nvim/plugin/50-smooth_scroll.lua | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/.config/nvim/plugin/50-smooth_scroll.lua b/.config/nvim/plugin/50-smooth_scroll.lua index 84824a3..3c2ef05 100644 --- a/.config/nvim/plugin/50-smooth_scroll.lua +++ b/.config/nvim/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 |
