Python with a modular IDE (Vim)
On Thursday, May 9th, 2008 the Utah Python User Group decided to settle the debate that has plagued us developers since the beginning of time: If you were a programming language, what editor would you use?
I was tasked with showing Eclipse with the PyDev plugin in all its glory–but we all know–real men / developers don’t use IDE’s, so we are going to talk about using Python and Vim together, reaching a state of Zen that the Dalai LLama would be jealous of and establishing more Feng Shui than Martha Stewart’s Kitchen.
Freely jump between your code and python class libraries
There are 2 ways to add your ability to jump between python class libraries, the first is to setup vim to know where the Python libs are so you can use ‘gf’ to get to them (gf is goto file). You can do this by adding this snippet to your .vimrc:
python << EOF
import os
import sys
import vim
for p in sys.path:
if os.path.isdir(p):
vim.command(r"set path+=%s" % (p.replace(" ", r"\ ")))
EOF
With that snippet you will be able to go to your import statements and hit ‘gf’ on one of them and it’ll jump you to that file.
Continuing accessibility of the Python class libraries we are going to want to use ctags to generate an index of all the code for vim to reference:
$ ctags -R -f ~/.vim/tags/python.ctags /usr/lib/python2.5/
and then in your .vimrc
set tags+=$HOME/.vim/tags/python.ctags
This will give you the ability to use CTRL+] to jump to the method/property under your cursor in the system libraries and CTRL+T to jump back to your source code.
I also have 2 tweaks in my .vimrc so you can use CTRL+LeftArrow and CTRL+RightArrow to move between the files with more natural key bindings.
map <silent><C-Left> <C-T>
map <silent><C-Right> <C-]>
You can also see all the tags you’ve been to with “:tags”
Code Completion
To enable code completion support for Python in Vim you should be able to add the following line to your .vimrc:
autocmd FileType python set omnifunc=pythoncomplete#Complete
but this relies on the fact that your distro compiled python support into vim (which they should!).
Then all you have to do to use your code completion is hit the unnatural, wrist breaking, keystrokes CTRL+X, CTRL+O. I’ve re-bound the code completion to CTRL+Space since we are making vim an IDE! Add this command to your .vimrc to get the better keybinding:
inoremap <Nul> <C-x><C-o>
Along with code completion, you will also have call tip support. Here is a screenshot:

Documentation
No IDE is complete without the ability to access the class libraries documentation! You’ll need to grab this vim plugin. This gives you the ability to type :Pydoc os.path or use the keystrokes <Leader>pw and <Leader>pW to search for the item under the cursor. (Vim’s default <Leader> is “\”). Here is a screenshot:

Syntax Checking
Vim already has built in syntax highlighting for python but I have a small tweak to vim to give you notifications of small syntax errors like forgetting a colon after a for loop. Create a file called ~/.vim/syntax/python.vim and add the following into it:
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
Now that you have the basics covered, lets get more complicated checking added. Add these 2 lines to your .vimrc so you can type :make and get a list of syntax 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
You will have the ability to to type :cn and :cp to move around the error list. You can also type :clist to see all the errors, and finally, sometimes you will want to check the syntax of small chunks of code, so we’ll add the ability to execute visually selected lines of code, add this snippet to your .vimrc:
python << EOL
import vim
def EvaluateCurrentRange():
eval(compile('\n'.join(vim.current.range),'','exec'),globals())
EOL
map <C-h> :py EvaluateCurrentRange()
Now you will be able to visually select a method/class and execute it by hitting “Ctrl+h”.
Browsing the source
Moving around the source code is an important feature in most IDE’s with their project explorers, so to get that type of functionality in vim we grab the Tag List plugin. This will give you the ability to view all opened buffers easily and jump to certain method calls in those buffers. Here is a screenshot of it in action:

