What is the recommended way to use Vim folding for Python code? [closed]
Asked Answered
S

8

130

I am interested in enabling code folding in Vim for Python code. I have noticed multiple ways to do so.

Does anyone have a preferred way to do Python code folding in Vim? I.e,

  • Do you have a particular Vim plugin that you use and like?
  • Do you use manual folding or do you place markers in comments?
  • Any other recommended ways to do code folding for Python in Vim?
Spermatophyte answered 10/12, 2008 at 22:10 Comment(0)
O
149

Personally I can't convince myself to litter my code with the markers. I've become pretty used to (and efficient) at using indent-folding. Together with my mapping of space bar (see below) to open/close folds and the zR and zM commands, I'm right at home. Perfect for Python!

set foldmethod=indent
nnoremap <space> za
vnoremap <space> zf

This maps the spacebar to open/close the current indented fold in normal mode. It also maps the spacebar to create a manual fold in visual mode. However, this doesn't work if foldmethod is set to indent so its purpose is a mystery.

Obstructionist answered 11/12, 2008 at 19:47 Comment(4)
:set foldmethod=indent first. I was googling for just this and stumbled upon your answer, very nice! :)Eichhorn
My friend also liked set foldnestmax=2, this way the methods of classes are folded, but internal statements aren't.Barkentine
I'm not certain why the second mapping is in this answer to zf. It's not used if indent-folding is being used. However, if you are doing manual folding the mapping makes perfect sense. za, however, seems to be the best way to open/close folds quickly. I also recommend using fold navigation (zk, zj).Domiciliate
The vnoremap is good for manual mapping. In your ftplugin, add set foldmethod=indent for Python. Then, in your .vimrc, set foldmethod=manual. Now, you can fold in both Python and non-Python with spacebar mappingSanatory
G
25

I use this syntax file for Python. It sets the folding method to syntax and folds all classes and functions, but nothing else.

Giess answered 12/12, 2008 at 0:32 Comment(4)
how to fold after unfolding? I cant find the shortcut! tnxThereinto
Tried this syntax file and it worked reasonably well for the highlighting. But it did absolutely nothing for the cold folding, when i use 'zM' nothing happens, when i use 'za' in a class i get the E490 (No Fold found). What is going wrong?Ogden
+1. At first try, python code (class, method) folding works wonderfully for me. Employ Walter's (https://mcmap.net/q/173419/-what-is-the-recommended-way-to-use-vim-folding-for-python-code-closed) answers to map space bar to fold commands, but that solution doesn't work nearly as well (for me) as this one. Thanks @Giess for the reference.Artilleryman
@DaniGehtdichnixan, perhaps you need :AnsiEsc -- look into that and I think you will find a solutionBackspin
B
12

Yet another plugin for folding Python code. Rather simple, handling docstrings, and on the GitHub:

SimpylFold

Enjoy!

Barcelona answered 26/11, 2015 at 13:51 Comment(4)
This works best. I have stopped thinking about code folding at all since it has never caused any headache.Exteriorize
@Exteriorize I sometimes wish it would also fold if, for and while blocks, do you not?Barcelona
hmm that might not be very helpful i think. If he folds these blocks, it is not very clear what the content is while in a folded state. However with methods and other named blocks the name tells it all. I can sort of guess what the folded block is doing by looking at its name.Exteriorize
@Exteriorize I don't know.. I'd like to try. Why not trying? ^ ^Barcelona
P
7

Python is well suited for folding on indent, bit for writing my own code I use markers as they can crunch a document down the way you want it and can serve as a kind of a table of contents. I have this in my vimrc to flip between the two when I'm viewing someone elses code.

#Toggle fold methods \fo
let g:FoldMethod = 0
map <leader>fo :call ToggleFold()<cr>
fun! ToggleFold()
    if g:FoldMethod == 0
        exe 'set foldmethod=indent'
        let g:FoldMethod = 1
    else
        exe 'set foldmethod=marker'
        let g:FoldMethod = 0
    endif
endfun
#Add markers (trigger on class Foo line)
nnoremap ,f2 ^wywO#<c-r>0 {{{2<esc>
nnoremap ,f3 ^wywO#<c-r>0 {{{3<esc> 
nnoremap ,f4 ^wywO#<c-r>0 {{{4<esc>
nnoremap ,f1 ^wywO#<c-r>0 {{{1<esc>
Perversion answered 10/12, 2008 at 22:26 Comment(0)
R
6

I really like the python_ifold plugin.

Riel answered 10/12, 2008 at 22:29 Comment(2)
Unfortunately, this plugin uses more processor time than I would prefer (even with the a version) as I like to keep my vim speedy. Any other suggestions?Spermatophyte
This answer really needs a description.Peat
P
4

In your .vimrc:

set foldmethod=indent
set shiftwidth=4

Then zM to mask all zR to expand all. I also added:

nnoremap <space> za
vnoremap <space> zf
map z1  :set foldlevel=0<CR><Esc>
map z2  :set foldlevel=1<CR><Esc>
map z3  :set foldlevel=2<CR><Esc>
map z4  :set foldlevel=3<CR><Esc>
map z5  :set foldlevel=4<CR><Esc>
map z6  :set foldlevel=5<CR><Esc>
map z7  :set foldlevel=6<CR><Esc>
map z8  :set foldlevel=7<CR><Esc>
map z9  :set foldlevel=8<CR><Esc>

So you can z1 and z2 to unindent little by little.

Perceivable answered 3/1, 2020 at 3:46 Comment(0)
H
3

For me the ideal folding is to fold just the class and def blocks, indent folding is too much for my taste. I think one elegant solution is to use the syntax system like this one mentioned by Tomas. However, this one is meant to replace the original syntax file and it may end being older than the original (i.e. that script doesn't mention Python 3 syntax).

My solution is to place in the ~/.vim/syntax folder a file named python.vim with just the important lines (taken from the above script):

syn match   pythonDefStatement  /^\s*\%(def\|class\)/
       \ nextgroup=pythonFunction skipwhite
syn region  pythonFunctionFold  start="^\z(\s*\)\%(def\|class\)\>"
       \ end="\ze\%(\s*\n\)\+\%(\z1\s\)\@!." fold transparent

hi link pythonDefStatement Statement

Then simply activate the folding with :set foldmethod=syntax.

Hyperesthesia answered 14/1, 2014 at 11:9 Comment(1)
I like this solution. But it does not match 'n fold classes and defs if they stand at the beginning of a line. Since I can hardly read the expression, I am in trouble trying to tweak it in order to match ^def and ^class. This is curious though since \s* should deal well with this..Barcelona
A
2

I really like this little vim script i wrote for .vimrc. It maps alt+1 to fold the first python indent level (class definitions and functions), alt+2 to fold the second level (class methods), and alt+0 to unfold everything. It makes sure it only folds one level and doesn't fold any of the nested sub levels. You can still use za to toggle folding for the current block. Note that in ^[0, the ^[ is alt for my terminal. Don't have a lot of experience in vim script so feel free to make suggestions on the function :)

" Python folding
nnoremap ^[0 zR<CR>
nnoremap ^[1 :call Fold(0)<CR>
nnoremap ^[2 :call Fold(1)<CR>
function Fold(level)
    :let b:max = a:level + 1
    :set foldmethod=indent
    :execute 'set foldnestmax='.b:max
    :execute 'set foldlevel='.a:level
endfunction
Admire answered 18/6, 2020 at 14:55 Comment(1)
To use alt keys on a Mac: https://mcmap.net/q/81926/-can-i-map-alt-key-in-vimOglesby

© 2022 - 2024 — McMap. All rights reserved.