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 17
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,9 @@ 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
110+ | fold-expr-slow | .
111+
107112It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
108113will also start (end) when the fold level is higher (lower) than the fold
109114level of the previous line.
@@ -117,14 +122,8 @@ recognized, there is no error message and the fold level will be zero.
117122For debugging the 'debug' option can be set to "msg", the error messages will
118123be visible then.
119124
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-
126125If the 'foldexpr' expression starts with s: or | <SID> | , then it is replaced
127- with the script ID (| local-function | ). Examples: >
126+ with the script ID (| local-function | ). Examples: >
128127 set foldexpr=s:MyFoldExpr()
129128 set foldexpr=<SID>SomeFoldExpr()
130129<
@@ -148,6 +147,39 @@ end in that line.
148147It may happen that folds are not updated properly. You can use | zx | or | zX |
149148to force updating folds.
150149
150+ MINIMIZING COMPUTATIONAL COST *fold-expr-slow*
151+
152+ Due to its computational cost, this fold method can make Vim unresponsive,
153+ especially when the fold level of all lines have to be initially computed.
154+ Afterwards, after each change, Vim restricts the computation of foldlevels
155+ to those lines whose fold level was affected by it (and reuses the known
156+ foldlevels of all the others).
157+
158+ The fold expression should therefore strive to minimize the number of
159+ dependent lines needed for the computation of a given line: For example, try
160+ to avoid the "=", "a" and "s" return values, because these will require the
161+ evaluation of the fold levels on previous lines until an independent fold
162+ level is found.
163+
164+ If this proves difficult, the next best thing could be to cache all fold
165+ levels in a buffer-local variable (b:foldlevels) that is only updated on
166+ | b:changedtick | :
167+ >vim
168+ vim9script
169+ def MyFoldFunc(): number
170+ if b:lasttick == b:changedtick
171+ return b:foldlevels[v:lnum - 1]
172+ endif
173+ b:lasttick = b:changedtick
174+ b:foldlevels = []
175+ # compute foldlevels ...
176+ return b:foldlevels[v:lnum - 1]
177+ enddef
178+ set foldexpr=s:MyFoldFunc()
179+ <
180+ In above example further speedup was gained by using a precompiled Vim9 script
181+ function without arguments (that must still use v:lnum). See
182+ | expr-option-function | .
151183
152184SYNTAX *fold-syntax*
153185
@@ -384,8 +416,8 @@ zX Undo manually opened and closed folds: re-apply 'foldlevel'.
384416 Also forces recomputing folds, like | zx | .
385417
386418 *zm*
387- zm Fold more: Subtract | v:count1 | from 'foldlevel' . If 'foldlevel' was
388- already zero nothing happens.
419+ zm Fold more: Subtract | v:count1 | from 'foldlevel' . If
420+ 'foldlevel' was already zero nothing happens.
389421 'foldenable' will be set.
390422
391423 *zM*
@@ -449,7 +481,7 @@ zk Move upwards to the end of the previous fold. A closed fold
449481
450482EXECUTING COMMANDS ON FOLDS ~
451483
452- :[range] foldd[oopen] {cmd} *:foldd* *:folddo* *:folddoopen*
484+ :[range] foldd[oopen] {cmd} *:foldd* *:folddo* *:folddoopen*
453485 Execute {cmd} on all lines that are not in a closed fold.
454486 When [range] is given, only these lines are used.
455487 Each time {cmd} is executed the cursor is positioned on the
@@ -539,7 +571,7 @@ When there is room after the text, it is filled with the character specified
539571by 'fillchars' .
540572
541573If the 'foldtext' expression starts with s: or | <SID> | , then it is replaced
542- with the script ID (| local-function | ). Examples: >
574+ with the script ID (| local-function | ). Examples: >
543575 set foldtext=s:MyFoldText()
544576 set foldtext=<SID>SomeFoldText()
545577<
0 commit comments