h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 1 | *fold.txt* For Vim version 9.1. Last change: 2024 Dec 17 |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 2 | |
| 3 | |
| 4 | VIM REFERENCE MANUAL by Bram Moolenaar |
| 5 | |
| 6 | |
Bram Moolenaar | 8f3f58f | 2010-01-06 20:52:26 +0100 | [diff] [blame] | 7 | Folding *Folding* *folding* *folds* |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 8 | |
| 9 | You can find an introduction on folding in chapter 28 of the user manual. |
| 10 | |usr_28.txt| |
| 11 | |
| 12 | 1. Fold methods |fold-methods| |
| 13 | 2. Fold commands |fold-commands| |
| 14 | 3. Fold options |fold-options| |
| 15 | 4. Behavior of folds |fold-behavior| |
| 16 | |
Bram Moolenaar | db84e45 | 2010-08-15 13:50:43 +0200 | [diff] [blame] | 17 | {not available when compiled without the |+folding| feature} |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 18 | |
| 19 | ============================================================================== |
| 20 | 1. Fold methods *fold-methods* |
| 21 | |
| 22 | The folding method can be set with the 'foldmethod' option. |
| 23 | |
| 24 | When setting 'foldmethod' to a value other than "manual", all folds are |
| 25 | deleted and new ones created. Switching to the "manual" method doesn't remove |
| 26 | the existing folds. This can be used to first define the folds automatically |
| 27 | and then change them manually. |
| 28 | |
| 29 | There are six methods to select folds: |
| 30 | manual manually define folds |
| 31 | indent more indent means a higher fold level |
| 32 | expr specify an expression to define folds |
| 33 | syntax folds defined by syntax highlighting |
| 34 | diff folds for unchanged text |
| 35 | marker folds defined by markers in the text |
| 36 | |
| 37 | |
| 38 | MANUAL *fold-manual* |
| 39 | |
| 40 | Use commands to manually define the fold regions. This can also be used by a |
| 41 | script that parses text to find folds. |
| 42 | |
| 43 | The level of a fold is only defined by its nesting. To increase the fold |
| 44 | level of a fold for a range of lines, define a fold inside it that has the |
| 45 | same lines. |
| 46 | |
| 47 | The manual folds are lost when you abandon the file. To save the folds use |
| 48 | the |:mkview| command. The view can be restored later with |:loadview|. |
| 49 | |
| 50 | |
| 51 | INDENT *fold-indent* |
| 52 | |
| 53 | The folds are automatically defined by the indent of the lines. |
| 54 | |
| 55 | The foldlevel is computed from the indent of the line, divided by the |
| 56 | 'shiftwidth' (rounded down). A sequence of lines with the same or higher fold |
| 57 | level form a fold, with the lines with a higher level forming a nested fold. |
| 58 | |
| 59 | The nesting of folds is limited with 'foldnestmax'. |
| 60 | |
| 61 | Some lines are ignored and get the fold level of the line above or below it, |
Bram Moolenaar | 446beb4 | 2011-05-10 17:18:44 +0200 | [diff] [blame] | 62 | whichever is lower. These are empty or white lines and lines starting |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 63 | with a character in 'foldignore'. White space is skipped before checking for |
| 64 | characters in 'foldignore'. For C use "#" to ignore preprocessor lines. |
| 65 | |
Bram Moolenaar | 214641f | 2017-03-05 17:04:09 +0100 | [diff] [blame] | 66 | When you want to ignore lines in another way, use the "expr" method. The |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 67 | |indent()| function can be used in 'foldexpr' to get the indent of a line. |
| 68 | |
| 69 | |
| 70 | EXPR *fold-expr* |
| 71 | |
| 72 | The folds are automatically defined by their foldlevel, like with the "indent" |
| 73 | method. The value of the 'foldexpr' option is evaluated to get the foldlevel |
| 74 | of a line. Examples: |
Bram Moolenaar | 666771a | 2007-05-12 14:03:30 +0000 | [diff] [blame] | 75 | This will create a fold for all consecutive lines that start with a tab: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 76 | :set foldexpr=getline(v:lnum)[0]==\"\\t\" |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 77 | This will make a fold out of paragraphs separated by blank lines: > |
| 78 | :set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1 |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 79 | This does the same: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 80 | :set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1 |
| 81 | |
| 82 | Note that backslashes must be used to escape characters that ":set" handles |
| 83 | differently (space, backslash, double quote, etc., see |option-backslash|). |
| 84 | |
Bram Moolenaar | 87b4e5c | 2022-10-01 15:32:46 +0100 | [diff] [blame] | 85 | The most efficient is to call a compiled function without arguments: > |
| 86 | :set foldexpr=MyFoldLevel() |
| 87 | The function must use v:lnum. See |expr-option-function|. |
| 88 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 89 | These are the conditions with which the expression is evaluated: |
Konfekt | 3920bb4 | 2024-12-16 21:10:45 +0100 | [diff] [blame] | 90 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 91 | - The current buffer and window are set for the line. |
| 92 | - The variable "v:lnum" is set to the line number. |
Konfekt | 3920bb4 | 2024-12-16 21:10:45 +0100 | [diff] [blame] | 93 | |
| 94 | The result of foldexpr then determines the fold level as follows: |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 95 | value meaning ~ |
| 96 | 0 the line is not in a fold |
| 97 | 1, 2, .. the line is in a fold with this level |
| 98 | -1 the fold level is undefined, use the fold level of a |
| 99 | line before or after this line, whichever is the |
| 100 | lowest. |
| 101 | "=" use fold level from the previous line |
| 102 | "a1", "a2", .. add one, two, .. to the fold level of the previous |
Bram Moolenaar | d042dc8 | 2015-11-24 19:18:36 +0100 | [diff] [blame] | 103 | line, use the result for the current line |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 104 | "s1", "s2", .. subtract one, two, .. from the fold level of the |
Bram Moolenaar | d042dc8 | 2015-11-24 19:18:36 +0100 | [diff] [blame] | 105 | previous line, use the result for the next line |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 106 | "<1", "<2", .. a fold with this level ends at this line |
| 107 | ">1", ">2", .. a fold with this level starts at this line |
| 108 | |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 109 | The result values "=", "s" and "a" are more expensive, please see |
| 110 | |fold-expr-slow|. |
Konfekt | 3920bb4 | 2024-12-16 21:10:45 +0100 | [diff] [blame] | 111 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 112 | It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold |
| 113 | will also start (end) when the fold level is higher (lower) than the fold |
| 114 | level of the previous line. |
| 115 | |
| 116 | There must be no side effects from the expression. The text in the buffer, |
| 117 | cursor position, the search patterns, options etc. must not be changed. |
Bram Moolenaar | e2f98b9 | 2006-03-29 21:18:24 +0000 | [diff] [blame] | 118 | You can change and restore them if you are careful. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 119 | |
| 120 | If there is some error in the expression, or the resulting value isn't |
| 121 | recognized, there is no error message and the fold level will be zero. |
| 122 | For debugging the 'debug' option can be set to "msg", the error messages will |
| 123 | be visible then. |
| 124 | |
Yegappan Lakshmanan | 8bb65f2 | 2021-12-26 10:51:39 +0000 | [diff] [blame] | 125 | If the 'foldexpr' expression starts with s: or |<SID>|, then it is replaced |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 126 | with the script ID (|local-function|). Examples: > |
Yegappan Lakshmanan | 8bb65f2 | 2021-12-26 10:51:39 +0000 | [diff] [blame] | 127 | set foldexpr=s:MyFoldExpr() |
| 128 | set foldexpr=<SID>SomeFoldExpr() |
| 129 | < |
Bram Moolenaar | d042dc8 | 2015-11-24 19:18:36 +0100 | [diff] [blame] | 130 | An example of using "a1" and "s1": For a multi-line C comment, a line |
| 131 | containing "/*" would return "a1" to start a fold, and a line containing "*/" |
| 132 | would return "s1" to end the fold after that line: > |
| 133 | if match(thisline, '/\*') >= 0 |
| 134 | return 'a1' |
| 135 | elseif match(thisline, '\*/') >= 0 |
| 136 | return 's1' |
| 137 | else |
| 138 | return '=' |
| 139 | endif |
| 140 | However, this won't work for single line comments, strings, etc. |
| 141 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 142 | |foldlevel()| can be useful to compute a fold level relative to a previous |
| 143 | fold level. But note that foldlevel() may return -1 if the level is not known |
| 144 | yet. And it returns the level at the start of the line, while a fold might |
| 145 | end in that line. |
| 146 | |
Bram Moolenaar | 214641f | 2017-03-05 17:04:09 +0100 | [diff] [blame] | 147 | It may happen that folds are not updated properly. You can use |zx| or |zX| |
Bram Moolenaar | 00a927d | 2010-05-14 23:24:24 +0200 | [diff] [blame] | 148 | to force updating folds. |
| 149 | |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 150 | MINIMIZING COMPUTATIONAL COST *fold-expr-slow* |
Konfekt | 3920bb4 | 2024-12-16 21:10:45 +0100 | [diff] [blame] | 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 | |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 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. |
Konfekt | 3920bb4 | 2024-12-16 21:10:45 +0100 | [diff] [blame] | 163 | |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 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|: |
Konfekt | 3920bb4 | 2024-12-16 21:10:45 +0100 | [diff] [blame] | 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 | < |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 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|. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 183 | |
| 184 | SYNTAX *fold-syntax* |
| 185 | |
| 186 | A fold is defined by syntax items that have the "fold" argument. |:syn-fold| |
| 187 | |
| 188 | The fold level is defined by nesting folds. The nesting of folds is limited |
| 189 | with 'foldnestmax'. |
| 190 | |
| 191 | Be careful to specify proper syntax syncing. If this is not done right, folds |
| 192 | may differ from the displayed highlighting. This is especially relevant when |
| 193 | using patterns that match more than one line. In case of doubt, try using |
| 194 | brute-force syncing: > |
| 195 | :syn sync fromstart |
| 196 | |
| 197 | |
| 198 | DIFF *fold-diff* |
| 199 | |
| 200 | The folds are automatically defined for text that is not part of a change or |
| 201 | close to a change. |
| 202 | |
| 203 | This method only works properly when the 'diff' option is set for the current |
| 204 | window and changes are being displayed. Otherwise the whole buffer will be |
| 205 | one big fold. |
| 206 | |
| 207 | The 'diffopt' option can be used to specify the context. That is, the number |
| 208 | of lines between the fold and a change that are not included in the fold. For |
| 209 | example, to use a context of 8 lines: > |
| 210 | :set diffopt=filler,context:8 |
| 211 | The default context is six lines. |
| 212 | |
| 213 | When 'scrollbind' is also set, Vim will attempt to keep the same folds open in |
| 214 | other diff windows, so that the same text is visible. |
| 215 | |
| 216 | |
| 217 | MARKER *fold-marker* |
| 218 | |
| 219 | Markers in the text tell where folds start and end. This allows you to |
| 220 | precisely specify the folds. This will allow deleting and putting a fold, |
| 221 | without the risk of including the wrong lines. The 'foldtext' option is |
| 222 | normally set such that the text before the marker shows up in the folded line. |
| 223 | This makes it possible to give a name to the fold. |
| 224 | |
| 225 | Markers can have a level included, or can use matching pairs. Including a |
| 226 | level is easier, you don't have to add end markers and avoid problems with |
| 227 | non-matching marker pairs. Example: > |
| 228 | /* global variables {{{1 */ |
| 229 | int varA, varB; |
| 230 | |
| 231 | /* functions {{{1 */ |
| 232 | /* funcA() {{{2 */ |
| 233 | void funcA() {} |
| 234 | |
| 235 | /* funcB() {{{2 */ |
| 236 | void funcB() {} |
Bram Moolenaar | be4e016 | 2023-02-02 13:59:48 +0000 | [diff] [blame] | 237 | < *{{{* *}}}* |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 238 | A fold starts at a "{{{" marker. The following number specifies the fold |
| 239 | level. What happens depends on the difference between the current fold level |
| 240 | and the level given by the marker: |
| 241 | 1. If a marker with the same fold level is encountered, the previous fold |
| 242 | ends and another fold with the same level starts. |
| 243 | 2. If a marker with a higher fold level is found, a nested fold is started. |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 244 | 3. If a marker with a lower fold level is found, all folds up to and including |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 245 | this level end and a fold with the specified level starts. |
| 246 | |
Bram Moolenaar | 009b259 | 2004-10-24 19:18:58 +0000 | [diff] [blame] | 247 | The number indicates the fold level. A zero cannot be used (a marker with |
| 248 | level zero is ignored). You can use "}}}" with a digit to indicate the level |
| 249 | of the fold that ends. The fold level of the following line will be one less |
| 250 | than the indicated level. Note that Vim doesn't look back to the level of the |
| 251 | matching marker (that would take too much time). Example: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 252 | |
| 253 | {{{1 |
| 254 | fold level here is 1 |
| 255 | {{{3 |
| 256 | fold level here is 3 |
| 257 | }}}3 |
| 258 | fold level here is 2 |
| 259 | |
| 260 | You can also use matching pairs of "{{{" and "}}}" markers to define folds. |
| 261 | Each "{{{" increases the fold level by one, each "}}}" decreases the fold |
| 262 | level by one. Be careful to keep the markers matching! Example: > |
| 263 | |
| 264 | {{{ |
| 265 | fold level here is 1 |
| 266 | {{{ |
| 267 | fold level here is 2 |
| 268 | }}} |
| 269 | fold level here is 1 |
| 270 | |
| 271 | You can mix using markers with a number and without a number. A useful way of |
| 272 | doing this is to use numbered markers for large folds, and unnumbered markers |
| 273 | locally in a function. For example use level one folds for the sections of |
| 274 | your file like "structure definitions", "local variables" and "functions". |
| 275 | Use level 2 markers for each definition and function, Use unnumbered markers |
| 276 | inside functions. When you make changes in a function to split up folds, you |
| 277 | don't have to renumber the markers. |
| 278 | |
| 279 | The markers can be set with the 'foldmarker' option. It is recommended to |
| 280 | keep this at the default value of "{{{,}}}", so that files can be exchanged |
| 281 | between Vim users. Only change it when it is required for the file (e.g., it |
| 282 | contains markers from another folding editor, or the default markers cause |
| 283 | trouble for the language of the file). |
| 284 | |
| 285 | *fold-create-marker* |
| 286 | "zf" can be used to create a fold defined by markers. Vim will insert the |
| 287 | markers for you. Vim will append the start and end marker, as specified with |
| 288 | 'foldmarker'. The markers are appended to the end of the line. |
| 289 | 'commentstring' is used if it isn't empty. |
| 290 | This does not work properly when: |
| 291 | - The line already contains a marker with a level number. Vim then doesn't |
| 292 | know what to do. |
| 293 | - Folds nearby use a level number in their marker which gets in the way. |
| 294 | - The line is inside a comment, 'commentstring' isn't empty and nested |
| 295 | comments don't work. For example with C: adding /* {{{ */ inside a comment |
| 296 | will truncate the existing comment. Either put the marker before or after |
| 297 | the comment, or add the marker manually. |
| 298 | Generally it's not a good idea to let Vim create markers when you already have |
| 299 | markers with a level number. |
| 300 | |
| 301 | *fold-delete-marker* |
| 302 | "zd" can be used to delete a fold defined by markers. Vim will delete the |
| 303 | markers for you. Vim will search for the start and end markers, as specified |
| 304 | with 'foldmarker', at the start and end of the fold. When the text around the |
| 305 | marker matches with 'commentstring', that text is deleted as well. |
| 306 | This does not work properly when: |
| 307 | - A line contains more than one marker and one of them specifies a level. |
| 308 | Only the first one is removed, without checking if this will have the |
| 309 | desired effect of deleting the fold. |
| 310 | - The marker contains a level number and is used to start or end several folds |
| 311 | at the same time. |
| 312 | |
| 313 | ============================================================================== |
| 314 | 2. Fold commands *fold-commands* *E490* |
| 315 | |
| 316 | All folding commands start with "z". Hint: the "z" looks like a folded piece |
| 317 | of paper, if you look at it from the side. |
| 318 | |
| 319 | |
| 320 | CREATING AND DELETING FOLDS ~ |
| 321 | *zf* *E350* |
| 322 | zf{motion} or |
| 323 | {Visual}zf Operator to create a fold. |
| 324 | This only works when 'foldmethod' is "manual" or "marker". |
| 325 | The new fold will be closed for the "manual" method. |
| 326 | 'foldenable' will be set. |
| 327 | Also see |fold-create-marker|. |
| 328 | |
| 329 | *zF* |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 330 | zF Create a fold for [count] lines. Works like "zf". |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 331 | |
| 332 | :{range}fo[ld] *:fold* *:fo* |
| 333 | Create a fold for the lines in {range}. Works like "zf". |
| 334 | |
| 335 | *zd* *E351* |
Bram Moolenaar | 8169525 | 2004-12-29 20:58:21 +0000 | [diff] [blame] | 336 | zd Delete one fold at the cursor. When the cursor is on a folded |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 337 | line, that fold is deleted. Nested folds are moved one level |
Bram Moolenaar | dfb1841 | 2013-12-11 18:53:29 +0100 | [diff] [blame] | 338 | up. In Visual mode one level of all folds (partially) in the |
| 339 | selected area are deleted. |
| 340 | Careful: This easily deletes more folds than you expect and |
| 341 | there is no undo for manual folding. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 342 | This only works when 'foldmethod' is "manual" or "marker". |
| 343 | Also see |fold-delete-marker|. |
| 344 | |
| 345 | *zD* |
| 346 | zD Delete folds recursively at the cursor. In Visual mode all |
| 347 | folds (partially) in the selected area and all nested folds in |
| 348 | them are deleted. |
| 349 | This only works when 'foldmethod' is "manual" or "marker". |
| 350 | Also see |fold-delete-marker|. |
| 351 | |
| 352 | *zE* *E352* |
| 353 | zE Eliminate all folds in the window. |
| 354 | This only works when 'foldmethod' is "manual" or "marker". |
| 355 | Also see |fold-delete-marker|. |
| 356 | |
| 357 | |
| 358 | OPENING AND CLOSING FOLDS ~ |
| 359 | |
| 360 | A fold smaller than 'foldminlines' will always be displayed like it was open. |
| 361 | Therefore the commands below may work differently on small folds. |
| 362 | |
| 363 | *zo* |
| 364 | zo Open one fold under the cursor. When a count is given, that |
| 365 | many folds deep will be opened. In Visual mode one level of |
| 366 | folds is opened for all lines in the selected area. |
| 367 | |
| 368 | *zO* |
| 369 | zO Open all folds under the cursor recursively. Folds that don't |
| 370 | contain the cursor line are unchanged. |
| 371 | In Visual mode it opens all folds that are in the selected |
| 372 | area, also those that are only partly selected. |
| 373 | |
| 374 | *zc* |
| 375 | zc Close one fold under the cursor. When a count is given, that |
| 376 | many folds deep are closed. In Visual mode one level of folds |
| 377 | is closed for all lines in the selected area. |
| 378 | 'foldenable' will be set. |
| 379 | |
| 380 | *zC* |
| 381 | zC Close all folds under the cursor recursively. Folds that |
| 382 | don't contain the cursor line are unchanged. |
| 383 | In Visual mode it closes all folds that are in the selected |
| 384 | area, also those that are only partly selected. |
| 385 | 'foldenable' will be set. |
| 386 | |
| 387 | *za* |
Bram Moolenaar | 71badf9 | 2023-04-22 22:40:14 +0100 | [diff] [blame] | 388 | za Summary: Toggle the fold under the cursor. |
| 389 | When on a closed fold: open it. When folds are nested, you |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 390 | may have to use "za" several times. When a count is given, |
| 391 | that many closed folds are opened. |
| 392 | When on an open fold: close it and set 'foldenable'. This |
| 393 | will only close one level, since using "za" again will open |
| 394 | the fold. When a count is given that many folds will be |
| 395 | closed (that's not the same as repeating "za" that many |
| 396 | times). |
| 397 | |
| 398 | *zA* |
| 399 | zA When on a closed fold: open it recursively. |
| 400 | When on an open fold: close it recursively and set |
| 401 | 'foldenable'. |
| 402 | |
| 403 | *zv* |
| 404 | zv View cursor line: Open just enough folds to make the line in |
| 405 | which the cursor is located not folded. |
| 406 | |
| 407 | *zx* |
| 408 | zx Update folds: Undo manually opened and closed folds: re-apply |
| 409 | 'foldlevel', then do "zv": View cursor line. |
Bram Moolenaar | 00a927d | 2010-05-14 23:24:24 +0200 | [diff] [blame] | 410 | Also forces recomputing folds. This is useful when using |
| 411 | 'foldexpr' and the buffer is changed in a way that results in |
| 412 | folds not to be updated properly. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 413 | |
| 414 | *zX* |
| 415 | zX Undo manually opened and closed folds: re-apply 'foldlevel'. |
Bram Moolenaar | 00a927d | 2010-05-14 23:24:24 +0200 | [diff] [blame] | 416 | Also forces recomputing folds, like |zx|. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 417 | |
| 418 | *zm* |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 419 | zm Fold more: Subtract |v:count1| from 'foldlevel'. If |
| 420 | 'foldlevel' was already zero nothing happens. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 421 | 'foldenable' will be set. |
| 422 | |
| 423 | *zM* |
| 424 | zM Close all folds: set 'foldlevel' to 0. |
| 425 | 'foldenable' will be set. |
| 426 | |
| 427 | *zr* |
Bram Moolenaar | 7d2757a | 2015-03-31 17:46:22 +0200 | [diff] [blame] | 428 | zr Reduce folding: Add |v:count1| to 'foldlevel'. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 429 | |
| 430 | *zR* |
| 431 | zR Open all folds. This sets 'foldlevel' to highest fold level. |
| 432 | |
| 433 | *:foldo* *:foldopen* |
| 434 | :{range}foldo[pen][!] |
| 435 | Open folds in {range}. When [!] is added all folds are |
| 436 | opened. Useful to see all the text in {range}. Without [!] |
| 437 | one level of folds is opened. |
| 438 | |
| 439 | *:foldc* *:foldclose* |
| 440 | :{range}foldc[lose][!] |
| 441 | Close folds in {range}. When [!] is added all folds are |
| 442 | closed. Useful to hide all the text in {range}. Without [!] |
| 443 | one level of folds is closed. |
| 444 | |
| 445 | *zn* |
| 446 | zn Fold none: reset 'foldenable'. All folds will be open. |
| 447 | |
| 448 | *zN* |
| 449 | zN Fold normal: set 'foldenable'. All folds will be as they |
| 450 | were before. |
| 451 | |
| 452 | *zi* |
| 453 | zi Invert 'foldenable'. |
| 454 | |
| 455 | |
| 456 | MOVING OVER FOLDS ~ |
| 457 | *[z* |
| 458 | [z Move to the start of the current open fold. If already at the |
| 459 | start, move to the start of the fold that contains it. If |
| 460 | there is no containing fold, the command fails. |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 461 | When a count is used, repeats the command [count] times. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 462 | |
| 463 | *]z* |
| 464 | ]z Move to the end of the current open fold. If already at the |
| 465 | end, move to the end of the fold that contains it. If there |
| 466 | is no containing fold, the command fails. |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 467 | When a count is used, repeats the command [count] times. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 468 | |
| 469 | *zj* |
| 470 | zj Move downwards to the start of the next fold. A closed fold |
| 471 | is counted as one fold. |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 472 | When a count is used, repeats the command [count] times. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 473 | This command can be used after an |operator|. |
| 474 | |
| 475 | *zk* |
| 476 | zk Move upwards to the end of the previous fold. A closed fold |
| 477 | is counted as one fold. |
Bram Moolenaar | 5e3dae8 | 2010-03-02 16:19:40 +0100 | [diff] [blame] | 478 | When a count is used, repeats the command [count] times. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 479 | This command can be used after an |operator|. |
| 480 | |
| 481 | |
| 482 | EXECUTING COMMANDS ON FOLDS ~ |
| 483 | |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 484 | :[range]foldd[oopen] {cmd} *:foldd* *:folddo* *:folddoopen* |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 485 | Execute {cmd} on all lines that are not in a closed fold. |
| 486 | When [range] is given, only these lines are used. |
| 487 | Each time {cmd} is executed the cursor is positioned on the |
| 488 | line it is executed for. |
| 489 | This works like the ":global" command: First all lines that |
| 490 | are not in a closed fold are marked. Then the {cmd} is |
| 491 | executed for all marked lines. Thus when {cmd} changes the |
| 492 | folds, this has no influence on where it is executed (except |
| 493 | when lines are deleted, of course). |
| 494 | Example: > |
| 495 | :folddoopen s/end/loop_end/ge |
| 496 | < Note the use of the "e" flag to avoid getting an error message |
| 497 | where "end" doesn't match. |
| 498 | |
| 499 | :[range]folddoc[losed] {cmd} *:folddoc* *:folddoclosed* |
| 500 | Execute {cmd} on all lines that are in a closed fold. |
| 501 | Otherwise like ":folddoopen". |
| 502 | |
| 503 | ============================================================================== |
| 504 | 3. Fold options *fold-options* |
| 505 | |
| 506 | COLORS *fold-colors* |
| 507 | |
| 508 | The colors of a closed fold are set with the Folded group |hl-Folded|. The |
| 509 | colors of the fold column are set with the FoldColumn group |hl-FoldColumn|. |
| 510 | Example to set the colors: > |
| 511 | |
| 512 | :highlight Folded guibg=grey guifg=blue |
| 513 | :highlight FoldColumn guibg=darkgrey guifg=white |
| 514 | |
| 515 | |
| 516 | FOLDLEVEL *fold-foldlevel* |
| 517 | |
| 518 | 'foldlevel' is a number option: The higher the more folded regions are open. |
| 519 | When 'foldlevel' is 0, all folds are closed. |
Bram Moolenaar | 8169525 | 2004-12-29 20:58:21 +0000 | [diff] [blame] | 520 | When 'foldlevel' is positive, some folds are closed. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 521 | When 'foldlevel' is very high, all folds are open. |
| 522 | 'foldlevel' is applied when it is changed. After that manually folds can be |
| 523 | opened and closed. |
| 524 | When increased, folds above the new level are opened. No manually opened |
| 525 | folds will be closed. |
| 526 | When decreased, folds above the new level are closed. No manually closed |
| 527 | folds will be opened. |
| 528 | |
| 529 | |
| 530 | FOLDTEXT *fold-foldtext* |
| 531 | |
| 532 | 'foldtext' is a string option that specifies an expression. This expression |
| 533 | is evaluated to obtain the text displayed for a closed fold. Example: > |
| 534 | |
| 535 | :set foldtext=v:folddashes.substitute(getline(v:foldstart),'/\\*\\\|\\*/\\\|{{{\\d\\=','','g') |
| 536 | |
| 537 | This shows the first line of the fold, with "/*", "*/" and "{{{" removed. |
| 538 | Note the use of backslashes to avoid some characters to be interpreted by the |
Bram Moolenaar | f269eab | 2022-10-03 18:04:35 +0100 | [diff] [blame] | 539 | ":set" command. It is much simpler to define a function and call it: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 540 | |
| 541 | :set foldtext=MyFoldText() |
| 542 | :function MyFoldText() |
| 543 | : let line = getline(v:foldstart) |
| 544 | : let sub = substitute(line, '/\*\|\*/\|{{{\d\=', '', 'g') |
Bram Moolenaar | c51cf03 | 2022-02-26 12:25:45 +0000 | [diff] [blame] | 545 | : return v:folddashes .. sub |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 546 | :endfunction |
| 547 | |
Bram Moolenaar | f269eab | 2022-10-03 18:04:35 +0100 | [diff] [blame] | 548 | The advantage of using a function call without arguments is that it is faster, |
| 549 | see |expr-option-function|. |
| 550 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 551 | Evaluating 'foldtext' is done in the |sandbox|. The current window is set to |
Bram Moolenaar | 6f4754b | 2022-01-23 12:07:04 +0000 | [diff] [blame] | 552 | the window that displays the line. The context is set to the script where the |
| 553 | option was last set. |
| 554 | |
| 555 | Errors are ignored. For debugging set the 'debug' option to "throw". |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 556 | |
| 557 | The default value is |foldtext()|. This returns a reasonable text for most |
| 558 | types of folding. If you don't like it, you can specify your own 'foldtext' |
| 559 | expression. It can use these special Vim variables: |
| 560 | v:foldstart line number of first line in the fold |
| 561 | v:foldend line number of last line in the fold |
| 562 | v:folddashes a string that contains dashes to represent the |
| 563 | foldlevel. |
| 564 | v:foldlevel the foldlevel of the fold |
| 565 | |
| 566 | In the result a TAB is replaced with a space and unprintable characters are |
| 567 | made into printable characters. |
| 568 | |
| 569 | The resulting line is truncated to fit in the window, it never wraps. |
| 570 | When there is room after the text, it is filled with the character specified |
| 571 | by 'fillchars'. |
| 572 | |
Yegappan Lakshmanan | 27708e6 | 2021-12-26 21:54:43 +0000 | [diff] [blame] | 573 | If the 'foldtext' expression starts with s: or |<SID>|, then it is replaced |
h-east | a977883 | 2024-12-17 20:48:42 +0100 | [diff] [blame] | 574 | with the script ID (|local-function|). Examples: > |
Yegappan Lakshmanan | 27708e6 | 2021-12-26 21:54:43 +0000 | [diff] [blame] | 575 | set foldtext=s:MyFoldText() |
| 576 | set foldtext=<SID>SomeFoldText() |
| 577 | < |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 578 | Note that backslashes need to be used for characters that the ":set" command |
| 579 | handles differently: Space, backslash and double-quote. |option-backslash| |
| 580 | |
| 581 | |
| 582 | FOLDCOLUMN *fold-foldcolumn* |
| 583 | |
| 584 | 'foldcolumn' is a number, which sets the width for a column on the side of the |
| 585 | window to indicate folds. When it is zero, there is no foldcolumn. A normal |
Bram Moolenaar | 578b49e | 2005-09-10 19:22:57 +0000 | [diff] [blame] | 586 | value is 4 or 5. The minimal useful value is 2, although 1 still provides |
| 587 | some information. The maximum is 12. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 588 | |
| 589 | An open fold is indicated with a column that has a '-' at the top and '|' |
| 590 | characters below it. This column stops where the open fold stops. When folds |
| 591 | nest, the nested fold is one character right of the fold it's contained in. |
| 592 | |
| 593 | A closed fold is indicated with a '+'. |
| 594 | |
Bram Moolenaar | 53f7fcc | 2021-07-28 20:10:16 +0200 | [diff] [blame] | 595 | These characters can be changed with the 'fillchars' option. |
| 596 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 597 | Where the fold column is too narrow to display all nested folds, digits are |
| 598 | shown to indicate the nesting level. |
| 599 | |
| 600 | The mouse can also be used to open and close folds by clicking in the |
| 601 | fold column: |
| 602 | - Click on a '+' to open the closed fold at this row. |
| 603 | - Click on any other non-blank character to close the open fold at this row. |
| 604 | |
| 605 | |
| 606 | OTHER OPTIONS |
| 607 | |
| 608 | 'foldenable' 'fen': Open all folds while not set. |
| 609 | 'foldexpr' 'fde': Expression used for "expr" folding. |
| 610 | 'foldignore' 'fdi': Characters used for "indent" folding. |
| 611 | 'foldmarker' 'fmr': Defined markers used for "marker" folding. |
| 612 | 'foldmethod' 'fdm': Name of the current folding method. |
| 613 | 'foldminlines' 'fml': Minimum number of screen lines for a fold to be |
| 614 | displayed closed. |
| 615 | 'foldnestmax' 'fdn': Maximum nesting for "indent" and "syntax" folding. |
| 616 | 'foldopen' 'fdo': Which kinds of commands open closed folds. |
| 617 | 'foldclose' 'fcl': When the folds not under the cursor are closed. |
| 618 | |
| 619 | ============================================================================== |
| 620 | 4. Behavior of folds *fold-behavior* |
| 621 | |
| 622 | When moving the cursor upwards or downwards and when scrolling, the cursor |
| 623 | will move to the first line of a sequence of folded lines. When the cursor is |
| 624 | already on a folded line, it moves to the next unfolded line or the next |
| 625 | closed fold. |
| 626 | |
| 627 | While the cursor is on folded lines, the cursor is always displayed in the |
| 628 | first column. The ruler does show the actual cursor position, but since the |
| 629 | line is folded, it cannot be displayed there. |
| 630 | |
| 631 | Many movement commands handle a sequence of folded lines like an empty line. |
| 632 | For example, the "w" command stops once in the first column. |
| 633 | |
Bram Moolenaar | 86b4816 | 2022-12-06 18:20:10 +0000 | [diff] [blame] | 634 | When starting a search in a closed fold it will not find a match in the |
| 635 | current fold. It's like a forward search always starts from the end of the |
| 636 | closed fold, while a backwards search starts from the start of the closed |
| 637 | fold. |
| 638 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 639 | When in Insert mode, the cursor line is never folded. That allows you to see |
| 640 | what you type! |
| 641 | |
| 642 | When using an operator, a closed fold is included as a whole. Thus "dl" |
| 643 | deletes the whole closed fold under the cursor. |
| 644 | |
Bram Moolenaar | a330695 | 2016-01-02 21:41:06 +0100 | [diff] [blame] | 645 | For Ex commands that work on buffer lines the range is adjusted to always |
| 646 | start at the first line of a closed fold and end at the last line of a closed |
| 647 | fold. Thus this command: > |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 648 | :s/foo/bar/g |
| 649 | when used with the cursor on a closed fold, will replace "foo" with "bar" in |
| 650 | all lines of the fold. |
| 651 | This does not happen for |:folddoopen| and |:folddoclosed|. |
| 652 | |
| 653 | When editing a buffer that has been edited before, the last used folding |
| 654 | settings are used again. For manual folding the defined folds are restored. |
| 655 | For all folding methods the manually opened and closed folds are restored. |
| 656 | If this buffer has been edited in this window, the values from back then are |
| 657 | used. Otherwise the values from the window where the buffer was edited last |
| 658 | are used. |
| 659 | |
| 660 | ============================================================================== |
Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 661 | vim:tw=78:ts=8:noet:ft=help:norl: |