whitespace: support multiline statusline for warnings

Add a new airline_section_warning2 that displays whitespace warnings on
a second statusline line when Vim supports the statuslineopt option
(Vim 9.2.0083+) and g:airline_multiline is set. The second line only
appears when there are actual whitespace issues, avoiding an empty
second line when the buffer is clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2026-04-12 08:15:15 +00:00
parent 7fe264257e
commit ee44d57525
7 changed files with 77 additions and 16 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ scriptencoding utf-8
let g:airline_statusline_funcrefs = get(g:, 'airline_statusline_funcrefs', [])
let g:airline_inactive_funcrefs = get(g:, 'airline_inactive_statusline_funcrefs', [])
let s:sections = ['a','b','c','gutter','x','y','z', 'error', 'warning']
let s:sections = ['a','b','c','gutter','x','y','z', 'error', 'warning', 'warning2']
let s:contexts = {}
let s:core_funcrefs = [
\ function('airline#extensions#apply'),
+35 -10
View File
@@ -11,10 +11,11 @@ let s:section_truncate_width = get(g:, 'airline#extensions#default#section_trunc
\ 'z': 45,
\ 'warning': 80,
\ 'error': 80,
\ 'warning2': 80,
\ })
let s:layout = get(g:, 'airline#extensions#default#layout', [
\ [ 'a', 'b', 'c' ],
\ [ 'x', 'y', 'z', 'warning', 'error' ]
\ [ 'x', 'y', 'z', 'warning', 'error', 'warning2' ]
\ ])
function! s:get_section(winnr, key, ...)
@@ -32,9 +33,24 @@ function! s:get_section(winnr, key, ...)
return empty(text) ? '' : prefix.text.suffix
endfunction
function! s:eval_section_empty(content)
let exprlist = []
call substitute(a:content, '%{\([^}]*\)}', '\=add(exprlist, submatch(1))', 'g')
for expr in exprlist
try
if !empty(eval(expr))
return 0
endif
catch
return 0
endtry
endfor
return 1
endfunction
function! s:build_sections(builder, context, keys)
for key in a:keys
if (key == 'warning' || key == 'error') && !a:context.active
if (key == 'warning' || key == 'error' || key == 'warning2') && !a:context.active
continue
endif
call s:add_section(a:builder, a:context, key)
@@ -49,21 +65,30 @@ if s:section_use_groups && (v:version >= 704 || (v:version >= 703 && has('patch8
\ (v:version == 704 && !has("patch1511"))
" i have no idea why the warning section needs special treatment, but it's
" needed to prevent separators from showing up
if ((a:key == 'error' || a:key == 'warning') && empty(s:get_section(a:context.winnr, a:key)))
if ((a:key == 'error' || a:key == 'warning' || a:key == 'warning2')
\ && empty(s:get_section(a:context.winnr, a:key)))
return
endif
if condition
call a:builder.add_raw('%(')
endif
call a:builder.add_section('airline_'.a:key, s:get_section(a:context.winnr, a:key))
if condition
call a:builder.add_raw('%)')
if a:key == 'warning2' && airline#util#has_multiline()
let section = s:get_section(a:context.winnr, a:key)
if !s:eval_section_empty(section)
call a:builder.add_raw('%@%#airline_warning#'.section)
endif
else
if condition
call a:builder.add_raw('%(')
endif
call a:builder.add_section('airline_'.a:key, s:get_section(a:context.winnr, a:key))
if condition
call a:builder.add_raw('%)')
endif
endif
endfunction
else
" older version don't like the use of %(%)
function! s:add_section(builder, context, key)
if ((a:key == 'error' || a:key == 'warning') && empty(s:get_section(a:context.winnr, a:key)))
if ((a:key == 'error' || a:key == 'warning')
\ && empty(s:get_section(a:context.winnr, a:key)))
return
endif
if a:key == 'warning'
+14 -3
View File
@@ -161,6 +161,9 @@ function! airline#extensions#whitespace#check()
endif
endif
endif
if airline#util#has_multiline()
return b:airline_whitespace_check
endif
return airline#util#shorten(b:airline_whitespace_check, 120, 9)
endfunction
@@ -178,8 +181,16 @@ function! airline#extensions#whitespace#toggle()
if exists("g:airline#extensions#whitespace#enabled")
let g:airline#extensions#whitespace#enabled = s:enabled
if s:enabled && match(g:airline_section_warning, '#whitespace#check') < 0
let g:airline_section_warning .= airline#section#create(['whitespace'])
if s:enabled
if airline#util#has_multiline() && exists('g:airline_section_warning2')
if match(g:airline_section_warning2, '#whitespace#check') < 0
let g:airline_section_warning2 .= airline#section#create(['whitespace'])
endif
else
if match(g:airline_section_warning, '#whitespace#check') < 0
let g:airline_section_warning .= airline#section#create(['whitespace'])
endif
endif
call airline#update_statusline()
endif
endif
@@ -211,7 +222,7 @@ function! s:ws_refresh()
return
endif
unlet! b:airline_whitespace_check
if get(g:, 'airline_skip_empty_sections', 0)
if get(g:, 'airline_skip_empty_sections', 0) || airline#util#has_multiline()
exe ':AirlineRefresh!'
endif
let b:airline_ws_changedtick = b:changedtick
+11 -2
View File
@@ -294,7 +294,16 @@ function! airline#init#sections()
if !exists('g:airline_section_error')
let g:airline_section_error = airline#section#create(['ycm_error_count', 'syntastic-err', 'eclim', 'neomake_error_count', 'ale_error_count', 'lsp_error_count', 'nvimlsp_error_count', 'languageclient_error_count', 'coc_error_count', 'vim9lsp_error_count'])
endif
if !exists('g:airline_section_warning')
let g:airline_section_warning = airline#section#create(['ycm_warning_count', 'syntastic-warn', 'neomake_warning_count', 'ale_warning_count', 'lsp_warning_count', 'nvimlsp_warning_count', 'languageclient_warning_count', 'whitespace', 'coc_warning_count', 'vim9lsp_warning_count'])
if airline#util#has_multiline()
if !exists('g:airline_section_warning')
let g:airline_section_warning = airline#section#create(['ycm_warning_count', 'syntastic-warn', 'neomake_warning_count', 'ale_warning_count', 'lsp_warning_count', 'nvimlsp_warning_count', 'languageclient_warning_count', 'coc_warning_count', 'vim9lsp_warning_count'])
endif
if !exists('g:airline_section_warning2')
let g:airline_section_warning2 = airline#section#create(['whitespace'])
endif
else
if !exists('g:airline_section_warning')
let g:airline_section_warning = airline#section#create(['ycm_warning_count', 'syntastic-warn', 'neomake_warning_count', 'ale_warning_count', 'lsp_warning_count', 'nvimlsp_warning_count', 'languageclient_warning_count', 'whitespace', 'coc_warning_count', 'vim9lsp_warning_count'])
endif
endif
endfunction
+6
View File
@@ -250,3 +250,9 @@ function! airline#util#has_vim9_script()
\ get(g:, "airline_experimental", 0))
endfunction
function! airline#util#has_multiline()
" Returns true, if Vim supports multiline statusline (Vim 9.2.0083)
return (exists("+statuslineopt") &&
\ get(g:, "airline_multiline", 0))
endfunction
+7
View File
@@ -57,6 +57,8 @@ this: >
+---------------------------------------------------------------------------+
| A | B | C X | Y | Z | [...] |
+---------------------------------------------------------------------------+
| [...] |
+---------------------------------------------------------------------------+
The statusline is the colored line at the bottom, which contains the sections
(possibly in different colors):
@@ -82,6 +84,7 @@ section meaning (example)~
<
[...] additional sections (warning/errors/statistics)
from external plugins (e.g. YCM/syntastic/...)
Can be shown on a second line optionally.
For a better look, those sections can be colored differently, depending on
the mode and whether the current file is 'modified'
@@ -124,6 +127,9 @@ values):
" Currently: Enable Vim9 Script implementation
let g:airline_experimental = 1
* enable multiline feature (requires Vim 9.2.0083) >
let g:airline_multiline = 1
* the separator used on the left side >
let g:airline_left_sep='>'
<
@@ -445,6 +451,7 @@ window.
languageclient_error_count)
let g:airline_section_warning (ycm_warning_count, syntastic-warn,
languageclient_warning_count, whitespace)
let g:airline_section_warning2 (whitespace) [optional]
" [*] This section needs at least the fugitive extension or else
" it will remain empty
+3
View File
@@ -203,6 +203,9 @@ function! s:airline_toggle()
endif
endif
endif
if airline#util#has_multiline() && &statuslineopt !~ 'maxheight:'
set statuslineopt+=maxheight:2
endif
if s:airline_initialized
call s:on_window_changed('Init')
endif