diff --git a/nvim/.config/nvim/lua/DarthMooMancer/statusline.lua b/nvim/.config/nvim/lua/DarthMooMancer/statusline.lua index da5e3da..68662be 100644 --- a/nvim/.config/nvim/lua/DarthMooMancer/statusline.lua +++ b/nvim/.config/nvim/lua/DarthMooMancer/statusline.lua @@ -1,71 +1,60 @@ -local ok, D = pcall(require, 'nvim-web-devicons') +local D = require('nvim-web-devicons') local a, S = vim.api, vim.diagnostic.severity local now = (vim.uv or vim.loop).now local C = a.nvim_get_current_buf +local function cn(c) + return c.name +end local R = function() vim.cmd.redrawstatus() -end -- absorb autocmd ev (.file etc.) -local M = '%m%r %=' -local LOAD = '%#DiagnosticInfo#' +end local T, JOB = {}, nil -local IV = vim.g.statusline_prog_interval or 750 -- ms cap between progress redraws -local LAST = 0 +local IV, LAST = 750, 0 + local function snap(bb) - local nm = ' %F' -- native tail: handles [No Name] and escaping in C - if ok then - local i, hl = D.get_icon(a.nvim_buf_get_name(bb), nil, { default = true }) - if i then - nm = ' %#' .. hl .. '#' .. i .. ' %*%F' - end + local nm = ' %F' + local i, hl = D.get_icon(a.nvim_buf_get_name(bb), nil, { default = true }) + if i then + nm = ' %#' .. hl .. '#' .. i .. ' %*%F' end 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 dg = '' - if e + w + h > 0 then - dg = (e > 0 and ('%#DiagnosticError#E' .. e .. '%* ') or '') - .. (w > 0 and ('%#DiagnosticWarn#W' .. w .. '%* ') or '') - .. (h > 0 and ('%#DiagnosticHint#H' .. h .. '%* ') or '') - end - local rd, cs = '', vim.lsp.get_clients({ bufnr = bb }) - if #cs > 0 then - local nm2 = {} - for i = 1, #cs do - nm2[i] = cs[i].name - end - rd = '󰄭 ' .. table.concat(nm2, '/') .. ' ' - end - return nm .. M .. dg, rd + local dg = (e > 0 and ('%#DiagnosticError#E' .. e .. '%* ') or '') + .. (w > 0 and ('%#DiagnosticWarn#W' .. w .. '%* ') or '') + .. (h > 0 and ('%#DiagnosticHint#H' .. h .. '%* ') or '') + local cs = vim.lsp.get_clients({ bufnr = bb }) + local rd = #cs > 0 and ('󰄭 ' .. table.concat(vim.tbl_map(cn, cs), '/') .. ' ') or '' + return nm .. '%m%r %=' .. dg, rd end + local function touch(bb, redraw) - local v = vim.b[bb] -- per-buffer cache; nvim frees b: vars on unload - if v then - v.d = true - end + vim.b[bb].d = true if redraw then R() end end -local function SYNC(force) -- refresh JOB; redraw only when it changed and (force or gate open) + +local function sync(force) local prev = JOB JOB = nil for _, t in pairs(T) do - for _, m in pairs(t) do + local _, m = next(t) + if m then JOB = m break end - if JOB then - break - end end if JOB ~= prev and (force or now() - LAST >= IV) then LAST = now() R() end end + local G = a.nvim_create_augroup('STL5', { clear = true }) local function au(ev, cb) a.nvim_create_autocmd(ev, { group = G, callback = cb }) end + au({ 'BufEnter', 'BufFilePost' }, function(e) touch(e.buf, true) end) @@ -75,39 +64,32 @@ end) au({ 'LspAttach', 'LspDetach' }, function(e) if e.event == 'LspDetach' then T[e.data.client_id] = nil - SYNC(true) + sync(true) end touch(e.buf, true) end) au('LspProgress', function(e) local v = e.data.params.value - if type(v) ~= 'table' then - return - end local id, tk = e.data.client_id, e.data.params.token or 'default' T[id] = T[id] or {} if v.kind == 'end' or (v.kind == 'report' and v.percentage == 100) then T[id][tk] = nil - SYNC(true) -- clear immediately, don't gate + sync(true) else - 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 - m = v.title .. ' ' .. v.message - end - T[id][tk] = m - SYNC() -- gated: at most one redraw per IV ms + local title = (v.title and v.title ~= '') and v.title or nil + local msg = (v.message and v.message ~= '') and v.message or nil + T[id][tk] = (title and msg and (title .. ' ' .. msg)) or title or msg or 'Loading...' + sync() end end) -au('ColorScheme', R) -au('FocusGained', R) -local function Status() +au({ 'ColorScheme', 'FocusGained' }, R) + +function _G.Status() local v = vim.b if not v.h or v.d then v.h, v.r = snap(C()) - v.stl = v.h .. v.r - v.d = nil + v.stl, v.d = v.h .. v.r, nil end - return JOB and (v.h .. LOAD .. JOB .. '%* ') or v.stl + return JOB and (v.h .. '%#DiagnosticInfo#' .. JOB .. '%* ') or v.stl end -_G.Status = Status vim.opt.statusline = '%!v:lua.Status()'