Vim customization for python

Python seems to keep grow­ing on me. By no means am I a Python mas­ter, nor am I a vim guru but I do pre­fer to use vim over a gui edi­tor. Sure there are some niceties with using a gui but get­ting com­fort­able using a tool that is almost always at your dis­posal has some­thing to be said for it. Adding a few things to your vim envi­ron­ment will make writ­ing python much more pleasurable.

First there is the python indent plu­gin. At the time of this writ­ing the cur­rent ver­sion is 0.3. There is one annoy­ing thing about it. When com­ment­ing with hashes it un-indents. Luck­ily Henry Prêcheu pointed out that its an easy one line fix.

setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except

should be changed to.

setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except,0#

Here is the full updated ver­sion of the script. Vim Python Indent 0.4_alpha1

Syn­tax Highlighting

Down­load at the time of this writ­ing the cur­rent ver­sion is 2.6.3. and place it in your .vim /syntax/ direc­tory (if its not there you should cre­ate it). This will add awe­some high­light­ing to your python files. But we can make it bet­ter! We can add some sim­ple error check­ing for things like miss­ing colons. These are the addi­tions that I have added which I found pro­vided by son­tek aka John M. Ander­son. Don’t for­get to add syntax on to your .vimrc.

syn match pythonError "^\s*def\s\+\w\+(.*)\s*$" display
syn match pythonError "^\s*class\s\+\w\+(.*)\s*$" display
syn match pythonError "^\s*for\s.*[^:]$" display
syn match pythonError "^\s*except\s*$" display
syn match pythonError "^\s*finally\s*$" display
syn match pythonError "^\s*try\s*$" display
syn match pythonError "^\s*else\s*$" display
syn match pythonError "^\s*else\s*[^:].*" display
syn match pythonError "^\s*if\s.*[^\:]$" display
syn match pythonError "^\s*except\s.*[^\:]$" display
syn match pythonError "[;]$" display
syn keyword pythonError         do

We can take that a step fur­ther with the fol­low­ing addi­tions to your .vimrc.

" Syntax checking entire file
" Usage: :make (check file)
" :clist (view list of errors)
" :cn, :cp (move around list of errors)
autocmd BufRead *.py set makeprg=python\ -c\ \"import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(r'%')\"
autocmd BufRead *.py set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m

This will allow you to check the syn­tax ofy­our entire file by typ­ing :make. you can the get a list of errors with :clist and move between the errors with :cn and :cp.

Exe­cute block of code
Some­times you want to check or exe­cute a block of code. Drop the python exe­cute block vim script into your .vim/ftplugin/ direc­tory. With it you can visu­ally select a block of code and exe­cute it with Ctrl+h.

So you are find­ing errors in your code and want to trace them? Drop this python ipdb vim script into your .vim/ftplugin/directory. You can set break points with F7 and clear them with shift-F7. If your not famil­iar with ipdb you should look it up.

While we’re at it lets add an easy way to run your cur­rent script.
map <f8> :!python %<cr>
It was pointed out by fboen­der on red­dit that there is a bet­ter way to do this.

Down­load the bexec plu­gin open it with vim using the full path to your vim­ball and then type :so % to source and install the vim­ball. Now setup some maps for it.

nmap <silent> <unique> <F8> :call Bexec()<cr>
vmap <silent> <unique> <F8> :call BexecVisual()<cr>
map <silent> <unique <F9> :call BexecCloseOut()<cr>

in your .vimrc will cause F8 to run the file you cur­rently have open.

Who doesn’t love tabs? You can have them in vim too ya know! Add these lines to your .vimrc

map \t :tabnew<cr>
map \n :tabnext<cr>
map \p :tabprevious<cr>
map \c :tabclose<cr>

With these addi­tions you can open a new tab with \t move right with \n and move left with \p. To close the tab sim­ply enter \c.

Edit File Menu
You can add a handy menu when open­ing files with :e. Its called the wild­menu. Add the fol­low­ing lines to your .vimrc. As a side note it will also give com­ple­tion options for vim commands.

