&fileencoding
displayed, but I only really care about it if its not "utf-8". In that case I would like it to be highlighted using the "error" highlight group so that I'll be sure to notice it.If you too have jacked off far into the night imagining how much fun you could have with conditionally highlighted statusline flags, then take off your pants, point the pork sword in a safe direction and read this raving immediately.
Note: this raving assumes a fair amount of knowledge about statuslines in vim. If you aren't pro at statuslines then you should read this raving first.
The desired result
In the bottom image, the statusline was set up to display
&fileformat
and &fileencoding
using the "error" highlight if they were anything other than "unix" and "utf-8" respectively.ZOMG how do you do it?!
Unfortunately there is no clean way to do it, but we can easily encapsulate the hacks in a couple of functions.Here is the code that generated the statusline above:
1 "Add the variable with the name a:varName to the statusline. Highlight it as
2 "'error' unless its value is in a:goodValues (a comma separated string)
3 function! AddStatuslineFlag(varName, goodValues)
4 set statusline+=[
5 set statusline+=%#error#
6 exec "set statusline+=%{RenderStlFlag(".a:varName.",'".a:goodValues."',1)}"
7 set statusline+=%*
8 exec "set statusline+=%{RenderStlFlag(".a:varName.",'".a:goodValues."',0)}"
9 set statusline+=]
10 endfunction
11
12 "returns a:value or ''
13 "
14 "a:goodValues is a comma separated string of values that shouldn't be
15 "highlighted with the error group
16 "
17 "a:error indicates whether the string that is returned will be highlighted as
18 "'error'
19 "
20 function! RenderStlFlag(value, goodValues, error)
21 let goodValues = split(a:goodValues, ',')
22 let good = index(goodValues, a:value) != -1
23 if (a:error && !good) || (!a:error && good)
24 return a:value
25 else
26 return ''
27 endif
28 endfunction
29
30 "statusline setup
31 set statusline=%t "tail of the filename
32 call AddStatuslineFlag('&ff', 'unix') "fileformat
33 call AddStatuslineFlag('&fenc', 'utf-8') "file encoding
34 set statusline+=%h "help file flag
35 set statusline+=%m "modified flag
36 set statusline+=%r "read only flag
37 set statusline+=%y "filetype
38 set statusline+=%{StatuslineCurrentHighlight()}
39 set statusline+=%= "left/right separator
40 set statusline+=%c, "cursor column
41 set statusline+=%l/%L "cursor line/total lines
42 set statusline+=\ %P "percent through file
2 "'error' unless its value is in a:goodValues (a comma separated string)
3 function! AddStatuslineFlag(varName, goodValues)
4 set statusline+=[
5 set statusline+=%#error#
6 exec "set statusline+=%{RenderStlFlag(".a:varName.",'".a:goodValues."',1)}"
7 set statusline+=%*
8 exec "set statusline+=%{RenderStlFlag(".a:varName.",'".a:goodValues."',0)}"
9 set statusline+=]
10 endfunction
11
12 "returns a:value or ''
13 "
14 "a:goodValues is a comma separated string of values that shouldn't be
15 "highlighted with the error group
16 "
17 "a:error indicates whether the string that is returned will be highlighted as
18 "'error'
19 "
20 function! RenderStlFlag(value, goodValues, error)
21 let goodValues = split(a:goodValues, ',')
22 let good = index(goodValues, a:value) != -1
23 if (a:error && !good) || (!a:error && good)
24 return a:value
25 else
26 return ''
27 endif
28 endfunction
29
30 "statusline setup
31 set statusline=%t "tail of the filename
32 call AddStatuslineFlag('&ff', 'unix') "fileformat
33 call AddStatuslineFlag('&fenc', 'utf-8') "file encoding
34 set statusline+=%h "help file flag
35 set statusline+=%m "modified flag
36 set statusline+=%r "read only flag
37 set statusline+=%y "filetype
38 set statusline+=%{StatuslineCurrentHighlight()}
39 set statusline+=%= "left/right separator
40 set statusline+=%c, "cursor column
41 set statusline+=%l/%L "cursor line/total lines
42 set statusline+=\ %P "percent through file
This code does two things. First it defines two functions that implement conditionally highlighted statusline flags. Secondly, it sets up the statusline variable, making use of
AddStatusLineFlag()
.How does it work?
A function call like this:call AddStatuslineFlag('&fenc', 'utf-8,latin1')
will cause the following to be added to the
&statusline
variable:[%#error#%{RenderStlFlag(&fenc,'utf-8,latin1',1)}%*%{RenderStlFlag(&fenc,'utf-8,latin1',0)}]
If we break this down we have the following:
[
output a literal "[" char%#error#
switch to the "error" highlight group%{RenderStlFlag(&fenc,'utf-8,latin1',1)}
render &fenc
only if it's not "utf-8" or "latin1".%*
switch back to the normal statusline highlight group%{RenderStlFlag(&fenc,'utf-8,latin1',0)}
render &fenc
only if it is "utf-8" or "latin1".]
output a literal "]" char.The key thing is that
&fenc
will either be rendered inside the error highlight or (exclusive) just outside it.Generalizing...
This exact code wont work for all cases, but we can derive some general guidelines.If you want to highlight something (lets call it
foobar
) X different ways then:- You must define a function to render
foobar
. - You must call the function X times on your statusline, where each call must be highlighted one of the possible ways.
- The function must take an argument to specify which highlight group it is currently rendering for.
- At all times, all but one of the function calls must return an empty string, while the other call must return the value of
foobar
which will appear on the statusline.
I (heart) Clippy
ReplyDeletemy .vimrc - the 1st part ONLY displays when errors are encountered in RED (User? colors must be defined)
ReplyDelete---------------------------------------------------
"at first only return something visual if an error found
set statusline=
set statusline+=\ %1*%r "set color + RO flag
set statusline+=%{&ff!='unix'?'['.&ff.']':''} "display ONLY if &ff != unix
set statusline+=%{(&fenc!='utf-8'&&&fenc!='')?'['.&fenc.']':''} "display ONLY if NOT utf-8
set statusline+=%{&bomb?'[!]':''}
set statusline+=%{StatuslineTabWarning()} "returns mixed, !et, tabs
set statusline+=%{&paste?'[paste]':''} "paste"
set statusline+=%{&modified?'+':''}\ "modified, constant OUTPUT starts here
set statusline+=%*%-40t\ "reset color, filename
set statusline+=%y
set statusline+=%{FileSize()}
set statusline+=[%{&hls?'h':'-'} "highlight search?
set statusline+=%{&is?'i':'-'} "incremental search
set statusline+=%2*%{&sta?'s':'-'} "smarttab
set statusline+=%3*%{&ts}%*%{&sw} "tab/shiftwidth
set statusline+=%4*%{&ai?'a':'-'}%{&si?'i':'-'}%{&cin?'c':'-'} "indent values
set statusline+=%5*%{&wrap?'<':'>'}%6*%{&tw}%*] "wrap/textwidth
set statusline+=%(\ %{VisualSelectionSize()}%)
set statusline+=%=%([%l,%c%)][%L:%p%%]\ "current line