VIM Better FoldText
Update 3: Improved the code for extraction of fillchar from
fillchars
option and takingfoldcolumn
into account.
Update 2: Fixed the regex for removing the fold marker from the displayed text by splitting the
'{{{'
in the regex to'{{'. '{'
so that it is not treated as a fold marker by vim. Thanks to Amadan on reddit Reddit Tip
Update: Fixed
NeatFoldText()
to getfoldchar
fromfillchars
settings.
Initially when I started using VIM, I had borrowed configs from my mentor Vagmi Mudumbai (1)To whom I am Eternally Thankful!!! .
He used folding in VIM actively. I on the other hand though, barely got around
using VIM itself, found folding to be quite confusing and hard to work with.
The first folding mapping I learnt was zR
, which is for recursively opening
all folds in the current documents, so I don’t have to deal / worry about
them. I became so habitual to using zR
that one day I decided I was better
off without folding altogether, after all I was clearly not using folding
anyways. That day I removed folding related configs from my ~/.vimrc
. Much
later as I became more comfortable using VIM, I came back to folding and have
not looked back ever since!
I have always thought though that the vim’s default folding look and feel
could use some beautification, and although I have been aware about
foldtext
, I never really got around to understanding how to take advantage
of it to customize things like I wanted.
After quite a bit of effort and quite a few iterations, I now present to you
my NeatFoldText()
, a vim function that makes the fold line look really
impressive, meaningful and ‘neat’ at the same time! It puts focus on what’s
most important
(2)The text in the Start of the fold
.
And right aligns the number of lines in the fold. Also formats it to fixed
size which makes it look neat and consistent.
Put this in your $VIMRC
(3)~/.vimrc
:
function! NeatFoldText()
let line = ' ' . substitute(getline(v:foldstart), '^\s*"\?\s*\|\s*"\?\s*{{' . '{\d*\s*', '', 'g') . ' '
let lines_count = v:foldend - v:foldstart + 1
let lines_count_text = '| ' . printf("%10s", lines_count . ' lines') . ' |'
let foldchar = matchstr(&fillchars, 'fold:\zs.')
let foldtextstart = strpart('+' . repeat(foldchar, v:foldlevel*2) . line, 0, (winwidth(0)*2)/3)
let foldtextend = lines_count_text . repeat(foldchar, 8)
let foldtextlength = strlen(substitute(foldtextstart . foldtextend, '.', 'x', 'g')) + &foldcolumn
return foldtextstart . repeat(foldchar, winwidth(0)-foldtextlength) . foldtextend
endfunction
set foldtext=NeatFoldText()
And this is how the fold text look like :
This example should also prove to be a great starting point for those who wish to tweak the folding text further.