runtime(doc): document how to minimize fold computation costs
Commit:
https://github.com/vim/vim/commit/3920bb4356aa7324a4be1071c87524a2f921d921
Author: Konfekt <[email protected]>
Date: Mon Dec 16 21:10:45 2024 +0100
runtime(doc): document how to minimize fold computation costs
closes: https://github.com/vim/vim/issues/16224
Signed-off-by: Konfekt <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/runtime/doc/fold.txt b/runtime/doc/fold.txt
index b29049205..61f3b67f3 100644
--- a/runtime/doc/fold.txt
+++ b/runtime/doc/fold.txt
@@ -1,4 +1,4 @@
-*fold.txt* For Vim version 9.1. Last change: 2023 Mar 24
+*fold.txt* For Vim version 9.1. Last change: 2024 Dec 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -87,9 +87,11 @@ The most efficient is to call a compiled function without
arguments: >
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 is used for the fold level in this way:
+
+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
@@ -104,6 +106,8 @@ These are the conditions with which the expression is
evaluated:
"<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.
@@ -117,12 +121,6 @@ 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.
-Note: Since the expression has to be evaluated for every line, this fold
-method can be very slow!
-
-Try to avoid the "=", "a" and "s" return values, since Vim often has to search
-backwards for a line for which the fold level is defined. This can be slow.
-
If the 'foldexpr' expression starts with s: or |<SID>|, then it is replaced
with the script ID (|local-function|). Examples: >
set foldexpr=s:MyFoldExpr()
@@ -148,6 +146,36 @@ 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
+ vim9script
+ def MyFoldFunc(): number
+ if b:lasttick == b:changedtick
+ return b:foldlevels[v:lnum - 1]
+ endif
+ b:lasttick = b:changedtick
+ 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 precompiled Vim9script
+function without arguments (that must still use v:lnum). See
|expr-option-function|.
SYNTAX *fold-syntax*
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 0f8b2051f..9f46c6e06 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -7218,6 +7218,7 @@ fold-create-marker fold.txt
/*fold-create-marker*
fold-delete-marker fold.txt /*fold-delete-marker*
fold-diff fold.txt /*fold-diff*
fold-expr fold.txt /*fold-expr*
+fold-expr-slow fold.txt /*fold-expr-slow*
fold-foldcolumn fold.txt /*fold-foldcolumn*
fold-foldlevel fold.txt /*fold-foldlevel*
fold-foldtext fold.txt /*fold-foldtext*
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1tNHUe-000reM-MA%40256bit.org.