How do I programmatically get the count of diagnostics by severity in Neovim Lua?
Answer
vim.diagnostic.count()
Explanation
vim.diagnostic.count(bufnr, opts) returns a table of diagnostic counts keyed by severity level. It is the right tool for building custom statusline components that display the number of errors and warnings in the current buffer — more efficient than iterating over vim.diagnostic.get() yourself.
How it works
vim.diagnostic.count(0)counts diagnostics in the current buffer (0= current)- The return value is a sparse table:
{ [1]=2, [2]=5 }where the keys map to severity constants - Severity constants:
vim.diagnostic.severity.ERROR = 1,WARN = 2,INFO = 3,HINT = 4 - Pass
{ severity = vim.diagnostic.severity.ERROR }as the second argument to count only a specific severity
Example
-- Statusline component: " E:2 W:5" or empty string when clean
local function diag_summary()
local counts = vim.diagnostic.count(0)
local E = counts[vim.diagnostic.severity.ERROR] or 0
local W = counts[vim.diagnostic.severity.WARN] or 0
if E + W == 0 then return '' end
return string.format(' E:%d W:%d', E, W)
end
-- Wire it into a simple statusline:
vim.o.statusline = '%f %=%{v:lua._G.diag_summary()} %l:%c'
_G.diag_summary = diag_summary
Tips
- Trigger a statusline redraw when diagnostics change with
autocmd DiagnosticChanged * redrawstatusso the count stays current - Pass any valid buffer number — not just
0— to count diagnostics in background buffers vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR })gives the full list when you need per-diagnostic detail (line, message, source)