vim-anyfold
vim-anyfold copied to clipboard
Language agnostic vim plugin for folding and motion based on indentation.
vim-anyfold
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.