Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: incremental updates #45

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions lua/satellite/handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ local user_config = require 'satellite.config'.user_config
---@class Handler
---@field name string
---@field ns integer
---@field setup fun(config: HandlerConfig, update: fun())
---@field setup fun(config: HandlerConfig, update: fun(winid?: integer))
---@field update fun(bufnr: integer, winid: integer): SatelliteMark[]
---@field enabled fun(): boolean

Expand Down Expand Up @@ -53,6 +53,12 @@ function M.register(spec)
table.insert(M.handlers, h)
end

local function updater(handler)
return function(winid)
require('satellite.view').render_handler(handler, winid)
end
end

function M.init()
-- Load builtin handlers
for _, name in ipairs(BUILTIN_HANDLERS) do
Expand All @@ -61,12 +67,10 @@ function M.init()
end
end

local update = require('satellite.view').refresh_bars

-- Initialize handlers
for _, h in ipairs(M.handlers) do
if h:enabled() and h.setup then
h.setup(user_config.handlers[h.name], update)
for _, handler in ipairs(M.handlers) do
if handler:enabled() and handler.setup then
handler.setup(user_config.handlers[handler.name], updater(handler))
end
end
end
Expand Down
8 changes: 6 additions & 2 deletions lua/satellite/handlers/diagnostic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ local config = {
min_severity = vim.diagnostic.severity.HINT,
}

function handler.init(config0, update)
function handler.setup(config0, update)
config = vim.tbl_deep_extend('force', config, config0)

local gid = vim.api.nvim_create_augroup('satellite_diagnostics', {})
vim.api.nvim_create_autocmd('DiagnosticChanged', {
group = gid,
callback = update,
callback = function(args)
for _, winid in ipairs(vim.fn.win_findbuf(args.buf)) do
update(winid)
end
end
})
end

Expand Down
4 changes: 3 additions & 1 deletion lua/satellite/handlers/gitsigns.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ function handler.setup(config0, update)
api.nvim_create_autocmd('User', {
pattern = 'GitSignsUpdate',
group = group,
callback = update,
callback = function()
update()
end
})
end

Expand Down
7 changes: 4 additions & 3 deletions lua/satellite/handlers/marks.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
local util = require 'satellite.util'
local view = require 'satellite.view'

local highlight = 'MarkSV'

Expand Down Expand Up @@ -34,7 +33,7 @@ local function mark_is_builtin(m)
return false
end

function handler.init(config0, update)
function handler.setup(config0, update)
config = config0

local group = api.nvim_create_augroup('satellite_marks', {})
Expand All @@ -49,7 +48,9 @@ function handler.init(config0, update)
api.nvim_create_autocmd('User', {
group = group,
pattern = 'Mark',
callback = vim.schedule_wrap(update),
callback = vim.schedule_wrap(function()
update(api.nvim_get_current_win())
end)
})
end

Expand Down
6 changes: 3 additions & 3 deletions lua/satellite/handlers/search.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ local function update_matches(bufnr, pattern)
return matches
end

--- @param update fun()
--- @param update fun(winid?: integer)
local refresh = async.void(function(update)
update_matches(api.nvim_get_current_buf())
update()
update(api.nvim_get_current_win())
end)

---@type Handler
Expand All @@ -114,7 +114,7 @@ local function setup_hl()
})
end

function handler.init(_config, update)
function handler.setup(_config, update)
local group = api.nvim_create_augroup('satellite_search', {})

