vim do not fold everything on first fold - vim

When I close the first fold in a buffer (zc in normal mode), all the folds are automatically closed. Is there a way to just close the given fold without closing the rest?
I have foldmethod=syntax. Observed with python but probably this applies to other languages.
Example python file
zc on method a()
As you can see, all methods: a, b, c are folded. Desired behaviour is for only method a to be folded, as shown below:
This only happens on the first time a fold is closed in a buffer. After re-opening all the folds, zc will only close the proper fold.
EDIT: I believe this has to do with SimpylFold plugin. I have set nofoldenable by default. When I zc, it looks like SimpylFold sets foldenable, which automatically folds all the methods.

The cause was a weird interaction with nofoldenable and the plugin SimpylFold. I set nofoldenable by default. If you have foldenable, unless you add additional commands all your folds are closed by default.
Now when using the SimpylFold plugin, zc on first use also sets foldenable, which will close all folds.
The solution is to add something like this to your ~/.vimrc
autocmd FileType python setlocal foldenable foldlevel=20
This enables folding locally for python files while leaving the folds open on buffer open. Then zc behaves normally.

Related

recalculating folds in vim without applying foldlevel

I'm trying to set up neovim as a python IDE and I'm having some trouble making folding work like I want it to.
My setup:
NVIM 0.4.3
Plug 'Konfekt/FastFold'
Plug 'tmhedberg/SimpylFold'
nnoremap <space> za to toggle a fold with spacebar
My issue is that SimpylFold does not seem to recalculate folds as I edit a file in insert mode. So any function or class I add to a file with insert mode will just say E490: No fold found. Curiously, if I select the lines I've added, delete them and undo, the folds are then correctly recognized. Pasting in a function in normal mode also correctly detects the new fold. So the issue seems to only appear when adding lines in insert mode.
Here's what I know so far:
I've tried :set foldmethod=indent but it falls short of the functionality I'm looking for.
zx forces recalculate on folds. This does work, but the problem is it reapplies foldlevel to the whole buffer, which will undo all the manual fold toggles I've done with space. Couldn't find anything in the documentation about recalculating folds without reapplying foldlevel
From what I can gather, each line in vim has a foldlevel which determines what fold level that line belongs to.. for example all unindented lines in python would have foldlevel=0, Then the entire buffer also has a foldlevel, which determines which levels are actually folded.. so if the buffer's foldlevel is set to 1, then all lines with foldlevel of 1 or more would be folded.
the za command which im using to toggle a specific fold manually seems to operate on a layer separate from all this foldlevel stuff, and when zx is used to recalculate folds, all manual folds/unfolds from za are lost
Anyways, please correct me if I'm wrong, I just switched to linux (and with it, vim) a couple weeks ago, so I'm far from what you'd consider an expert.

Vim closes all folds on write

