How do I define custom fold boundaries using a Vimscript expression in Vim?
Answer
:set foldmethod=expr
Explanation
Setting foldmethod=expr tells Vim to call the foldexpr expression for every line to compute its fold level. This gives you full programmatic control over folding — you can fold based on any line content, prefix, pattern, or surrounding context.
How it works
With foldmethod=expr, Vim evaluates foldexpr for each line number (available as v:lnum). The expression must return:
- A number: the absolute fold level for that line
'=': same fold level as the previous line'a1','s1', etc.: increase/decrease fold level
Example
Fold Markdown by heading level (lines starting with #):
set foldmethod=expr
set foldexpr=v:lnum==1?0:getline(v:lnum)=~'^#'?'>1':'='
This creates a fold boundary at every line beginning with #, making each section collapsible.
For shell scripts, fold by function definitions:
set foldmethod=expr
set foldexpr=getline(v:lnum)=~'^\\w.*()\\s*{$'?'>1':getline(v:lnum)==='}'?'<1':'='
Tips
- For complex logic, define a function and reference it:
:set foldexpr=MyFoldExpr(v:lnum) foldmethod=exprrecomputes on every file edit; for large files usefoldmethod=syntaxorindentfor better performance- Add
set foldlevel=99to start with all folds open after switching to expr mode :set foldmethod=manualtemporarily disables expr folding without losing your fold configuration