set wildmenu
set wildignore+=*.pyc,*.zip,*.gz,*.bz,*.tar,*.jpg,*.png,*.gif,*.avi,*.wmv,*.ogg,*.mp3,*.mov

Code Snip­pets
The vim snippy plu­gin pro­vides text­mate like code snip­pets. Its pretty darn cool. Installing is hard. Down­load the lat­est ver­sion from here. Be sure to down­load both snippy_plugin.vba and snippy_bundles.vba as the plu­gin and snip­pets are now seper­ated. Cre­ate a direc­tory .vim/after/ftplugin and put both .vba files in there. I installed them by open­ing them with vim using the full path to the .vba files and then typ­ing :source % to source the file. The vim ball script will install and you will be ready to go. Open a .py file and type def<tab>. You can tab through each <{}> and fill in the con­tent to con­struct your function.

Extra func­tional good­ness like block comment

Oper­at­ing on blocks of code is handy. Being able to com­ment out an entire sec­tion with a few key­strokes saves much time. This vim script pro­vides that func­tion­al­ity. I down­load it and save it to .vim/ftplugin/python_fn.vim.  Then you can visu­ally select a block of code with ]v and com­ment it out with ]c and move its inden­ta­tion level with ]< and ]> as well as a few other things.

PEP8 Good­ness

Adding the fol­low­ing to .vim/ftplugin/python_pep8.vim will help you with tab space and other such wor­ries with pep8.

setlocal tabstop=4
setlocal softtabstop=4
setlocal shiftwidth=4
setlocal textwidth=79
setlocal smarttab
setlocal expandtab
setlocal smartindent

One last note
Make sure indent and plu­g­ins are turned on in your .vimrc

filetype plugin indent on


  • Very nice, thanks. One ques­tion: Under debug­ging you say you can clear break­points with F8 — but then you imme­di­ately sug­gest map­ping F8 to run. Was that a mis­take or do you really over­ride the former?

  • Ah thanks for point­ing that out. It was an error. Clear­ing break­points is done with shift-f7

  • Fol­lowed your link here; cer­tainly a far more com­pre­hen­sive look at what you can do with Vim than my own! Cheers, I’m going to have to set this up :D (and then imme­di­ately regret it when I ssh to another box at work and realise I don’t have a nice vim any­more :p).

  • Every time i come here I am not dis­s­a­pointed, nice post

  • I’m glad you enjoyed it.

  • lonecat Linux Unknow wrote:

    Great post. I’m not that much into python, but I’ve grown my vim to be a (Cookie) Mon­ster :D. Have you tried NERD_snippets and NERD_tree? check this out:

  • Johnathan Windows Vista Firefox 3.0.10 wrote:

    The indent/python.vim file’s han­dling of com­ments is fine, actu­ally. No need to edit it.

    It’s smartin­dent that is mess­ing the com­ments up, because it’s meant for C-like lan­guages and assumes ‘#’ is the begin­ning of a pre­processer instruc­tion. smartin­dent is really only meant to be used if you don’t have a smart inden­ta­tion file around, and with indent/python.vim you do!

    It really isn’t adding any­thing you need either, it just does some not-quite pythonic inden­ta­tion around ‘{‘ and ’}’, and inden­ta­tion after C key­words like ‘switch’ or ‘do’, all of which is get­ting over­rid­den by the python indent file. The only thing smartin­dent is still doing is mess­ing up lines start­ing with ‘#’. Even after edit­ing the indent file in the man­ner you sug­gest, I sus­pect smartin­dent will still stop you from being able to move com­ments to the right with ‘»’.

    So just don’t use smartin­dent on python files. Change the last line of python_pep8.vim to be “set­lo­cal nos­martin­dent” and your inden­ta­tion should still be just as auto­matic and pretty much exactly the same, just with­out messed up com­ment indentation.

Leave a Reply

Your email is never shared.Required fields are marked *

To submit your comment, click the image below where it asks you to...
Clickcha - The One-Click Captcha