Open Rumi152 opened 5 months ago
For anyone interested here is my config for auto zz after
local function post_hook(info)
local neoscroll = require("neoscroll")
if info == nil then
return
end
if info.move_view ~= nil then
vim.defer_fn(function()
neoscroll.scroll(info.move_view.lines, {
move_cursor = false,
duration = info.move_view.duration,
})
end, 10)
end
if info.move_cursor ~= nil then
vim.defer_fn(function()
vim.api.nvim_win_set_cursor(0, {
math.max(1 - vim.fn.line("."), math.min(vim.fn.line("$"), vim.fn.line(".") + info.move_cursor.lines)),
vim.api.nvim_win_get_cursor(0)[2],
})
end, 10 + info.move_cursor.duration)
end
end
local function scroll_and_center(scroll, half_win_duration)
local window_height = vim.api.nvim_win_get_height(0)
local topmost_line = vim.fn.line("w0")
local current_middle_line = topmost_line + math.ceil(window_height / 2)
local current_line = vim.fn.line(".")
local off_target = math.max(-current_line + 1, math.min(scroll, vim.fn.line("$") - current_line))
local off_center = current_line - current_middle_line
local both_scroll = 0
local view_scroll = 0
local cursor_scroll = 0
-- both scrolls work together in one direction
if off_center * off_target >= 0 then
both_scroll = off_target
view_scroll = off_center
cursor_scroll = 0
else
both_scroll = off_target + off_center -- off_center is opposite to off target here, so actually its substracting
view_scroll = 0
cursor_scroll = -off_center
end
local both_scroll_duration = math.floor(half_win_duration * (math.abs(both_scroll) / (window_height / 2)) + 0.5)
local view_scroll_duration = math.floor(half_win_duration * (math.abs(view_scroll) / (window_height / 2)) + 0.5)
local cursor_scroll_duration = math.floor(half_win_duration * (math.abs(cursor_scroll) / (window_height / 2)) + 0.5)
if both_scroll == 0 then
post_hook({
move_view = {
duration = view_scroll_duration,
lines = view_scroll,
},
move_cursor = {
duration = cursor_scroll_duration,
lines = cursor_scroll,
},
})
else
require("neoscroll").scroll(both_scroll, {
move_cursor = true,
duration = both_scroll_duration,
info = {
move_view = {
duration = view_scroll_duration,
lines = view_scroll,
},
move_cursor = {
duration = cursor_scroll_duration,
lines = cursor_scroll,
},
},
})
end
end
return {
"karb94/neoscroll.nvim",
config = function()
local neoscroll = require("neoscroll")
neoscroll.setup({
mappings = {},
-- pre_hook = function(info) end,
post_hook = post_hook,
})
local keymap = {
["<C-u>"] = function()
scroll_and_center(-vim.wo.scroll, 100)
end,
["<C-d>"] = function()
scroll_and_center(vim.wo.scroll, 100)
end,
["<C-y>"] = function()
neoscroll.scroll(-0.1, { move_cursor = false, duration = 80 })
end,
["<C-e>"] = function()
neoscroll.scroll(0.1, { move_cursor = false, duration = 80 })
end,
["zz"] = function()
neoscroll.zz({ half_win_duration = 100 })
end,
-- ["G"] = function()
-- neoscroll.G({ half_win_duration = 100 })
-- end,
-- ["gg"] = function()
-- neoscroll.gg({ half_win_duration = 100 })
}
local modes = { "n", "v", "x" }
for key, func in pairs(keymap) do
vim.keymap.set(modes, key, func)
end
end,
}
Can you explain in more detail what kind of animation are you looking to achieve? I copied your config but I can't really tell what is going on.
When the view is at the bottom of a file the cursor keeps scrolling until it hits eof (At least when this option is set in config). I would love to have this possibility whenever i want. My config makes it so C-d is basically C-D + zz, but doign these two commands one after another makes view go down first and then back up after (If cursor is at the top half of screen). I wanted to do it, so view scrolls down just enough to be centered around line that is vim.wo.scroll lines down.
Behavior for C-d (analogous to C-u)
If cursor is on to half, for example first line of window: cursor scrolls half a page, but the view doesnt need to scroll at all. This is problematic because plugin doesn't allow for smooth scrolling cursor, without moving view. Let me know if I need to explain more, english isn't my first language and my lua skills are not great either so it's kind of messy
Thanks for sharing your config @Rumi152 -- I was just trying to customize C-u and C-d so that it keeps the cursor in the middle of the screen.
To piggyback on this request, it would be great if this case was natively supported as an option on the plugin itself. My default remap for \<C-d> used to be "\<C-d>zz" (based on ThePrimeagen's dotfiles). Feels less disorienting than the default vim behaviour personally.
In any case, big thanks for neoscroll @karb94!
This is just a thought but what about using the pre_hook
functionality to move the cursor to the centre before starting the scrolling animation? You could even hide the cursor so that the transition is seamless.
I mean yeah, it kind of works right now. Just the option of smoothly moving the cursor instead of hiding it and showing again is not possible. Even without that the plugin is great and I love using similiar solution, it just doesn't seamlessly integrate with defaults (Where both the view and cursor scroll together, not the one where cursor is hidden during animation).
I wanted to achieve the same effect and also couldn't manage with neoscroll, so I wrote my own animation and it works well. I thought I would share it here in case it helps, as an inspiration.
https://gist.github.com/Lcchy/a438997093438785db4796ebcb97b873
ps: it uses coop.nvim
for async execution
Could we get option for scrolling only cursor, without viewport, unless the cursor goes out of bounds. It will be really useful if you create custom scrolling with chaining multiple scrolls with hooks. I am doing equivalent ofzz that looks nice, which is combination of scrolling only cursor (not possible), scrolling viewport, and scrolling both