the known
foldlevels of all the others).
The fold expression should therefore strive to minimize the number of
dependent lines needed for the computation of a given line: For example, try
to avoid the "=", "a" and "s" return values, because these will require the
evaluation of the fold levels on previous lines until an independent fold
level is found.
If this proves difficult, the next best thing could be to cache all fold
levels in a buffer-local variable (b:foldlevels) that is only updated on
|b:changedtick|:
>vim
func MyFoldFunc()
if b:lasttick == b:changedtick
return b:foldlevels[v:lnum - 1]
endif
let b:lasttick = b:changedtick
let b:foldlevels = []
" compute foldlevels ...
return b:foldlevels[v:lnum - 1]
enddef
set foldexpr=s:MyFoldFunc()
<
In above example further speedup was gained by using a function without
arguments (that must still use v:lnum). See |expr-option-function|.
SYNTAX *fold-syntax*
A fold is defined by syntax items that have the "fold" argument. |:syn-fold|
The fold level is defined by nesting folds. The nesting of folds is limited
with 'foldnestmax'.
Be careful to specify proper syntax syncing. If this is not done right, folds
may differ from the displayed highlighting. This is especially relevant when
using patterns that match more than one line. In case of doubt, try using
brute-force syncing: >
:syn sync fromstart
DIFF *fold-diff*
The folds are automatically defined for text that is not part of a change or
close to a change.
This method only works properly when the 'diff' option is set for the current
window and changes are being displayed. Otherwise the whole buffer will be
one big fold.
The 'diffopt' option can be used to specify the context. That is, the number
of lines between the fold and a change that are not included in the fold. For
example, to use a context of 8 lines: >
:set diffopt=filler,context:8
The default context is six lines.
When 'scrollbind' is also set, Vim will attempt to keep the same folds open in
other diff windows, so that the same text is visible.
MARKER *fold-marker*
Markers in the text tell where folds start and end. This allows you to
precisely specify the folds. This will allow deleting and putting a fold,
without the risk of including the wrong lines. The 'foldtext' option is
normally set such that the text before the marker shows up in the folded line.
This makes it possible to give a name to the fold.
Markers can have a level included, or can use matching pairs. Including a
level is easier, you don't have to add end markers and avoid problems with
non-matching marker pairs. Example: >
/* global variables {{{1 */
int varA, varB;
/* functions {{{1 */
/* funcA() {{{2 */
void funcA() {}
/* funcB() {{{2 */
void funcB() {}
< *{{{* *}}}*
A fold starts at a "{{{" marker. The following number specifies the fold
level. What happens depends on the difference between the current fold level
and the level given by the marker:
1. If a marker with the same fold level is encountered, the previous fold
ends and another fold with the same level starts.
2. If a marker with a higher fold level is found, a nested fold is started.
3. If a marker with a lower fold level is found, all folds up to and including
this level end and a fold with the specified level starts.
The number indicates the fold level. A zero cannot be used (a marker with
level zero is ignored). You can use "}}}" with a digit to indicate the level
of the fold that ends. The fold level of the following line will be one less
than the indicated level. Note that Vim doesn't look back to the level of the
matching marker (that would take too much time). Example: >
{{{1
fold level here is 1
{{{3
fold level here is 3
}}}3
fold level here is 2
You can also use matching pairs of "{{{" and "}}}" markers to define folds.
Each "{{{" increases the fold level by one, each "}}}" decreases the fold
level by one. Be careful to