The other must-have feature of an IDE when browsing code is being able to open up multiple files in tabs. To do this you type :tabnew to open up a file in a new tab and than :tabn and :tabp to move around the tabs. Add these to lines to your .vimrc to be able to move between the tabs with ALT+LeftArrow and ALT+RightArrow:
map <silent><A-Right> :tabnext<CR>
map <silent><A-Left> :tabprevious<CR>
Debugging
To add debugging support into vim, we use the pdb module. Add this to your ~/.vim/ftplugin/python.vim to have the ability to quickly add break points and clear them out when you are done debugging:
python << EOF
def SetBreakpoint():
import re
nLine = int( vim.eval( 'line(".")'))
strLine = vim.current.line
strWhite = re.search( '^(\s*)', strLine).group(1)
vim.current.buffer.append(
"%(space)spdb.set_trace() %(mark)s Breakpoint %(mark)s" %
{'space':strWhite, 'mark': '#' * 30}, nLine - 1)
for strLine in vim.current.buffer:
if strLine == "import pdb":
break
else:
vim.current.buffer.append( 'import pdb', 0)
vim.command( 'normal j1')
vim.command( 'map <f7> :py SetBreakpoint()<cr>')
def RemoveBreakpoints():
import re
nCurrentLine = int( vim.eval( 'line(".")'))
nLines = []
nLine = 1
for strLine in vim.current.buffer:
if strLine == ‘import pdb’ or strLine.lstrip()[:15] == ‘pdb.set_trace()’:
nLines.append( nLine)
nLine += 1
nLines.reverse()
for nLine in nLines:
vim.command( ‘normal %dG’ % nLine)
vim.command( ‘normal dd’)
if nLine < nCurrentLine:
nCurrentLine -= 1
vim.command( ‘normal %dG’ % nCurrentLine)
vim.command( ‘map <s-f7> :py RemoveBreakpoints()<cr>’)
EOF
With that code you can now hit F7 and Shift-F7 to add/remove breakpoints. Then you just launch your application with !python % (percent being the current file, you can declare your main file here if its different).
Another tweak I use is to have my vim inside screen with a horizontal split, that way I can see the python interpreter and debug while still having vim there so I can easily fix my code. Here is a screenshot of that in action:

