Aleksandra Glesaaen
Aleksandra Glesaaen

Reputation: 594

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

Upvotes: 9

Views: 3240

Answers (4)

Ben Weedon
Ben Weedon

Reputation: 63

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

Upvotes: 3

user4830797
user4830797

Reputation:

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:

  1. 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.

  2. 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!

Upvotes: 6

Ben
Ben

Reputation: 8905

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.

Upvotes: 0

majkinetor
majkinetor

Reputation: 9046

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)

Upvotes: 0

Related Questions