diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-07 13:25:59 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-05-07 13:25:59 +0200 |
| commit | e44a4cadb2a3fe17bea2d528704cfb35ade73938 (patch) | |
| tree | 5b9192e57b118efe1d08c54144ad9b7ac22265ee | |
| parent | bb86e587b284a144ebf92f35c1d393d5b546e3d3 (diff) | |
| download | dotfiles-e44a4cadb2a3fe17bea2d528704cfb35ade73938.tar.gz dotfiles-e44a4cadb2a3fe17bea2d528704cfb35ade73938.zip | |
feat(nvim): smooth scrolling plugin
| -rw-r--r-- | .config/nvim/init.lua | 3 | ||||
| -rw-r--r-- | .config/nvim/plugin/50-smooth_scroll.lua | 35 |
2 files changed, 38 insertions, 0 deletions
diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua index 0a116d5..8d62ed3 100644 --- a/.config/nvim/init.lua +++ b/.config/nvim/init.lua @@ -113,6 +113,9 @@ vim.keymap.set({ "n", "i", "t" }, "<M-n>", "<Cmd>tabnext<CR>", { desc = "Move to vim.keymap.set({ "n", "i", "t" }, "<M-b>", "<Cmd>tabprevious<CR>", { desc = "Move to previous tab page" }) vim.keymap.set("i", "<M-h>", "<Space><BS><Left>") vim.keymap.set("i", "<M-l>", "<Space><BS><Right>") +-- Scrolling +vim.keymap.set("n", "<C-u>", vim.cmd.ScrollSmoothUp, { desc = "Scroll up smoothly" }) +vim.keymap.set("n", "<C-d>", vim.cmd.ScrollSmoothDown, { desc = "Scroll down smoothly" }) -- Navigate in command/insert mode vim.keymap.set({ "c", "i" }, "<M-h>", "<Space><BS><Left>") vim.keymap.set({ "c", "i" }, "<M-l>", "<Space><BS><Right>") diff --git a/.config/nvim/plugin/50-smooth_scroll.lua b/.config/nvim/plugin/50-smooth_scroll.lua new file mode 100644 index 0000000..84824a3 --- /dev/null +++ b/.config/nvim/plugin/50-smooth_scroll.lua @@ -0,0 +1,35 @@ +local Dir = { + UP = 1, + DOWN = 2, +} + +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 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 steps_number = math.ceil(duration / sleep_duration) -- We want a movement every `sleep_duration` msec + local step = distance / steps_number + for i = 1, steps_number do + 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 + end + end, sleep_duration * i) + end +end + +vim.api.nvim_create_user_command("ScrollSmoothDown", function() + smooth_scroll(Dir.DOWN) +end, { desc = "Scroll down smoothly" }) +vim.api.nvim_create_user_command("ScrollSmoothUp", function() + smooth_scroll(Dir.UP) +end, { desc = "Scroll up smoothly" }) |
