On an up-to-date Arch system, I set up marker-based folds in vim and python scripts like so:

Extracted from my ~/.vimrc [1]

set nocompatible  " default
filetype plugin indent on
set nofoldenable
set foldlevel=1
set foldcolumn=1

Along with:

$ cat ~/.vim/after/ftplugin/vim.vim
setlocal foldmethod=marker
setlocal foldmarker={{{,}}}  " Default for fdm=marker

$ cat ~/.vim/after/ftplugin/python.vim
setlocal foldmethod=marker
setlocal foldmarker={{{,}}}  " Default for fdm=marker
setlocal foldnestmax=3

It works for vim scripts but not for python. I've been at it most of one day already and frankly I am missing something. I am currently resorting to committing the content of ~/.vim/after/ftplugin/python.vim directly to ~/.vimrc and setting the corresponding parameters globally instead of locally. That works well, but that also excludes the possibility of differentiating settings, e.g.:

  • marker-based folds in vim
  • indent-based or syntax-based folds in python or in bash scripts.

What am I doing wrong ?

With all setting committed globaly to ~/.vimrc, what I get in the vim buffer of any python module is:

: verbose set filetype? foldmethod? foldmarker?
            Last set from /usr/share/vim/vim82/filetype.vim line 1291                                                      
            Last set from ~/.vim/view/~=+Documents=+Work=+Projects=+xxx-data=+Src=+proof_demo.py= line 67
            Last set from ~/.vim/view/~=+Documents=+Work=+Projects=+xxx-data=+Src=+proof_demo.py= line 66 

What "it doesn't work" means

It doesn't fold at all when I do zc, other than where I have previously set fold(s) manually. zM has no effect at all (for example when foldmethod=indent in ~/.vim/after/ftplugin/python.vim), again except when markers are set manually (provided foldmethod=marker in ~/.vimrc). Same behavior for all python files, which tells me it is probably some deep-seated issue, not malformed python file. Same in shell scripts with a similarly built ~/.vim/after/ftplugin/sh.vim, so it's not python specific.

Views info

The most interesting use case in that context is when foldmethod=manual because, without views, manually set folds are lost upon closing the buffer. But I need views to be able to go back to the buffer's last cursor position (line + col) when re-opening a file with vim. I need views for that because the alternative I did implement before I started using folds, based on vim.fandom.com/wiki/…, is incompatible with implementing any kind of folds apparently. It just fails silently.

It turns out my use of "views" is not compatible with parsing settings from ~/.vim/after/ftplugin/*.vim files. "Why ?" is beyond me. I am not sure whether it is the execution context I build by means of my ~/.vimrc or a bug. I would tend to favor the first, although I really don't have much special in ~/.vimrc.

  • 1
    With the setup you described... What does :verbose set filetype? foldmethod? foldmarker? return? Wondering if any of your settings are being overwritten elsewhere... When you say it doesn't work, what do you mean? It doesn't fold at all? It folds the incorrect blocks? What if you use a command such as zM to fold everything? Can you share a small reproducer Python file with the markers where this doesn't do what you expect it to? – filbranden Apr 15 at 5:49
  • You said "except when markers are set manually", but when you're using foldmethod=marker, you have to add the markers (manually) for folding to work... Like, you need to add a # {{{ comment to begin a fold and a # }}} to end it. (Or a # {{{1 comment at each new top-level fold, using an explicit level also works.) Do you by any chance misunderstand how foldmethod=marker is supposed to work? See :help fold-marker... – filbranden Apr 15 at 11:17
  • 1
    Yeah I thought as much, just wanted to double check... I'm puzzled at why this doesn't work for you, I can't reproduce it really... I'm not that knowledgeable in how Vim folding works, hopefully someone who knows it better than me will pitch in with a better suggestion on how to troubleshoot this. – filbranden Apr 15 at 11:26
  • 1
    I’m not using views and I’m able to get to the last-edited line with a similar autocommand, folds or no... github.com/benknoble/Dotfiles/blob/… – D. Ben Knoble Apr 15 at 13:09
  • @D.BenKnoble Restoring last cursor position is also in defaults.vim – filbranden May 1 at 15:12

[Thanks to @DBenKnoble for his insight. It led me right to the solution.]

When using "views" to store vim sessions snapshots, watch for the value(s) of the vop option parameter. For more info :h vop. Its default is:

set viewoptions=cursor,folds,options,curdir

Use of folds in the above conflicts with the use of ~/.vim/after/ftplugin/*.vim files. You can take foldsout and go on using the two autocmd lines below in your ~/.vimrc. Both call on "views":

au BufWinLeave * mkview
au VimEnter * silent loadview

Then you can go back to using ~/.vim/after/ftplugin/python.vim as you did. You can check that for any python module:

:verbose set filetype? foldmethod? foldmarker?
         Last set from /usr/share/vim/vim82/filetype.vim line 1291
         Last set from ~/.vim/view/~=+.vimrc line 67
         Last set from ~/.vim/view/~=+.vimrc line 65

So the best thing is to stick to views and just suppress the folds option in viewoptions in your ~/.vimrc:

set viewoptions=cursor,options,curdir 
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.