vim-anyfold
November 1, 2018 ยท View on GitHub
Generic folding mechanism and motion based on indentation. Fold anything that is structured into indented blocks. Quickly navigate between blocks.
Short Instructions
Using this plugin is easy: Activate vim-anyfold by the command :AnyFoldActivate and deal with folds using Vim's built-in fold commands. Use key combinations [[ and ]] to navigate to the beginning and end of the current open fold. Use ]k and [j to navigate to the end of the previous block and to the beginning of the next block. For more detailed documentation, read the included vim doc :h anyfold or continue reading.
Introduction
This Vim plugin comes with the following features:
- Folding mechanism based on indented blocks that has a very intuitive and predictable behaviour (see examples below).
- Results comparable to syntax aware folding methods but fast and generic algorithm that does not rely on language specific rules.
- Works out of the box for any filetypes, optimal results for all indented languages (including properly indented curly brace languages).
- Shortcuts to navigate to beginning / end of a block and to previous / next indented block.
- Can handle corner cases with ease (comments, varying indentation widths, line breaks).
- Fast update mechanism that keeps folds in sync with buffer.
It has the following shortcomings:
- Can not correctly fold mismatched indentation and thus should only be used together with disciplined programming style (or in combination with Vim's
equalprgautoindent feature).
Advantages over foldmethod=indent
foldmethod=indentonly works for indents that are a multiple ofshiftwidthand thus fails for aligned code lines and inconsistent indentation. Vim-anyfold correctly defines folds for arbitrary indents.- vim-anyfold recognizes braces as part of indented blocks and correctly folds them. Vim-anyfold thus produces good folds not only for indented languages but also for e.g. C++ or Java.
- vim-anyfold optionally folds multiline comments.
Be aware that vim-anyfold is much slower than foldmethod=indent and can reduce Vim's responsiveness. This is noticeable only when editing large files.
Examples
Python

Fortran

C++

Java
Note: this example is outdated since better defaults have been implemented for curly braces.

Examples were recorded using
autocmd Filetype * AnyFoldActivate
let g:anyfold_fold_comments=1
set foldlevel=0
colorscheme solarized
hi Folded term=NONE cterm=NONE
Setup and usage
-
Install this plugin with a vim plugin manager.
-
Add the following lines to your vimrc (if not already present).
filetype plugin indent on " required syntax on " required autocmd Filetype * AnyFoldActivate " activate for all filetypes " or autocmd Filetype <your-filetype> AnyFoldActivate " activate for a specific filetype set foldlevel=0 " close all folds " or set foldlevel=99 " Open all folds
If you prefer to not activate vim-anyfold automatically, you can always invoke this plugin manually inside vim by typing :AnyFoldActivate.
- Use Vim's fold commands
zo,zO,zc,za, ... to fold / unfold folds (read:h fold-commandsfor more information). Use key combinations[[and]]to navigate to the beginning and end of the current open fold. Use]kand[jto navigate to the end of the previous block and to the beginning of the next block.
Additional remarks
-
Supported folding commands: anyfold uses
foldmethod=exprto define folds. Thus all commands that work with expression folding are supported. -
Fold display: anyfold's minimalistic display of closed fold assumes that folds are highlighted by your color scheme. If that is not the case, consider installing a suitable color scheme or highlight folds yourself by a command similar to
hi Folded term=underline -
Lines to ignore: By default, anyfold uses the
foldignoreoption to identify lines to ignore (such as comment lines and preprocessor statements). Vim's default isfoldignore = #. Lines starting with characters infoldignorewill get their fold level from surrounding lines. Ifanyfold_fold_comments = 1these lines get their own folds. For instance, in order to ignore C++ style comments starting with//and preprocessor statements starting with#, setautocmd Filetype cpp set foldignore=#/This approach is fast but does not work for e.g. C style multiline comments and Python doc strings. If you'd like anyfold to correctly ignore these lines, add
let g:anyfold_identify_comments=2to your vimrc. Please note that this may considerably slow down your Vim performance (mostly when opening large files).
-
Large Files: anyfold causes long load times on large files, significantly longer than plain indent folding. By adding the following to your vimrc (and replacing
<filetype>), anyfold is not initialized for large files:" activate anyfold by default augroup anyfold autocmd! autocmd Filetype <filetype> AnyFoldActivate augroup END " disable anyfold for large files let g:LargeFile = 1000000 " file is large if size greater than 1MB autocmd BufReadPre,BufRead * let f=getfsize(expand("<afile>")) | if f > g:LargeFile || f == -2 | call LargeFile() | endif function LargeFile() augroup anyfold autocmd! " remove AnyFoldActivate autocmd Filetype <filetype> setlocal foldmethod=indent " fall back to indent folding augroup END endfunction -
Customization: For expert configuration, anyfold triggers an event
anyfoldLoadedafter initialisation. This enables user-defined startup steps such asautocmd User anyfoldLoaded normal zvwhich unfolds the line in which the cursor is located when opening a file.
-
Documentation: For more detailed instructions and information, read the included vim doc
:h anyfold.
Options
All options can be either set globally
let g:<option>=<value>
or filetype specific
autocmd Filetype <filetype> let g:<option>=<value>
| Option | Values | Default value | Description |
|---|---|---|---|
anyfold_fold_display | 0, 1 | 1 | Minimalistic display of closed folds |
anyfold_motion | 0, 1 | 1 | Map motion commands to [[, ]], [j, ]k |
anyfold_identify_comments | 0, 1, 2 | 1 | Identify lines to ignore for better fold behavior. 1: use foldignore, 2: use foldignore and syntax (slow) |
anyfold_fold_comments | 0, 1 | 0 | Fold multiline comments |
anyfold_comments | list of strings | ['comment', 'string'] | Names of syntax items that should be ignored. Only used if anyfold_identify_comments = 2. |
anyfold_fold_toplevel | 0, 1 | 0 | Fold subsequent unindented lines |
anyfold_fold_size_str | string | '%s lines' | Format of fold size string in minimalistic display |
anyfold_fold_level_str | string | ' + ' | Format of fold level string in minimalistic display |
Complementary plugins
Here is a small list of plugins that I find very useful in combination with vim-anyfold:
- Cycle folds with one key, much more efficient than Vim's built-in folding commands: vim-fold-cycle
- Indent based text objects are not (yet) implemented in vim-anyfold, but this plugin works fine (even though blocks are defined in a slightly different way): vim-indent-object
Acknowledgements
I thank the following people for their contribution
- Greg Sexton for allowing me to use his function for improved fold display.