api.nvim_create_autocmd('ColorScheme', {
Expand Down
117 changes: 64 additions & 53 deletions lua/satellite/view.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,72 @@ local function render_scrollbar(winid, bbufnr, row, height)
end
end

---@param bufnr integer
---@param winid integer
---@param bbufnr integer
---@param handler Handler
local function render_handler(bufnr, winid, bbufnr, handler)
local name = handler.name
---@param bar_winid integer
local function reposition_bar(winid, bar_winid)
local toprow = vim.w[bar_winid].row
local winwidth = api.nvim_win_get_width(winid)
local wininfo = vim.fn.getwininfo(bar_winid)[1]

--- @type integer
local signwidth = wininfo.textoff

local cfg = {
relative = 'win',
win = winid,
row = 0,
col = winwidth - signwidth - 1,
width = 1 + signwidth,
}

api.nvim_win_set_config(bar_winid, cfg)

vim.w[bar_winid].col = cfg.col
vim.w[bar_winid].width = cfg.width
vim.w[bar_winid].row = toprow
end

local function get_target_windows()
if user_config.current_only then
return { api.nvim_get_current_win() }
end

local target_wins = {} ---@type integer[]
local current_tab = api.nvim_get_current_tabpage()
for _, winid in ipairs(api.nvim_list_wins()) do
if util.is_ordinary_window(winid) and api.nvim_win_get_tabpage(winid) == current_tab then
target_wins[#target_wins + 1] = winid
end
end
return target_wins
end

---@param handler Handler
---@param winid? integer
function M.render_handler(handler, winid)
if not handler:enabled() then
return
end

if not winid then
for _, w in ipairs(get_target_windows()) do
M.render_handler(handler, w)
end
return
end

local bwinid = winids[winid]
if not bwinid then
return
end

local bbufnr = api.nvim_win_get_buf(bwinid)

local name = handler.name

local handler_config = user_config.handlers[name] or {}

local bufnr = api.nvim_win_get_buf(winid)
api.nvim_buf_clear_namespace(bbufnr, handler.ns, 0, -1)
for _, m in ipairs(handler.update(bufnr, winid)) do
local pos, symbol = m.pos, m.symbol
Expand Down Expand Up @@ -118,50 +171,23 @@ local function render_handler(bufnr, winid, bbufnr, handler)
)
end
end
end

---@param winid integer
---@param bar_winid integer
---@param toprow integer
local function reposition_bar(winid, bar_winid, toprow)
local winwidth = api.nvim_win_get_width(winid)
local wininfo = vim.fn.getwininfo(bar_winid)[1]

--- @type integer
local signwidth = wininfo.textoff

local cfg = {
relative = 'win',
win = winid,
row = 0,
col = winwidth - signwidth - 1,
width = 1 + signwidth,
}

api.nvim_win_set_config(bar_winid, cfg)

vim.w[bar_winid].col = cfg.col
vim.w[bar_winid].width = cfg.width
vim.w[bar_winid].row = toprow
vim.schedule(function()
reposition_bar(winid, bwinid)
end)
end

---@param bbufnr integer
---@param bwinid integer
---@param winid integer
---@param row integer
---@param height integer
local render = async.void(function(bbufnr, bwinid, winid, row, height)
local render = async.void(function(bbufnr, winid, row, height)
render_scrollbar(winid, bbufnr, row, height)

-- Run handlers
local bufnr = api.nvim_win_get_buf(winid)
for _, handler in ipairs(Handlers.handlers) do
render_handler(bufnr, winid, bbufnr, handler)
M.render_handler(handler, winid)
end

-- if api.nvim_win_is_valid(winid) and api.nvim_win_is_valid(bwinid) then
-- reposition_bar(winid, bwinid, row)
-- end
end)

-- Show a scrollbar for the specified 'winid' window ID, using the specified
Expand Down Expand Up @@ -248,7 +274,7 @@ local function show_scrollbar(winid)

local toprow = util.row_to_barpos(winid, topline - 1)
local height = util.height_to_virtual(winid, topline - 1, botline - 1)
render(bar_bufnr, bar_winid, winid, toprow, height)
render(bar_bufnr, winid, toprow, height)

vim.w[bar_winid].height = height
vim.w[bar_winid].row = toprow
Expand Down Expand Up @@ -276,21 +302,6 @@ function M.get_props(winid)
}
end

local function get_target_windows()
if user_config.current_only then
return { api.nvim_get_current_win() }
end

local target_wins = {} ---@type integer[]
local current_tab = api.nvim_get_current_tabpage()
for _, winid in ipairs(api.nvim_list_wins()) do
if util.is_ordinary_window(winid) and api.nvim_win_get_tabpage(winid) == current_tab then
target_wins[#target_wins + 1] = winid
end
end
return target_wins
end

local function close(winid)
local bar_winid = winids[winid]
if not api.nvim_win_is_valid(bar_winid) then
Expand Down