vimtricks.wiki Concise Vim tricks, one at a time.

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=expr recomputes on every file edit; for large files use foldmethod=syntax or indent for better performance
  • Add set foldlevel=99 to start with all folds open after switching to expr mode
  • :set foldmethod=manual temporarily disables expr folding without losing your fold configuration

Next

How do I configure Vim's command-line tab completion to show all matches and complete to the longest common prefix?