1- *fold.txt* For Vim version 9.1. Last change: 2023 Mar 24
1+ *fold.txt* For Vim version 9.1. Last change: 2024 Dec 16
22
33
44 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -87,9 +87,11 @@ The most efficient is to call a compiled function without arguments: >
8787 The function must use v:lnum. See | expr-option-function | .
8888
8989These are the conditions with which the expression is evaluated:
90+
9091- The current buffer and window are set for the line.
9192- The variable "v:lnum" is set to the line number.
92- - The result is used for the fold level in this way:
93+
94+ The result of foldexpr then determines the fold level as follows:
9395 value meaning ~
9496 0 the line is not in a fold
9597 1, 2, .. the line is in a fold with this level
@@ -104,6 +106,8 @@ These are the conditions with which the expression is evaluated:
104106 "<1", "<2", .. a fold with this level ends at this line
105107 ">1", ">2", .. a fold with this level starts at this line
106108
109+ The result values "=", "s" and "a" are more expensive, please see | fold-expr-slow | .
110+
107111It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
108112will also start (end) when the fold level is higher (lower) than the fold
109113level of the previous line.
@@ -117,12 +121,6 @@ recognized, there is no error message and the fold level will be zero.
117121For debugging the 'debug' option can be set to "msg", the error messages will
118122be visible then.
119123
120- Note: Since the expression has to be evaluated for every line, this fold
121- method can be very slow!
122-
123- Try to avoid the "=", "a" and "s" return values, since Vim often has to search
124- backwards for a line for which the fold level is defined. This can be slow.
125-
126124If the 'foldexpr' expression starts with s: or | <SID> | , then it is replaced
127125with the script ID (| local-function | ). Examples: >
128126 set foldexpr=s:MyFoldExpr()
@@ -148,6 +146,36 @@ end in that line.
148146It may happen that folds are not updated properly. You can use | zx | or | zX |
149147to force updating folds.
150148
149+ Minimizing Computational Cost *fold-expr-slow*
150+
151+ Due to its computational cost, this fold method can make Vim unresponsive,
152+ especially when the fold level of all lines have to be initially computed.
153+ Afterwards, after each change, Vim restricts the computation of foldlevels
154+ to those lines whose fold level was affected by it (and reuses the known
155+ foldlevels of all the others).
156+
157+ The fold expression should therefore strive to minimize the number of dependent
158+ lines needed for the computation of a given line: For example, try to avoid the
159+ "=", "a" and "s" return values, because these will require the evaluation of the
160+ fold levels on previous lines until an independent fold level is found.
161+
162+ If this proves difficult, the next best thing could be to cache all fold levels
163+ in a buffer-local variable (b:foldlevels) that is only updated on | b:changedtick | :
164+ >vim
165+ vim9script
166+ def MyFoldFunc(): number
167+ if b:lasttick == b:changedtick
168+ return b:foldlevels[v:lnum - 1]
169+ endif
170+ b:lasttick = b:changedtick
171+ b:foldlevels = []
172+ # compute foldlevels ...
173+ return b:foldlevels[v:lnum - 1]
174+ enddef
175+ set foldexpr=s:MyFoldFunc()
176+ <
177+ In above example further speedup was gained by using a precompiled Vim9script
178+ function without arguments (that must still use v:lnum). See | expr-option-function | .
151179
152180SYNTAX *fold-syntax*
153181
0 commit comments