summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.config/nvim/init.lua3
-rw-r--r--.config/nvim/plugin/50-smooth_scroll.lua35
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" })