Skip to content

Commit 9054565

Browse files
authored
Merge pull request #1877 from h-east/update-fold
Update fold.{txt,jax}
2 parents 13fbaa9 + 8868f07 commit 9054565

File tree

2 files changed

+86
-26
lines changed

2 files changed

+86
-26
lines changed

doc/fold.jax

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*fold.txt* For Vim バージョン 9.1. Last change: 2023 Mar 24
1+
*fold.txt* For Vim バージョン 9.1. Last change: 2024 Dec 17
22

33

44
VIMリファレンスマニュアル by Bram Moolenaar
@@ -77,18 +77,20 @@
7777
同じ事(「段落」を折り畳みに)をする別の表現: >
7878
:set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1
7979
80-
バックスラッシュ(日本では \ 記号)が ":set" の流儀で、通常とは異なるキャラクタ
81-
(空白文字、バックスラッシュ、ダブルクォート、その他、詳細は|option-backslash|
82-
参照)をエスケープしていることに注意。
80+
Note バックスラッシュ (日本では \ 記号) が ":set" の流儀で、通常とは異なるキャ
81+
ラクタ (空白文字、バックスラッシュ、ダブルクォート、その他、詳細は
82+
|option-backslash| 参照) をエスケープしていることに注意。
8383

8484
最も効果的なのはコンパイル済み関数を引数なしで呼ぶ: >
8585
:set foldexpr=MyFoldLevel()
8686
関数は v:lnum を使用しなくてはいけない。|expr-option-function| を参照。
8787

8888
式が評価される際の前提条件は以下の通り:
89+
8990
- その行について現在のバッファとウィンドウが常に存在している。
9091
- 変数 "v:lnum" には評価対象となる行番号が設定されている。
91-
- 式の結果(戻り値)は以下の形式で折り畳みレベルを示す:
92+
93+
foldexpr の結果によって、以下のように折り畳みレベルが決定される:
9294
値 意味 ~
9395
0 対象行は折り畳みに含まれない
9496
1, 2, .. 対象行はこのレベルの折り畳みに含まれる
@@ -102,6 +104,8 @@
102104
"<1", "<2", .. 指定したレベルの折り畳みを対象行で終了する
103105
">1", ">2", .. 指定したレベルの折り畳みを対象行から開始する
104106

107+
結果の値 "="、"s" および "a" はより高価である。|fold-expr-slow| を参照。
108+
105109
折り畳みは直前の行の折り畳みレベルより高い(低い)行から開始(終了)されるので、折
106110
り畳みの開始 (終了)マーク ">1" ("<1") は明示的に指定する必要は無い。
107111

@@ -113,13 +117,6 @@
113117
折り畳みレベルは0に設定される。'debug' オプションに "msg" を設定すれば、エラー
114118
メッセージが表示されるようになるので、デバッグに利用できる。
115119

116-
NOTE: 各行について式評価が実行されるので、この折り畳み方式は非常に動作が遅くな
117-
る可能性がある!
118-
119-
"=", "a", そして "s" は極力避けるようにする。なぜならVimはそれらが使われると、
120-
折り畳みレベルが定義された行が見つかるまで戻って、幾度も検索を行わなければなら
121-
ないからだ。これは動作が遅くなることがある。
122-
123120
'foldexpr' の式が s: か |<SID>| で始まる場合、スクリプトID(|local-function|)
124121
に置き換えられる。例: >
125122
set foldexpr=s:MyFoldExpr()
@@ -144,6 +141,37 @@ NOTE: 各行について式評価が実行されるので、この折り畳み
144141
折り畳みが適切に更新されない場合がある。その場合は |zx||zX| を使って強制的
145142
に更新すること。
146143

144+
☆計算コストの最小化 *fold-expr-slow*
145+
146+
この折り畳み方式は計算コストが高いため、特にすべての行の折り畳みレベルを最初に
147+
計算する必要がある場合、Vim が応答しなくなる可能性がある。
148+
その後、各変更の後に Vim は折り畳みレベルの計算を折り畳みレベルが影響を受けた
149+
行に制限する (他のすべての行の既知の折り畳みレベルを再利用する)。
150+
151+
したがって、折り畳み式は特定の行の計算に必要な依存行の数を最小限に抑えるように
152+
努める必要がある。例えば、独立した折り畳みレベルが見つかるまで前の行の折り畳み
153+
レベルの評価が必要になるため、"="、"a" および "s" の戻り値を避けるようにするこ
154+
と。
155+
156+
これが難しい場合は、次善策として |b:changedtick| でのみ更新されるバッファロー
157+
カル変数 (b:foldlevels) にすべての折り畳みレベルをキャッシュすることが考えられ
158+
る:
159+
>vim
160+
vim9script
161+
def MyFoldFunc(): number
162+
if b:lasttick == b:changedtick
163+
return b:foldlevels[v:lnum - 1]
164+
endif
165+
b:lasttick = b:changedtick
166+
b:foldlevels = []
167+
# compute foldlevels ...
168+
return b:foldlevels[v:lnum - 1]
169+
enddef
170+
set foldexpr=s:MyFoldFunc()
171+
<
172+
上記の例では、プリコンパイルされた引数なしの Vim9 script 関数を使用することで、
173+
さらに高速化された (それでも v:lnum を使用する必要がある)。
174+
|expr-option-function| を参照。
147175

148176
☆構文 *fold-syntax*
149177

@@ -446,7 +474,7 @@ zk カーソルより上方の折り畳みへ移動する。閉じられた折
446474

447475
折り畳みに対してコマンドを実行する ~
448476

449-
:[range]foldd[oopen] {cmd} *:foldd* *:folddo* *:folddoopen*
477+
:[range]foldd[oopen] {cmd} *:foldd* *:folddo* *:folddoopen*
450478
閉じた折り畳みの中以外の全ての行に対して{cmd}を実行する。
451479
[range]が与えられた時は、その範囲だけが対象となる。
452480
コマンドが各行に対して実行される時にはカーソルはその対象となる

en/fold.txt

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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

8989
These 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+
107112
It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
108113
will also start (end) when the fold level is higher (lower) than the fold
109114
level of the previous line.
@@ -117,14 +122,8 @@ recognized, there is no error message and the fold level will be zero.
117122
For debugging the 'debug' option can be set to "msg", the error messages will
118123
be 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-
126125
If 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.
148147
It may happen that folds are not updated properly. You can use |zx| or |zX|
149148
to 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

152184
SYNTAX *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

450482
EXECUTING 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
539571
by 'fillchars'.
540572

541573
If 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

Comments
 (0)