Home Explore Blog CI



neovim

2nd chunk of `runtime/doc/fold.txt`
6cc7f60aa32465c37eefd00f7751716c4506cdae3bad3d170000000100000fa0

The most efficient is to call a function without arguments: >
	:set foldexpr=MyFoldLevel()
The function must use v:lnum.  See |expr-option-function|.

These are the conditions with which the expression is evaluated:

- The current buffer and window are set for the line.
- The variable "v:lnum" is set to the line number.

The result of foldexpr then determines the fold level as follows:
  value			meaning ~
  0			the line is not in a fold
  1, 2, ..		the line is in a fold with this level
  -1			the fold level is undefined, use the fold level of a
			line before or after this line, whichever is the
			lowest.
  "="			use fold level from the previous line
  "a1", "a2", ..	add one, two, .. to the fold level of the previous
			line, use the result for the current line
  "s1", "s2", ..	subtract one, two, .. from the fold level of the
			previous line, use the result for the next line
  "<1", "<2", ..	a fold with this level ends at this line
  ">1", ">2", ..	a fold with this level starts at this line

The result values "=", "s" and "a" are more expensive, please see
|fold-expr-slow|.

It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
will also start (end) when the fold level is higher (lower) than the fold
level of the previous line.

There must be no side effects from the expression.  The text in the buffer,
cursor position, the search patterns, options etc. must not be changed.
You can change and restore them if you are careful.

If there is some error in the expression, or the resulting value isn't
recognized, there is no error message and the fold level will be zero.
For debugging the 'debug' option can be set to "msg", the error messages will
be visible then.

If the 'foldexpr' expression starts with s: or |<SID>|, then it is replaced
with the script ID (|local-function|).  Examples: >
		set foldexpr=s:MyFoldExpr()
		set foldexpr=<SID>SomeFoldExpr()
<
An example of using "a1" and "s1": For a multi-line C comment, a line
containing "/*" would return "a1" to start a fold, and a line containing "*/"
would return "s1" to end the fold after that line: >
  if match(thisline, '/\*') >= 0
    return 'a1'
  elseif match(thisline, '\*/') >= 0
    return 's1'
  else
    return '='
  endif
However, this won't work for single line comments, strings, etc.

|foldlevel()| can be useful to compute a fold level relative to a previous
fold level.  But note that foldlevel() may return -1 if the level is not known
yet.  And it returns the level at the start of the line, while a fold might
end in that line.

It may happen that folds are not updated properly.  You can use |zx| or |zX|
to force updating folds.

MINIMIZING COMPUTATIONAL COST				*fold-expr-slow*

Due to its computational cost, this fold method can make Vim unresponsive,
especially when the fold level of all lines have to be initially computed.
Afterwards, after each change, Vim restricts the computation of foldlevels
to those lines whose fold level was affected by it (and reuses 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

Title: Expression-Based Folding Details and Optimizations
Summary
This section elaborates on the 'foldexpr' folding method, explaining how to define fold levels using expressions. It outlines the conditions under which the expression is evaluated, the meaning of different return values, and the importance of avoiding side effects. It also discusses how to minimize the computational cost of this method, especially by avoiding dependencies on previous lines and caching fold levels.