mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
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:

committed by
GitHub

parent
807a65b2da
commit
b79ff967ac
@@ -1019,6 +1019,23 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
|
|||||||
• {opts} (`vim.diagnostic.Opts?`) Display options. See
|
• {opts} (`vim.diagnostic.Opts?`) Display options. See
|
||||||
|vim.diagnostic.Opts|.
|
|vim.diagnostic.Opts|.
|
||||||
|
|
||||||
|
status({bufnr}) *vim.diagnostic.status()*
|
||||||
|
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', ... } }
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
|
Parameters: ~
|
||||||
|
• {bufnr} (`integer?`) Buffer number to get diagnostics from. Defaults
|
||||||
|
to 0 for the current buffer
|
||||||
|
|
||||||
|
Return: ~
|
||||||
|
(`string`)
|
||||||
|
|
||||||
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
|
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
|
||||||
Convert a list of diagnostics to a list of quickfix items that can be
|
Convert a list of diagnostics to a list of quickfix items that can be
|
||||||
passed to |setqflist()| or |setloclist()|.
|
passed to |setqflist()| or |setloclist()|.
|
||||||
|
@@ -145,6 +145,7 @@ DEFAULTS
|
|||||||
|
|
||||||
• 'statusline' default is exposed as a statusline expression (previously it
|
• 'statusline' default is exposed as a statusline expression (previously it
|
||||||
was implemented as an internal C routine).
|
was implemented as an internal C routine).
|
||||||
|
• 'statusline' includes |vim.diagnostic.status()|
|
||||||
• Project-local configuration ('exrc') is also loaded from parent directories.
|
• Project-local configuration ('exrc') is also loaded from parent directories.
|
||||||
Unset 'exrc' to stop further search.
|
Unset 'exrc' to stop further search.
|
||||||
• Mappings:
|
• Mappings:
|
||||||
@@ -157,6 +158,8 @@ DIAGNOSTICS
|
|||||||
location/quickfix list.
|
location/quickfix list.
|
||||||
• |vim.diagnostic.get()| now accepts an `enabled` filter to only return
|
• |vim.diagnostic.get()| now accepts an `enabled` filter to only return
|
||||||
enabled or disabled diagnostics.
|
enabled or disabled diagnostics.
|
||||||
|
• |vim.diagnostic.status()| returns a formatted string with current buffer
|
||||||
|
diagnostics
|
||||||
|
|
||||||
EDITOR
|
EDITOR
|
||||||
|
|
||||||
|
@@ -6231,7 +6231,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
an expensive expression can negatively affect render performance.
|
an expensive expression can negatively affect render performance.
|
||||||
|
|
||||||
*'statusline'* *'stl'* *E540* *E542*
|
*'statusline'* *'stl'* *E540* *E542*
|
||||||
'statusline' 'stl' string (default "%<%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 ) : '' %}")
|
'statusline' 'stl' string (default is very long)
|
||||||
global or local to window |global-local|
|
global or local to window |global-local|
|
||||||
Sets the |status-line|.
|
Sets the |status-line|.
|
||||||
|
|
||||||
|
2
runtime/lua/vim/_meta/options.lua
generated
2
runtime/lua/vim/_meta/options.lua
generated
@@ -6909,7 +6909,7 @@ vim.wo.stc = vim.wo.statuscolumn
|
|||||||
---
|
---
|
||||||
---
|
---
|
||||||
--- @type string
|
--- @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.o.stl = vim.o.statusline
|
||||||
vim.wo.statusline = vim.o.statusline
|
vim.wo.statusline = vim.o.statusline
|
||||||
vim.wo.stl = vim.wo.statusline
|
vim.wo.stl = vim.wo.statusline
|
||||||
|
@@ -2840,4 +2840,42 @@ function M.fromqflist(list)
|
|||||||
return diagnostics
|
return diagnostics
|
||||||
end
|
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
|
return M
|
||||||
|
@@ -8706,15 +8706,19 @@ local options = {
|
|||||||
{
|
{
|
||||||
abbreviation = 'stl',
|
abbreviation = 'stl',
|
||||||
cb = 'did_set_statusline',
|
cb = 'did_set_statusline',
|
||||||
defaults = table.concat({
|
defaults = {
|
||||||
'%<',
|
if_true = table.concat({
|
||||||
'%f %h%w%m%r ',
|
'%<',
|
||||||
'%=',
|
'%f %h%w%m%r ',
|
||||||
"%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}",
|
'%=',
|
||||||
"%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}",
|
"%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}",
|
||||||
"%{% &busy > 0 ? '◐ ' : '' %}",
|
"%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}",
|
||||||
"%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}",
|
"%{% &busy > 0 ? '◐ ' : '' %}",
|
||||||
}),
|
"%(%{luaeval('(pcall(require, ''vim.diagnostic'') and vim.diagnostic.status()) or '''' ')} %)",
|
||||||
|
"%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}",
|
||||||
|
}),
|
||||||
|
doc = 'is very long',
|
||||||
|
},
|
||||||
desc = [=[
|
desc = [=[
|
||||||
Sets the |status-line|.
|
Sets the |status-line|.
|
||||||
|
|
||||||
|
@@ -4022,6 +4022,72 @@ describe('vim.diagnostic', function()
|
|||||||
end)
|
end)
|
||||||
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()
|
describe('handlers', function()
|
||||||
it('checks that a new handler is a table', function()
|
it('checks that a new handler is a table', function()
|
||||||
matches(
|
matches(
|
||||||
|
@@ -792,6 +792,7 @@ describe('default statusline', function()
|
|||||||
"%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}",
|
"%{% &showcmdloc == 'statusline' ? '%-10.S ' : '' %}",
|
||||||
"%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}",
|
"%{% exists('b:keymap_name') ? '<'..b:keymap_name..'> ' : '' %}",
|
||||||
"%{% &busy > 0 ? '◐ ' : '' %}",
|
"%{% &busy > 0 ? '◐ ' : '' %}",
|
||||||
|
"%(%{luaeval('(pcall(require, ''vim.diagnostic'') and vim.diagnostic.status()) or '''' ')} %)",
|
||||||
"%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}",
|
"%{% &ruler ? ( &rulerformat == '' ? '%-14.(%l,%c%V%) %P' : &rulerformat ) : '' %}",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -2690,7 +2690,7 @@ func GetGlobalLocalWindowOptions()
|
|||||||
" Filter for global or local to window
|
" Filter for global or local to window
|
||||||
v/^'.*'.*\n.*global or local to window |global-local/d
|
v/^'.*'.*\n.*global or local to window |global-local/d
|
||||||
" get option value and type
|
" 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
|
" sil %s/empty/""/g
|
||||||
" split the result
|
" split the result
|
||||||
" let result=getline(1,'$')->map({_, val -> split(val, ' ')})
|
" let result=getline(1,'$')->map({_, val -> split(val, ' ')})
|
||||||
@@ -2705,6 +2705,10 @@ func Test_set_option_window_global_local_all()
|
|||||||
let optionlist = GetGlobalLocalWindowOptions()
|
let optionlist = GetGlobalLocalWindowOptions()
|
||||||
for [opt, type, default] in optionlist
|
for [opt, type, default] in optionlist
|
||||||
let _old = eval('&g:' .. opt)
|
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 type == 'string'
|
||||||
if opt == 'fillchars'
|
if opt == 'fillchars'
|
||||||
exe 'setl ' .. opt .. '=vert:+'
|
exe 'setl ' .. opt .. '=vert:+'
|
||||||
|
Reference in New Issue
Block a user