builder: bugs in is_empty_section

The current way to parse the statusline content and decide whether a
section is empty, has some flaws:

That is for the following reasons:
- accents are considered to be empty (which they really shouldn't)
- manually parsing the expressions using a
  `:while ... matchlist() ... endwhile` loop is slow and fragile
- grouping items such as %( %) are not considered

So replace the logic by using `substitute('pat', '\=add()', '')` to
capture all single expression groups into a list and then looping over
those to decide whether the section is empty.

fixes #2411
This commit is contained in:
Jeff Pitman 2021-12-28 09:40:20 +01:00 committed by Christian Brabandt
parent 64908db62a
commit 20d77c3220
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09

View File

@ -198,20 +198,22 @@ function! s:section_is_empty(self, content)
if get(w:, 'airline_skip_empty_sections', -1) == 0
return 0
endif
" assume accents sections to be never empty
" (avoides, that on startup the mode message becomes empty)
if match(a:content, '%#__accent_[^#]*#.*__restore__#') > -1
return 0
endif
if empty(a:content)
return 1
endif
let list=matchlist(a:content, '%{\zs.\{-}\ze}', 1, start)
if empty(list)
return 0 " no function in statusline text
let stripped = substitute(a:content,
\ '\(%{.*}\|%#__accent_[^#]*#\|%#__restore__#\|%( \| %)\)', '', 'g')
if !empty(stripped)
return 0 " There is content in the statusline
endif
while len(list) > 0
let expr = list[0]
let exprlist = []
call substitute(a:content, '%{\([^}]*\)}', '\=add(exprlist, submatch(1))', 'g')
for expr in exprlist
try
" catch all exceptions, just in case
if !empty(eval(expr))
@ -220,9 +222,7 @@ function! s:section_is_empty(self, content)
catch
return 0
endtry
let start += 1
let list=matchlist(a:content, '%{\zs.\{-}\ze}', 1, start)
endw
endfor
return 1
endfunction