What is the recommended way to use Vim folding for Python code
Question:
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?
Answers:
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>
I really like the python_ifold
plugin.
Try this plugin:
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.
I use this syntax file for Python. It sets the folding method to syntax and folds all classes and functions, but nothing else.
The Python source comes with a vim syntax plugin along with a custom vimrc file. Check the python FAQ on vim
I think that indent folding is fine for python. I’m making a multi-branched git repo for vim-config python/django IDE ideas. Fork away!
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)+%(z1s)@!." fold transparent
hi link pythonDefStatement Statement
Then simply activate the folding with :set foldmethod=syntax
.
Yet another plugin for folding Python code. Rather simple, handling docstrings, and on the GitHub:
Enjoy!
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.
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
Based on the answer by @Genma I glued together the following syntax rules which just need to be added as .vim/after/syntax/python.vim
syn keyword pythonStatement class def
syn match pythonFunction "hw*" containedin=pythonFold
syn region pythonFold fold transparent
start = "(^z(s*)v%(def|class|if|elif|else|for|while|try|except|finally|with)>)@<="
end = "vze%(s*n)+%(z1s)@!."
syn region pythonCurlyBrace start="{" end="}" fold transparent
syn region pythonSquareBrace start="[" end="]" fold transparent
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?
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>
I really like the python_ifold
plugin.
Try this plugin:
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.
I use this syntax file for Python. It sets the folding method to syntax and folds all classes and functions, but nothing else.
The Python source comes with a vim syntax plugin along with a custom vimrc file. Check the python FAQ on vim
I think that indent folding is fine for python. I’m making a multi-branched git repo for vim-config python/django IDE ideas. Fork away!
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)+%(z1s)@!." fold transparent
hi link pythonDefStatement Statement
Then simply activate the folding with :set foldmethod=syntax
.
Yet another plugin for folding Python code. Rather simple, handling docstrings, and on the GitHub:
Enjoy!
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.
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
Based on the answer by @Genma I glued together the following syntax rules which just need to be added as .vim/after/syntax/python.vim
syn keyword pythonStatement class def
syn match pythonFunction "hw*" containedin=pythonFold
syn region pythonFold fold transparent
start = "(^z(s*)v%(def|class|if|elif|else|for|while|try|except|finally|with)>)@<="
end = "vze%(s*n)+%(z1s)@!."
syn region pythonCurlyBrace start="{" end="}" fold transparent
syn region pythonSquareBrace start="[" end="]" fold transparent