Skip to content

Instantly share code, notes, and snippets.

@seandewar
Last active October 14, 2022 22:39
Show Gist options
  • Save seandewar/a2ca14b48e8f965a3aaa8ce76516abc6 to your computer and use it in GitHub Desktop.
Save seandewar/a2ca14b48e8f965a3aaa8ce76516abc6 to your computer and use it in GitHub Desktop.
Temporarily hide the cursor when scrolling with the mouse wheel off-screen in Neovim v0.8
-- This script temporarily hides the 'cursorline' (and cursor if 'tgc' is set) if the cursor
-- would be scrolled outside of the window viewport when using the mouse wheel.
--
-- Written for @deagle.50:matrix.org for use with Neovide's smooth scrolling feature. :)
-- Tested using Neovim v0.8.
--
-- TODO: if the window is split before restoring, the hidden 'cul' state will leak into the new
-- window. Can probably be fixed with some autocmd hackery.
local api, fn, keymap = vim.api, vim.fn, vim.keymap
local o, wo = vim.o, vim.wo
api.nvim_set_hl(0, 'noCursor', { reverse = true, blend = 100 })
local restore_timer, restore_cb = vim.loop.new_timer(), nil
local function scroll(key)
local wins = api.nvim_tabpage_list_wins(0)
local save_toplines = vim.tbl_map(function(win)
return fn.getwininfo(win)[1].topline
end, wins)
api.nvim_feedkeys(api.nvim_replace_termcodes(key, true, false, true), 'nx', false)
for i, win in ipairs(wins) do
local wininfo = fn.getwininfo(win)[1]
-- Trigger for the scrolled window. We cannot use WinScrolled here as it doesn't fire for
-- non-current windows yet (they can be scrolled with the mouse).
if wininfo.topline ~= save_toplines[i] then
local row = api.nvim_win_get_cursor(win)[1]
local so = wo[win].scrolloff
-- Check if the cursor (probably) would have scrolled outside of view.
if row <= wininfo.topline + so or row >= wininfo.botline - so then
if restore_cb then
restore_cb()
end
local save_gcr, save_cul = o.guicursor, o.cursorline
o.guicursor = 'a:noCursor'
wo[win].cursorline = false
restore_cb = function()
if o.guicursor == 'a:noCursor' then
o.guicursor = save_gcr
end
if api.nvim_win_is_valid(win) and not wo[win].cursorline then
wo[win].cursorline = save_cul
end
end
restore_timer:start(500, 0, function()
vim.schedule(restore_cb)
restore_cb = nil
end)
return
end
end
end
end
keymap.set('n', '<ScrollWheelUp>', function()
scroll('<ScrollWheelUp>')
end)
keymap.set('n', '<ScrollWheelDown>', function()
scroll('<ScrollWheelDown>')
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment