-- Pinned to the v2 rewrite branch until it replaces v1 on main (2026-11-16, -- see https://github.com/petertriho/nvim-scrollbar/issues/121). After that, -- switch to `version = vim.version.range("^2")`. vim.pack.add({ { src = "https://github.com/petertriho/nvim-scrollbar", version = "refactor/v2" }, }) require("scrollbar").setup({ exclude = { filetypes = { ["neo-tree"] = true }, }, -- Search marks are native in v2 (no hlslens dependency like v1). providers = { search = true, gitsigns = true, }, marks = { Illuminate = { text = "≡", priority = 8, highlight = "Special" }, Search = { highlight = "DiagnosticVirtualTextInfo" }, Error = { highlight = "DiagnosticFloatingError" }, Warn = { highlight = "DiagnosticFloatingWarn" }, Info = { highlight = "DiagnosticFloatingInfo" }, Hint = { highlight = "DiagnosticFloatingHint" }, GitAdd = { highlight = "GitSignsAdd" }, GitChange = { highlight = "GitSignsChange" }, GitDelete = { highlight = "GitSignsDelete" }, }, scrollbar = { -- Non-focusable so Ctrl+W w never lands on the float; also disables -- click/drag navigation on the scrollbar. mouse = false, -- v1 had no track; the explicit PmenuSbar handle highlight carried over -- would make the thumb indistinguishable from the v2 track, which also -- defaults to PmenuSbar. The v2 defaults (PmenuThumb thumb on a -- PmenuSbar track) give the same subtle-on-subtle look the v1 override -- was after. }, }) -- Show illuminated word matches as scrollbar marks. The illuminate plugin -- refreshes its references after CursorMoved, so hook the events directly and -- publish through the provider API. `buffer = "provider"` ownership means the -- manager dispatches no automatic buffer refreshes; our autocmds own that. -- illuminate also refreshes its own refs ~100ms after CursorMoved, so re-run -- the refresh on a small debounce for snappy bars. local function get_illuminate_marks(bufnr) local ok, reference = pcall(require, "illuminate.reference") if not ok then return {} end -- illuminate stores refs as { {0-indexed line, col}, {0-indexed line, col} }, -- sorted. Several refs can share a line, so keep one mark per line. local illuminate_marks = {} local last_line = -1 for _, ref in ipairs(reference.buf_get_references(bufnr)) do local line = ref[1][1] if line ~= last_line then last_line = line illuminate_marks[#illuminate_marks + 1] = { line = line, text = "≡", type = "Illuminate", } end end return illuminate_marks end require("scrollbar.providers").register({ name = "illuminate", refresh_owner = { buffer = "provider" }, refresh = function(bufnr) return get_illuminate_marks(bufnr) end, setup = function(context) local function publish(bufnr) bufnr = (bufnr == nil or bufnr == 0) and vim.api.nvim_get_current_buf() or bufnr if not vim.api.nvim_buf_is_valid(bufnr) then return end if context.is_buffer_eligible(bufnr) then context.set_marks(bufnr, get_illuminate_marks(bufnr)) else context.clear_marks(bufnr) end end vim.api.nvim_create_autocmd({ "CursorMoved", "CursorHold", "TextChanged", "BufEnter", "WinEnter" }, { group = context.create_augroup("illuminate"), callback = function(args) publish(args.buf) if args.event == "CursorMoved" or args.event == "TextChanged" then vim.defer_fn(function() publish(args.buf) end, 250) end end, }) end, })