1

In my vim configuration I have a function like

function! StatuslineTrailingSpace()
  if !exists('b:statusline_trailing_space_warning')
    let b:statusline_trailing_space_warning = &modifiable ? search('\s\+$', 'nw') != 0 ? ' %#warningmsg#[\s]%*' : '' : ''
  endif

  return b:statusline_trailing_space_warning
endfunction

and then somewhere later the line

set statusline+=%{StatuslineTrailingSpace()}

But instead of a colored [\s] tag in the statusline I see the full %#warningmsg#[\s]%* string.

Trying to use %! instead of %{} as proposed in this answer does not seem to work as my vim gives the error

line   70:
E539: Illegal character <!>: statusline+=%!StatuslineTrailingSpace()

How can I get the colored statusline working?

Community
  • 1
  • 1
Uroc327
  • 1,379
  • 2
  • 10
  • 28
  • Did you get the difference between `%!` and `%{}`? It looks like you want the `%!` because that's the one that takes the buffer into account. – dash-tom-bang Aug 21 '15 at 20:07
  • @dash-tom-bang I did. But as I've stated in my post, vim gives an error when using `%!`. – Uroc327 Aug 21 '15 at 20:09
  • Yeah I am looking into this now because it's interesting... The docs say, `When the option *starts* with "%!"...` So it may just be that you need to put the whole status line into a function. – dash-tom-bang Aug 21 '15 at 20:16

2 Answers2

2

My suspicion is that you must use the %! construct to get access to the buffer. However, since the docs imply that %! must start at the beginning of the option, your best bet is likely going to be to save off the current statusline and then use your function to return the whole thing.

function! StatuslineTrailingSpace()
  if !exists('b:statusline_trailing_space_warning')
let b:statusline_trailing_space_warning = &modifiable ? search('\s\+$', 'nw') != 0 ? ' %#warningmsg#[\s]%*' : '' : ''
  endif

  return s:former_status_line . b:statusline_trailing_space_warning
endfunction

let s:former_status_line = &statusline
set statusline=%!StatuslineTrailingSpace()

Something like that?

dash-tom-bang
  • 17,383
  • 5
  • 46
  • 62
  • 1
    The hint that `%!` has to stand at the beginning did it for me. I now use a statusline function which concatenates all my strings and functions together and use it via `set statusline=%!Statusline()` – Uroc327 Aug 22 '15 at 10:25
1

The highlight group should be in the 'statusline' option, not in the expression:

function! StatuslineTrailingSpace()
  if !exists('b:stsw')
    let b:stsw = &modifiable ? search('\s\+$', 'nw') != 0 ? ' [\s]' : '' : ''
  endif

  return b:stsw
endfunction

set statusline+=%#warningmsg#%{StatuslineTrailingSpace()}%*
romainl
  • 186,200
  • 21
  • 280
  • 313