I'm a novice user to vim and I haven't been able to find in the internet how to collapse functions and I've figured out how to collapse the argument list in C with zfa} and zfa). but I can't figure out how to collapse the comments sections. How do I do that?
Second question but related, is there a way to collapse all functions/argument lists/comments in a file at the same time?
The functionality you're referring to is called "folding" (see :help usr_28). The zf command is used to manually create a fold and is only used if the foldmethod option is set to either "marker" or "manual". In the examples you gave, you're creating folds over the regions specified by the a} and a) text objects (see :help usr_4.8).
For C, you can setlocal foldmethod=syntax and the folding regions will be automatically determined by the syntax rules. This should only be done for C files by either putting the setting in ~/.vim/ftplugin/c.vim or putting the following autocmd in your ~/.vimrc.
autocmd FileType c setlocal foldmethod=syntax
N.B. both of those require that filetype detection is enabled (filetype on), and the ftplugin solution requires that filetype plugins are enabled (filetype plugin on). The latter is a superset of the former, so you don't need both commands in your ~/.vimrc.
As for opening/closing all folds in the current buffer, those are the zR and zM commands respectively.
Add the following settings to ~/.gvimrc:
"folding settings
set foldmethod=indent "fold based on indent
set foldnestmax=10 "deepest fold is 10 levels
set nofoldenable "dont fold by default
set foldlevel=1 "this is just what i use
Then you can toggle folding with za. You can fold everything with zM and unfold everything with zR. zm and zr can be used to get those folds just right. Always remember the almighty help file at “help :folding” if you get stuck.
Source: http://smartic.us/2009/04/06/code-folding-in-vim/
Assuming you have set up your fold regions how you want them, set foldlevel to the desired level.
Related
Vim now has built-in Markdown folding, yay!
I want to fold on Markdown headers, and within headers, fold on indents also.
How can I have both Markdown header folding + indent fold method at the same time?
There can only be one of Vim's standard fold methods used within an individual window, but what you ask should still be possible. Here are a few options that I can think of:
You can use the expr method option and create your own custom rules with that. This is probably the only "real" way to get what you want, but it's the most complicated option.
You could also use two windows in a tab, each pointing at the same buffer, and set different fold methods locally for each split.
Finally, you could always hack something together with autocommands. From the Vim wiki page on folding, about having both indent and manual folding:
augroup vimrc
au BufReadPre * setlocal foldmethod=indent
au BufWinEnter * if &fdm == 'indent' | setlocal foldmethod=manual | endif
augroup END
This hack takes advantage of modelines, and Vim's behavior for setting variables before vs. after the modeline is read. Note that you have to have Vim's nocompatible option set for this sort of trick to work.
For example, textwidth=100 for go code and textwidth=80 for go comment.
With my OnSyntaxChange plugin, you can trigger settings changes based on the syntax element you're currently in.
call OnSyntaxChange#Install('GoComment', '^Comment$', 1, 'a')
autocmd User SyntaxGoCommentEnterA setlocal textwidth=80
autocmd User SyntaxGoCommentLeaveA setlocal textwidth=100
Put this into ~/.vim/after/ftplugin/go.vim. (This requires that you have :filetype plugin on. Alternatively, you could define an :autocmd FileType go ... (for each line) directly in your ~/.vimrc, but this tends to become unwieldy once you have many customizations.
Alternative
A smaller, non-plugin variant would be a custom gq mapping that changes 'textwidth' temporarily, performs the reformatting, and then restores the original value. But that only works for manually triggered reformatting of paragraphs.
I have inherited some c++ code with vim-based folding markers like this:
// CONSTRUCTORS/DESTRUCTORS /*{{{*/
Foo::Foo()
{
}
Foo::~Foo()
{
}
/*}}}*/
What do I need to put into my .vimrc to enable folding toggles like zm and space-bar?
With my current settings, when I hit space bar inside or zm, vim does nothing.
The default keybindings for folding are za or zm (though zm I think only closes folds, while za toggles them), so you should add the following lines to your .vimrc:
set foldmethod=marker to enable folding triggered by markers (the {{{ things in your code)
nnoremap <space> za to enable space to trigger the fold in normal mode.
But! if you're not sure if you want to enable folding in other files, you could use autocmds, like so:
autocmd FileType vim,c++,txt setlocal foldmethod=markerand that will ensure that folding only works in vim, c++, and text files.
By the way, what you've posted is only one kind of folding mentioned by vim guru Steve Losh in this article. Read it to learn more about folding. It's super cool.
If you only have a few files or if you just wish to control option(s) on a per file basis you may want to use modeline. My intro to folding came when I download a z-shell script and when I opened it, was surprised to find everything folded. Found something like this at the end of the file:
# vim:ts=4:sw=4:ai:foldmethod=marker:foldlevel=0:
Change commenting to match your code type, and insure there is a space before the word vim. As always a good place to start: :help modeline and :help folding. You may have to add set modeline to your .vimrc file if modeline was not set at build time.
OK, after googling around for a bit, I found this which seems to work:
set foldmethod=marker
nnoremap <space> za
1) I have in my .vimrc a fold expr (cf. the third example under the :help fold-expr section) which makes a fold out of paragraphs separated by blank lines :
set foldmethod=expr
set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
Most of my files are files with paragraphs (to begin with my .vimrc)
2) But I have two or three text files which are simply lists with no paragraphs and I would like to be able to fold everything except for matches to my search. I found in Vim Wikia (Tip 282) the following "Simple Folding" (at the bottom of the Tip's page) which I would like to implement :
:set foldexpr=getline(v:lnum)!~#/
:nnoremap <F8> :set foldmethod=expr<CR><Bar>zM
How can I have both of them peacefully coexist in my .vimrc ?
Is setlocal (for the second foldexpr) the solution ? Tried, failed…
Is it possible to have a fold expression (the second one) apply only to two files (file1.txt, file2.txt) ?
Is it possible to merge the 2 foldexpr in one ?
Thanks for your help
Option foldexpr is local to window, so:
:set will establish both global and local values. Global value will be used as a default for subsequent windows where local value is not specified.
:setlocal will determine local value only.
It's not clear to me what merging the two expressions would mean, but of course you can create a fold function containing all the complicated logic you want.
What is definitely easy is to set different values for foldexpr depending on the file (or file type). Use an autocommand for that.
So, the whole thing could be, in your .vimrc:
" Default: for all files
set foldmethod=expr
set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
nnoremap <F8> :setlocal foldmethod=expr<CR><Bar>zM
" Only for specific files
augroup NonDefaultFoldMethod
autocmd!
autocmd BufNewFile,BufRead file1.txt,file2.txt setlocal foldexpr=getline(v:lnum)!~#/
augroup end
The augroup/autocmd! idiom is there just to avoid duplicating autocommands if you source .vimrc repeatedly. It's best practice when establishing autocommands.
I want my Vim to display empty lines as a string of ### characters, like so:
I would like it to be work similarly to how I replace my tabs char to >--- with set listchars=tab:>-. Just display it that way, not actually insert them.
Also, it would be great if it could adapt to size of my terminal.
The desired effect can be achieved via folding. If we create one-line
folds separately containing empty lines of a buffer, they all will be
marked out as folded. The only thing left will be to customize the
highlighting accordingly.
First of all, we need to automatically create the folds. For this
purpose, we can switch folding to the expr method and then set
the foldexpr option to evaluate to a non-zero value for empty
lines only:
:setl foldmethod=expr
:setl foldexpr=empty(getline(v:lnum))
What we should do next for the trick to work out is to make those
folds close automatically in order to trigger the folding
highlighting:
:setl foldminlines=0
:setl foldlevel=0
:set foldclose=all
Finally, to repeat a custom character in the folding line, we just
empty the text displayed for a closed fold, and change the filling
character:
:setl foldtext=''
:set fillchars+=fold:#
Combining the above commands in one function for convenience,
we obtain the following:
function! FoldEmptyLine()
setl foldmethod=expr
setl foldexpr=empty(getline(v:lnum))
setl foldminlines=0
setl foldlevel=0
set foldclose=all
setl foldtext=''
set fillchars+=fold:#
endfunction
The downside of this trick, of course, is that it interferes with the
usual applications of folding, and cannot be easily used without
modifications if the user extensively relies on folding for other
purposes.