I have the following fold option set in my vimrc:
set foldmethod=marker
Now when I enter :w or press ZW vim closes irregularly (meaning it doesn't happen every time) all existent folds, which are marked by {{{...}}} in the file. It happens with different filetypes as well.
It is really annoying and I would like to figure out how to prevent this behaviors.

folding not found error when za is pressed in vim

I opened a large javascript file in gvim and am trying to use folding, but I cannot get it to work
Im trying
zo - opens folds
zc - closes fold
zm - increases auto fold depth
zr - reduces auto fold depth
but it says folding does not exist?
Do I have to turn the folding mechanism on?
Why wont this work? Is it a new install of gvim?
The folding behavior depends on the values of a bunch of options. The most important is foldmethod which dictates how folds are calculated. You can see its value with :set foldmethod? which should tell you which of these methods, manual, indent, expr, marker, syntax, diff, is currently in use. Refer to :help 'foldmethod' and the linked help sections for details.
manual is the default method where folds have to be created manually with zf before being opened or closed.
With indent, folds are automatically calculated for you based on indenting, with syntax they are calculated based on the filetype-specific syntax rules.

Stop vim from dynamically updating folds

Is there any way to stop vim from automatically updating folds on the fly? I really love vim's folding, and I prefer having it in syntax mode so that folds are created as I type. But for instance when I code C++ and I write a bracket { it automatically closes all subsequent folds, and when I then close the bracket again with a }, vim automatically expands all subsequent folds, meaning that I have to refold everything.
Another related problem, if I have the same document open in a different buffer, say I have run ":split", then writing an open bracket { will nest all folds in the buffer under the fold in which I opened the bracket, and closing it will un-nest the folds but also close all of them. If I use either "." or "->" to access a member function/variable, it resets all folds in the buffer to be whatever the current foldlevel is, regardless of which folds I have opened/closed myself.
This is somewhat frustrating when I have the same document open in two buffers so I can read the contents of one function when writing another, as I constantly have to switch buffers and reopen my folds.
In my .vimrc I have
set foldmethod=syntax
and that is about it. For autocompletion I use clang-complete and supertab with:
let g:SuperTabDefaultCompletionType = "<c-x><c-u><c-p>"
I think that is everything which migh affect this.
Edit:
Added some pictures to help illustrate the problem
Both problems can be solved with the following two autocmds:
autocmd InsertLeave,WinEnter * setlocal foldmethod=syntax
autocmd InsertEnter,WinLeave * setlocal foldmethod=manual
This sets the buffer local 'foldmethod' to manual when insert mode is entered or its window (a buffer display) is left, and sets it to syntax when insert mode is left or its window is entered.
This works because setting 'foldmethod' to manual will keep the folds automatically created by syntax as if you set them yourself (manually), and manual folds are not updated based on the syntax of the file.
I've found two bugs with this solution:
When switching windows while in insert mode, the autocmd will set the 'foldmethod' to syntax for the new window, even though it's in insert mode and should be set to manual.
This isn't really a problem for me because I use Vim like a civilized person and operate in normal mode by default.
When
a new buffer is created (e.g. by reading a file)
and 'foldlevel' is 0
and a particular syntax is used (I'm able to duplicate the issue with a C file)
and the o or O command is used to enter insert mode for the first time in that buffer (doing i<esc>o does not duplicate the bug),
then all folds below the cursor will be opened.
I accidentally discovered this when testing the above solution, and now looking back I'm surprised I found it; it's almost not even worth mentioning. I don't intend on trying to write a test file that has the exact syntax necessary to duplicate the bug, so this may go unnoticed for another eon.
I actually discovered this question several months ago and used the solution Ben linked to for a while, before eventually being annoyed enough with the multiple window for one buffer issue (your second problem) to fix it.
So thanks to Ben for his solution, and you for asking this question!
I made a bit of a modification to user4830797's answer which helps deal with situations where the file you're editing doesn't use foldmethod=syntax (for example, a .vimrc file which might use foldmethod=marker):
autocmd InsertLeave,WinEnter * let &l:foldmethod=g:oldfoldmethod
autocmd InsertEnter,WinLeave * let g:oldfoldmethod=&l:foldmethod | setlocal foldmethod=manual
I think you need to check :h 'foldlevel. You should also perhaps use :mkview, probably in autocmd which restores manually open and closed folds.
Other then that you should perhaps set folding method differently on different file types (for instance on C you could set it to manual or marker)
If you temporarily set the foldmethod to manual, then Vim will keep all the folds currently defined by syntax, and keep them in the exact open/closed state you have them in now. This can be done automatically with an InsertEnter autocmd and restored on InsertLeave to protect your fold states in a single window. Unfortunately I have not yet spent time trying to get it working in split windows, but using window-local variables it is easy enough to even account for the user switching windows or something without leaving insert mode. See http://vim.wikia.com/wiki/Keep_folds_closed_while_inserting_text for details and discussion.

Vim: Fold top level folds only

I have a long code file with syntax folding in Vim.
I know how to open all folds (zR) or close all folds (zM), and I know how to increase or decrease the foldlevel (zm, zr).
However when I increase the foldlevel the inner most folds are closed; instead I want the outer most folds closed while the inner most are unfolded. It is possible to do this manually by opening all folds and the closing each top level fold by hand it's incredible tedious specially with long files that I open quickly to get an overview of the code.
Is there any key shortcut to do this? Or do I need to make some sort of Vim function to do this? And if so, how?
I think you want to add set foldnestmax=1 to your $MYVIMRC.
Yes, you can type
:%foldc
Which closes one level of folds (outside in).
As Karl says, the foldnestmax setting is probably what you want.
zO (i.e., capital-letter-o) opens all nested folds.
I also find zx and zv very helpful.
When I use foldmethod=expr with a custom fold expression, I'll often modify the expression so that it only folds what I want it to fold.

Resources