Last Updated: February 25, 2016
·
4.226K
· gpakosz

A pretty vim foldtext function

Picture

As shown above, prints the number of folded lines on the right. Supports signs, foldcolumn, nonumber, number and relativenumber.

Here is an excerpt from my .vimrc. Press <Space> to fold. Folds are based on syntax.

if has("folding")
 set foldenable " enable folding
 set foldmethod=syntax " fold based on syntax highlighting
 set foldlevelstart=99 " start editing with all folds open

 " toggle folds
 nnoremap <Space> za
 vnoremap <Space> za

 set foldtext=FoldText()
 function! FoldText()
 let l:lpadding = &fdc
 redir => l:signs
 execute 'silent sign place buffer='.bufnr('%')
 redir End
 let l:lpadding += l:signs =~ 'id=' ? 2 : 0

 if exists("+relativenumber")
 if (&number)
 let l:lpadding += max([&numberwidth, strlen(line('$'))]) + 1
 elseif (&relativenumber)
 let l:lpadding += max([&numberwidth, strlen(v:foldstart - line('w0')), strlen(line('w$') - v:foldstart), strlen(v:foldstart)]) + 1
 endif
 else
 if (&number)
 let l:lpadding += max([&numberwidth, strlen(line('$'))]) + 1
 endif
 endif

 " expand tabs
 let l:start = substitute(getline(v:foldstart), '\t', repeat(' ', &tabstop), 'g')
 let l:end = substitute(substitute(getline(v:foldend), '\t', repeat(' ', &tabstop), 'g'), '^\s*', '', 'g')

 let l:info = ' (' . (v:foldend - v:foldstart) . ')'
 let l:infolen = strlen(substitute(l:info, '.', 'x', 'g'))
 let l:width = winwidth(0) - l:lpadding - l:infolen

 let l:separator = ' … '
 let l:separatorlen = strlen(substitute(l:separator, '.', 'x', 'g'))
 let l:start = strpart(l:start , 0, l:width - strlen(substitute(l:end, '.', 'x', 'g')) - l:separatorlen)
 let l:text = l:start . ' … ' . l:end

 return l:text . repeat(' ', l:width - strlen(substitute(l:text, ".", "x", "g"))) . l:info
 endfunction
endif

2 Responses
Add your response

What does this actually do? Would you add a bit of a description and/or a before/after comparison?

over 1 year ago ·

Sure. Updated

over 1 year ago ·