Snippets
A great time saver with stanard IDE’s is code snippets, so you can type a few key strokes and get a lot of code out of it. An example of this would be a django model, instead of typing out the complete declaration you could type ‘mmo<tab><tab>’ and have a skeleton of your model done for you. To do this in vim we grab the Snippets EMU plugin.
Check out a great screencast of snippetsEmu in action here
You can get my full setup here
Emacs
Here is a great post on how to do the same with Emacs.
Hey, great post - very useful.
Something happened with your code’s indentation in the debugging section.. a little help there would be appreciated.
Thanks!
Comment by Johnny — May 11, 2008 @ 7:02 pm
Hi,
Good work and Very promising setup.
I am tempted to switch from emacs. I kind of thought I had seen the last of vi. Lets see how long I can hold out.
v.
Comment by Vj — May 11, 2008 @ 7:05 pm
Wow, thorough! I’ll be using these tricks immediately, thanks.
Comment by Kevin — May 11, 2008 @ 7:47 pm
Sorry about the indentation with the debugging code, Heres the file for it: http://sontek.net/dotfiles/vim/ftplugin/python.vim . I also fixed the formatting in the post.
Comment by sontek — May 11, 2008 @ 7:55 pm
I’ve been looking for a good python setup with vim for quite some time. Thanks!
Comment by Jamie — May 11, 2008 @ 11:06 pm
Great post! I am using vim more and more lately and just embarking on a biggish python project. Your tips will really help me this time (except for debugging: real men don’t use debuggers
One thing I keep wondering, is how I could get a python interactive shell inside vim. I guess that is a standard vim feature that I just haven’t found?
Comment by Daren Thomas — May 11, 2008 @ 11:13 pm
Awesome post, What theme are you using?
Comment by Max — May 11, 2008 @ 11:16 pm
@Darren - You cannot get a python interpreter inside vim, The best way to do that is to use a split screen. Open up screen, and then create 2 windows, hit C-a C-S, that’ll create a split. Then open up your python interpreter in one and your vim in the other. It’ll look like:
http://sontek.net/blog_pictures/vim_debugging_with_screen.png
You can also look at my .screenrc and .vimrc to see tweaks I’ve added to make that easier.
Comment by sontek — May 11, 2008 @ 11:20 pm
@Max I’m using Tango theme, you can get it here: http://sontek.net/dotfiles/vim/colors/tango.vim
Comment by sontek — May 11, 2008 @ 11:20 pm
what about a ropelib integration ?
Comment by marco — May 12, 2008 @ 12:14 am
@marco:
There is an bicycle repair man integration for vim, works great for refactoring and the ‘goto definition’ works better than all other solutions shown
Comment by steffen — May 12, 2008 @ 12:55 am
Hi. Great post, but I’m having trouble with your basic pythonError syn match statements (i.e. they do nothing). What are they supposed to do? I expected a highlight, but as I said, nothing happens when I forget a colon.
Also, the quotes in all but the first two lines of that section are all non-default quotes which makes them copy and paste as invalid code.
Comment by Jack — May 12, 2008 @ 1:36 am
[...] a wonderful tutorial explaining how to turn my text editor of choice (vim) into a full nice ide for python. [...]
Pingback by Turning vim into a python editor | Neuronical dot Com — May 12, 2008 @ 1:56 am
If you want to have pydoc integration in vim, try this: http://www.vim.org/scripts/script.php?script_id=910
fs111
Comment by fs111 — May 12, 2008 @ 3:43 am
Thanks for the article. There is a bug with some quote signs (guessing from wordpress):
“^\s*finally\s*$”
Easily fixed, of course (:%s/[“”]/”/g)
Comment by Johannes — May 12, 2008 @ 3:49 am
Thanks for great tips! I have just switched from PyDev to Vim and I’m really pleased :). I also use NERDTree plugin which works great for browsing Python packages.
Comment by Artur — May 12, 2008 @ 4:23 am
HiJohn!
A great article/howto… very nice! But in my newbie condition, anything run as is supposed…
After looking for a “vim” module for a python, I find a vim.py, but here it is the error message when I make an “import vim” in a python shell:
>>> import vim
Traceback (most recent call last):
File “”, line 1, in
File “/usr/lib/python2.5/vim.py”, line 1
^
SyntaxError: invalid syntax
Anybody could help me, please? I would like to start learning something about python (this type of articles encourage me).
Thank you very much!!
Regards
Comment by TooManySecrets — May 12, 2008 @ 4:38 am
[...] are a couple of good resources for configuring Vim and Emacs for Python development. I know more key-bindings with Emacs than Vim, so my preference is [...]
Pingback by Nick Carroll » Blog Archive » Old School Editors for Python Development — May 12, 2008 @ 4:48 am
in your ctags link you have an apostrophe after the url link.
and thankies vewwy vewwy muchies for this. I’ve been looking for an article like this for a long time.
Comment by imonsei — May 12, 2008 @ 5:27 am
sontek ( John M. Anderson ) » Python with a modular IDE (Vim)…
sontek ( John M. Anderson ) » Python with a modular IDE (Vim)…
Trackback by roScripts - Webmaster resources and websites — May 12, 2008 @ 6:14 am
These are great, thanks.
I am still working through them, but found that for the ‘gf’ jump to a library file, your _vimrc must also contain the line ’set suffixesadd+=.py’. Maybe somewhere in filetype handling is a better place for this line?
Comment by Kevin — May 12, 2008 @ 8:46 am
I have this thing where i really dont like random trailing whitespace in my code, as it can make navigation of the file annoying sometimes. So I have found the following two bits to be very helpful:
au BufWritePre *.py mark `|:%s/\s\+$//e|normal “
nmap m`:s/\s\+$//g“
The first will delete trailing whitespace on save. The second will delete trailing whitespace from the current line when you hit the Tab key, in normal mode.
Also: set list listchars=tab:»·,trail:·,extends:$,nbsp:=
will make fancy markers show whitespace at the end of a line, so it’s visible for me.
Comment by Erich — May 12, 2008 @ 10:23 am
Configurar Vim como IDE de Python…
Conjunto de recetas de configuración y plugins que ayudarán a los usarios de vim a configurar este editor como IDE de Python que poco tiene que envidiar a otras opciones mucho más "pesadas"….
Trackback by meneame.net — May 12, 2008 @ 10:55 am
Python Scripting mit der “Vim-IDE”…
Ein netter Artikel, um seinen vim für das Programmieren mit Python zu konfigurieren. Hab ein paar nützliche Ideen daraus gezogen, die noch nicht in meiner $HOME/.vimrc standen….
Trackback by /dev/linkdump — May 12, 2008 @ 11:01 am
[...] sontek ( John M. Anderson ) » Python with a modular IDE (Vim) skill vim config to turn it into a python IDE (tags: vim) [...]
Pingback by links for 2008-05-12 | a convenient truth — May 12, 2008 @ 11:34 am
If you want to make additions to the Python syntax file, put them in ~/.vim/after/syntax/python.vim. Using ~/.vim/syntax/python.vim will override the system’s version.
Comment by Will — May 12, 2008 @ 11:56 am
[...] hay varios artículos sobre vim además del mencionado anterior, como por ejemplo uno sobre usar VIM como IDE para Python y una pregunta sobre porqué usar VIM: Can someone explain the advantages of emacs/vim/nano over [...]
Pingback by doce cosas : vim — May 12, 2008 @ 1:26 pm
I seem to be missing something fundamental, since no where online can I find the solution to this.
Where is the Python VIM module? (vim.py)? It is not included in my MacPython release for OS X.
I would love to switch to VIM on OS X, but I can’t seem to get the first step working…
Blaine
Comment by Blaine — May 12, 2008 @ 3:38 pm
Ok, so any help with OS X would be appreciated. With the ctags command, -R is apparently an illegal option?
Thanks!
Comment by Blaine — May 12, 2008 @ 3:46 pm
[...] Python with a modular IDE (Vim) (tags: python vim programming tips development vi software) [...]
Pingback by toshism » links for 2008-05-13 — May 12, 2008 @ 5:43 pm
[...] Python with a modular IDE (Vim) Awesome tips for attaining vim + Python nirvana. (tags: vim python programming tutorial) [...]
Pingback by links for 2008-05-13 — May 12, 2008 @ 10:37 pm
[...] sontek ( John M. Anderson ) » Python with a modular IDE (Vim) (tags: development python vim vi howto) [...]
Pingback by links for 2008-05-13 « Breyten’s Dev Blog — May 13, 2008 @ 4:30 am
[...] been giving Django a try. John Anderson posted a very detailed, excellent blog post about using VIM as a python IDE. If you follow that post, and use synic’s colorscheme, you pretty much have my IDE [...]
Pingback by Here we are now, entertain us » Vim as a Django IDE — May 13, 2008 @ 7:43 am
[...] sontek ( John M. Anderson ) » Python with a modular IDE (Vim) These are now in my ~/.vimrc. Turns vim into a very nice IDE. (tags: programming python vim development editor tips) This entry was written by delicious, posted on May 13, 2008 at 6:49 pm, filed under del.icio.us. Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL. « Twitter Updates for 2008-05-10 [...]
Pingback by Reign Drops Fall… » links for 2008-05-14 — May 13, 2008 @ 5:48 pm
@Blaine
In no specific order:
the ctags you need is exhuberant ctags, not the manky old ctags found by default in OSX. the command ‘ctags –version’ should return:
Exuberant Ctags 5.7, Copyright (C) 1996-2007 Darren Hiebert
Compiled: Sep 19 2007, 17:15:34
Addresses: , http://ctags.sourceforge.net
Optional compiled features: +wildcards, +regex
This is the ctags you need for all vim ctags magic.
the vim python module requires that your vim be build with python. run either ‘vim –version’ in the the shell or inside of vim “:version”
you need to see +python in the output of those somewhere. if not you’ll need to recompile
Comment by chiggsy — May 14, 2008 @ 5:45 am
Why ~/.vim/ folder isn’t created on my system? I’ve used vim to edit some files, so I’m not starting it for the first time. Anyway the directory has not been created. What’s wrong? I’m using Ubuntu 8.04.
Thanks!
Comment by Andrea Grandi — May 14, 2008 @ 8:36 am
Great job. Thanks a lot !
Comment by Martin — May 14, 2008 @ 1:42 pm
If you have a svn checkout of Python you can get the most up-to-date version of the syntax file in Misc/Vim/vimrc . It’s auto-generated so it is as up-to-date as the Python interpreter you use to run the script that creates the file (it’s in the same directory). It is also structured to support PEP 7/8 (the style guides for Python).
Comment by Brett — May 14, 2008 @ 6:11 pm
@chiggsy
Thanks for the help man! I’ll recompile vi and see where it gets me.
-blaine
Comment by Blaine — May 15, 2008 @ 6:18 pm