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'.
This commit is contained in:
Anton Kastritskii
2025-07-30 02:53:57 +01:00
committed by GitHub
parent 807a65b2da
commit b79ff967ac
9 changed files with 145 additions and 12 deletions

View File

@@ -4022,6 +4022,72 @@ describe('vim.diagnostic', function()
end)
end)
describe('status()', function()
it('returns empty string if no diagnostics', function()
local result = exec_lua(function()
vim.diagnostic.set(_G.diagnostic_ns, _G.diagnostic_bufnr, {})
return vim.diagnostic.status()
end)
eq('', result)
end)
it('returns count for each diagnostic kind', function()
local result = exec_lua(function()
vim.diagnostic.set(_G.diagnostic_ns, 0, {
_G.make_error('Error 1', 0, 1, 0, 1),
_G.make_warning('Warning 1', 2, 2, 2, 2),
_G.make_warning('Warning 2', 2, 2, 2, 2),
_G.make_info('Info 1', 3, 3, 3, 3),
_G.make_info('Info 2', 3, 3, 3, 3),
_G.make_info('Info 3', 3, 3, 3, 3),
_G.make_hint('Hint 1', 4, 4, 4, 4),
_G.make_hint('Hint 2', 4, 4, 4, 4),
_G.make_hint('Hint 3', 4, 4, 4, 4),
_G.make_hint('Hint 4', 4, 4, 4, 4),
})
return vim.diagnostic.status()
end)
eq('E:1 W:2 I:3 H:4', result)
exec_lua('vim.cmd.enew()')
-- Empty diagnostics for a buffer without diagnostics
eq(
'',
exec_lua(function()
return vim.diagnostic.status()
end)
)
end)
it('uses text from diagnostic.config().signs.text[severity]', function()
local result = exec_lua(function()
vim.diagnostic.config({
signs = {
text = {
[vim.diagnostic.severity.ERROR] = '',
[vim.diagnostic.severity.WARN] = '⚠︎',
},
},
})
vim.diagnostic.set(_G.diagnostic_ns, 0, {
_G.make_error('Error 1', 0, 1, 0, 1),
_G.make_warning('Warning 1', 2, 2, 2, 2),
})
return vim.diagnostic.status()
end)
eq(':1 ⚠︎:1', result)
end)
end)
describe('handlers', function()
it('checks that a new handler is a table', function()
matches(

View File

@@ -792,6 +792,7 @@ describe('default statusline', function()
"%{% &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 ) : '' %}",
})

View File

@@ -2690,7 +2690,7 @@ func GetGlobalLocalWindowOptions()
" Filter for global or local to window
v/^'.*'.*\n.*global or local to window |global-local/d
" get option value and type
sil %s/^'\([^']*\)'.*'\s\+\(\w\+\)\s\+(default \%(\(".*"\|\d\+\|empty\)\).*/\1 \2 \3/g
sil %s/^'\([^']*\)'.*'\s\+\(\w\+\)\s\+(default \%(\(".*"\|\d\+\|empty\|is very long\)\).*/\1 \2 \3/g
" sil %s/empty/""/g
" split the result
" let result=getline(1,'$')->map({_, val -> split(val, ' ')})
@@ -2705,6 +2705,10 @@ func Test_set_option_window_global_local_all()
let optionlist = GetGlobalLocalWindowOptions()
for [opt, type, default] in optionlist
let _old = eval('&g:' .. opt)
if opt == 'statusline'
" parsed default value is "is very long" as it is a doc string, not actual value
let default = "\"" . _old . "\""
endif
if type == 'string'
if opt == 'fillchars'
exe 'setl ' .. opt .. '=vert:+'