REFACTOR: Even more cleanup

This commit is contained in:
2026-10-10 03:26:15 -04:00
parent 10ef727e6f
commit ca015f90f9
@@ -1,52 +1,30 @@
local ok, D = pcall(require, 'nvim-web-devicons') local ok, D = pcall(require, 'nvim-web-devicons')
local a, u, S = vim.api, vim.uv or vim.loop, vim.diagnostic.severity local a, S = vim.api, vim.diagnostic.severity
local now = (vim.uv or vim.loop).now
local C = a.nvim_get_current_buf local C = a.nvim_get_current_buf
local R = function() local R = function()
vim.cmd.redrawstatus() vim.cmd.redrawstatus()
end end -- absorb autocmd ev (.file etc.)
local M = '%#StatusLineMod#%m%*%#StatusLineRO#%r%* %=' local M = '%m%r %='
local FR = { '⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏' } local LOAD = '%#DiagnosticInfo#'
local N, SPIN, LOAD = #FR, '%#StatusLspSpinner#', '%* %#StatusLspLoading#' local T, JOB = {}, nil
local c, T, JOB, TMR, IDX = {}, {}, nil, nil, 1 local IV = vim.g.statusline_prog_interval or 750 -- ms cap between progress redraws
local function HI() local LAST = 0
local bg = a.nvim_get_hl(0, { name = 'StatusLine' }).bg or 'none'
for _, t in ipairs({
{ 'StatusLineFilename', 'Normal', true },
{ 'StatusLineMod', 'WarningMsg', true },
{ 'StatusLineRO', 'ErrorMsg', true },
{ 'StatusDiagError', 'DiagnosticError', true },
{ 'StatusDiagWarn', 'DiagnosticWarn', false },
{ 'StatusDiagHint', 'DiagnosticHint', false },
{ 'StatusLspSpinner', 'DiagnosticWarn', true },
{ 'StatusLspLoading', 'DiagnosticInfo', false },
{ 'StatusLspReady', 'Comment', false },
}) do
local h = a.nvim_get_hl(0, { name = t[2], link = false })
a.nvim_set_hl(0, t[1], { fg = h.fg, bg = bg, bold = t[3] })
end
end
local function snap(bb) local function snap(bb)
local p = a.nvim_buf_get_name(bb) local nm = ' %F' -- native tail: handles [No Name] and escaping in C
local nm = ' %#StatusLineFilename#'
if p == '' then
nm = nm .. '[No Name]%*'
else
local f = p:match('([^/\\]+)$') or p
if ok then if ok then
local i, hl = D.get_icon(f, p:match('%.([^./\\]+)$'), { default = true }) local i, hl = D.get_icon(a.nvim_buf_get_name(bb), nil, { default = true })
if i then if i then
nm = nm .. '%#' .. hl .. '#' .. i .. ' %*' nm = ' %#' .. hl .. '#' .. i .. ' %*%F'
end end
end end
nm = nm .. f .. '%*'
end
local x = vim.diagnostic.count(bb) local x = vim.diagnostic.count(bb)
local e, w, h = x[S.ERROR] or 0, x[S.WARN] or 0, x[S.HINT] or 0 local e, w, h = x[S.ERROR] or 0, x[S.WARN] or 0, x[S.HINT] or 0
local dg = '' local dg = ''
if e + w + h > 0 then if e + w + h > 0 then
dg = (e > 0 and ('%#StatusDiagError#E' .. e .. '%* ') or '') dg = (e > 0 and ('%#DiagnosticError#E' .. e .. '%* ') or '')
.. (w > 0 and ('%#StatusDiagWarn#W' .. w .. '%* ') or '') .. (w > 0 and ('%#DiagnosticWarn#W' .. w .. '%* ') or '')
.. (h > 0 and ('%#StatusDiagHint#H' .. h .. '%* ') or '') .. (h > 0 and ('%#DiagnosticHint#H' .. h .. '%* ') or '')
end end
local rd, cs = '', vim.lsp.get_clients({ bufnr = bb }) local rd, cs = '', vim.lsp.get_clients({ bufnr = bb })
if #cs > 0 then if #cs > 0 then
@@ -54,12 +32,12 @@ local function snap(bb)
for i = 1, #cs do for i = 1, #cs do
nm2[i] = cs[i].name nm2[i] = cs[i].name
end end
rd = '%#StatusLspReady#󰄭 ' .. table.concat(nm2, '/') .. '%* ' rd = '󰄭 ' .. table.concat(nm2, '/') .. ' '
end end
return nm .. M .. dg, rd return nm .. M .. dg, rd
end end
local function touch(bb, redraw) local function touch(bb, redraw)
local v = c[bb] local v = vim.b[bb] -- per-buffer cache; nvim frees b: vars on unload
if v then if v then
v.d = true v.d = true
end end
@@ -67,7 +45,8 @@ local function touch(bb, redraw)
R() R()
end end
end end
local function SYNC() local function SYNC(force) -- refresh JOB; redraw only when it changed and (force or gate open)
local prev = JOB
JOB = nil JOB = nil
for _, t in pairs(T) do for _, t in pairs(T) do
for _, m in pairs(t) do for _, m in pairs(t) do
@@ -78,57 +57,29 @@ local function SYNC()
break break
end end
end end
if JOB and not TMR then if JOB ~= prev and (force or now() - LAST >= IV) then
IDX = math.floor(u.now() / 100) % N + 1 LAST = now()
TMR = u.new_timer()
TMR:start(
0,
100,
vim.schedule_wrap(function()
if JOB then
IDX = IDX % N + 1
R()
elseif TMR then
TMR:stop()
TMR:close()
TMR = nil
end
end)
)
elseif not JOB and TMR then
TMR:stop()
TMR:close()
TMR = nil
R() R()
end end
end end
local G = a.nvim_create_augroup('STL5', { clear = true }) local G = a.nvim_create_augroup('STL5', { clear = true })
for _, s in ipairs({ local function au(ev, cb)
{ a.nvim_create_autocmd(ev, { group = G, callback = cb })
{ 'BufEnter', 'BufFilePost' }, end
function(e) au({ 'BufEnter', 'BufFilePost' }, function(e)
touch(e.buf, true) touch(e.buf, true)
end, end)
}, au('DiagnosticChanged', function(e)
{
'DiagnosticChanged',
function(e)
touch(e.buf, e.buf == C()) touch(e.buf, e.buf == C())
end, end)
}, au({ 'LspAttach', 'LspDetach' }, function(e)
{
{ 'LspAttach', 'LspDetach' },
function(e)
if e.event == 'LspDetach' then if e.event == 'LspDetach' then
T[e.data.client_id] = nil T[e.data.client_id] = nil
SYNC() SYNC(true)
end end
touch(e.buf, true) touch(e.buf, true)
end, end)
}, au('LspProgress', function(e)
{
'LspProgress',
function(e)
local v = e.data.params.value local v = e.data.params.value
if type(v) ~= 'table' then if type(v) ~= 'table' then
return return
@@ -137,50 +88,26 @@ for _, s in ipairs({
T[id] = T[id] or {} T[id] = T[id] or {}
if v.kind == 'end' or (v.kind == 'report' and v.percentage == 100) then if v.kind == 'end' or (v.kind == 'report' and v.percentage == 100) then
T[id][tk] = nil T[id][tk] = nil
SYNC(true) -- clear immediately, don't gate
else else
local m = (v.title and v.title ~= '' and v.title) or v.message or 'Loading...' local m = (v.title and v.title ~= '' and v.title) or v.message or 'Loading...'
if v.title and v.message and v.message ~= '' then if v.title and v.message and v.message ~= '' then
m = v.title .. ' ' .. v.message m = v.title .. ' ' .. v.message
end end
T[id][tk] = m T[id][tk] = m
SYNC() -- gated: at most one redraw per IV ms
end end
SYNC() end)
end, au('ColorScheme', R)
}, au('FocusGained', R)
{
'BufUnload',
function(e)
c[e.buf] = nil
end,
},
{
'ColorScheme',
function()
HI()
R()
end,
},
{ 'FocusGained', R },
}) do
a.nvim_create_autocmd(s[1], { group = G, callback = s[2] })
end
HI()
local function Status() local function Status()
local bb = C() local v = vim.b
local v = c[bb] if not v.h or v.d then
if not v or v.d then v.h, v.r = snap(C())
if not v then
v = {}
c[bb] = v
end
v.h, v.r = snap(bb)
v.stl = v.h .. v.r v.stl = v.h .. v.r
v.d = nil v.d = nil
end end
if JOB then return JOB and (v.h .. LOAD .. JOB .. '%* ') or v.stl
return v.h .. SPIN .. FR[IDX] .. LOAD .. JOB .. '%* '
end
return v.stl
end end
_G.Status = Status _G.Status = Status
vim.opt.statusline = '%!v:lua.Status()' vim.opt.statusline = '%!v:lua.Status()'