vimtricks.wiki Concise Vim tricks, one at a time.

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 * redrawstatus so 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)

Next

What is the difference between the inner word (iw) and inner WORD (iW) text objects in Vim?