From b79ff967ac91dce40f3598ea407c5ccaa2929250 Mon Sep 17 00:00:00 2001 From: Anton Kastritskii Date: Wed, 30 Jul 2025 02:53:57 +0100 Subject: feat(statusline): vim.diagnostic.status() #33723 Problem: Not easy to get a status string for diagnostics. Solution: - Add vim.diagnostic.status(). - Add it to the default 'statusline'. --- runtime/lua/vim/_meta/options.lua | 2 +- runtime/lua/vim/diagnostic.lua | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index ee87ebc322..6d9ffb8850 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -6909,7 +6909,7 @@ vim.wo.stc = vim.wo.statuscolumn --- --- --- @type string -vim.o.statusline = "%<%f %h%w%m%r %=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &busy > 0 ? '◐ ' : '' %}%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}" +vim.o.statusline = "%<%f %h%w%m%r %=%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}%{% &busy > 0 ? '◐ ' : '' %}%(%{luaeval('(pcall(require, ''vim.diagnostic'') and vim.diagnostic.status()) or '''' ')} %)%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}" vim.o.stl = vim.o.statusline vim.wo.statusline = vim.o.statusline vim.wo.stl = vim.wo.statusline diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index 6ea6436c5b..1175ec6518 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -2840,4 +2840,42 @@ function M.fromqflist(list) return diagnostics end +--- Returns formatted string with diagnostics for the current buffer. +--- The severities with 0 diagnostics are left out. +--- Example `E:2 W:3 I:4 H:5` +--- +--- To customise appearance, set diagnostic signs text with +--- ```lua +--- vim.diagnostic.config({ +--- signs = { text = { [vim.diagnostic.severity.ERROR] = 'e', ... } } +--- }) +--- ``` +---@param bufnr? integer Buffer number to get diagnostics from. +--- Defaults to 0 for the current buffer +--- +---@return string +function M.status(bufnr) + vim.validate('bufnr', bufnr, 'number', true) + bufnr = bufnr or 0 + local counts = M.count(bufnr) + local user_signs = vim.tbl_get(M.config() --[[@as vim.diagnostic.Opts]], 'signs', 'text') or {} + local signs = vim.tbl_extend('keep', user_signs, { 'E', 'W', 'I', 'H' }) + local result_str = vim + .iter(pairs(counts)) + :map(function(severity, count) + return ('%s:%s'):format(signs[severity], count) + end) + :join(' ') + + return result_str +end + +vim.api.nvim_create_autocmd('DiagnosticChanged', { + group = vim.api.nvim_create_augroup('nvim.diagnostic.status', {}), + callback = function(ev) + vim.api.nvim__redraw({ buf = ev.buf, statusline = true }) + end, + desc = 'diagnostics component for the statusline', +}) + return M -- cgit