I prefer to use vim for most of my systems administration and programming related editing tasks. Aside from the usual argument that it will be present on any *nix system worth its silicon that you log in to, I choose it because of the succinct and expressive power of its syntax. While I am still learning new commands and techniques all the time, and while it is true that the learning curve to be anything resembling proficient is rather steep, few editors can boast such a wide range of actions in so few commands.
Right of out the box, however, vim isn’t as suited to editing Python code as it could be. In fact, it’s rather annoying to write Python code with an uncustomized instance of vim. What follows is a description of how to put into place what I see as the most essential features of the editor one chooses to write code, especially Python code, in as manifested with vim. With the following changes, you can create a highly customized and powerful IDE, allowing you to increase your productivity without purchasing a commercial offering.
Before the good stuff, a few requirements. You need to make sure you have vim-full and vim-python installed. Some systems come with vim-minimal, which is lacking in many advanced features. These packages should be in most repositories.
Aside from these package installs, configuration changes described are made in ~/.vimrc. A quick word on the syntax of this file. Double quotation marks denote a line as a comment. I make it a rule to place a comment line before every configuration line or block thereof, so I have some sense later of what the change was for (it’s amazing how fast syntax leaks out of my head when I don’t use it regularly). Regarding Python files, I eventually also began to collect the related customizations into a file “~/.vim/ftplugin/python.vim”. This is loaded whenever Python type files are opened, and allows me to isolate related configurations.
Having code displayed with proper highlighting of the logical components makes reading that code easier to read and understand. Any decent code editor allows for coloring particular to a number of languages, and vim is no exception. To get this working, simply add:
to your ~/.vimrc file. The actual colors will vary with your colorscheme. You can install new colorschemes (view hundreds here), as well as test out installed ones by typing
The various colorschemes will appear as you tab.
Having line numbers displayed with code makes it easier to reference and move around in. It’s easy to add. In ~/.vimrc:
# Turn on line numbers:
# Toggle line numbers and fold column for easy copying:
nnoremap <F2> :set nonumber!<CR>:set foldcolumn=0<CR>
This will allow you to toggle line numbers (as well as the spaces for the fold column described below) on and off by pressing <F2>. This makes it easy to copy out code without numbers.
Proper indentation and formatting
In Python more than almost all languages, indentation is essential, both to get right and to preserve. While most programmers add indentation to a wide variety of languages for greater readability, in Python getting this wrong means a syntax error. The following directive will allow vim to properly keep indentation in your Python files, without you having to touch <Tab>:
filetype plugin indent on
Additionally, you need to download the latest version of this script, placing it in ~/.vim/indent/python.vim. This will make indentation much less of a chore, and more of a pleasure. Be sure to also check out this blog post, wherein Henry Prêcheur explains how to improve indentation for comments as well.
To improve the formatting and display of improper indentation, as well as special highlighting for things like string formatting, download the latest version of this script, and place it in ~/.vim/syntax/python.vim. Then add this to your configuration:
autocmd FileType python set complete+=k~/.vim/syntax/python.vim isk+=.,(
Shortcut complete syntax
It can save time and your memory to be able to complete syntactic built-ins using a keyboard shortcut. [Edit: I had one method to get this working before, but it wasn't a good solution. For the right way to do this, check out this post.]
Access to documentation
It is essential to be able to access built-in help quickly. This plugin allows you to view the built-in documentation for a given function by pressing “\pW” while over the word. This opens a new window, containing the related help documentation, if found.
Ability to run script being edited
When debugging, I often need to make a small change, run the program, make another change, and so on. Having to write and close the file, then invoke it, is rather less than efficient. Simply add this to the ftplugin/python.vim file started above:
" Execute file being edited with <Shift> + e:
map <buffer> <S-e> :w<CR>:!/usr/bin/env python % <CR>
Now you can press <Shift> + e to execute the Python file being edited. Once the code errors out or completes execution, output stays displayed until a key is pressed. Then you are returned to the code in the editor. Hard to imagine a shorter method.
Checker utilities and debugging
pyflakes and pylint are two popular utilities for checking Python code for syntax errors, variable reference problems, and other signs of poor quality. If you haven’t tried them, install them both and see which you like best. Install the pyflakes and pylint packages for your system. For CentOS, you will need to add the EPEL repository to get access to these. Then add the functions listed here to your configuration. Now simply run “Pyflakes” and “Pylint” from within vim to view their output on your current file. Once you select the one you prefer, you could shorten access to it to a single keystroke, or even run it when you save your file.
[Edit, 2011-01-23, thanks to Mac Ryan for the heads up:] If you prefer a simpler approach, or want to additionally make sure your scripts are PEP8 compliant, try out the pep8 utility. It’s simple to install and use:
sudo easy_install pep8
> foo.py:3:14: E401 multiple imports on one line
You can run these from within vim as well:
Once you have narrowed down the region you know a problem is present in, you will likely need to add some debugging statements and run the code repeatedly. Adding these functions into your .vimrc will allow you to add a PDB breakpoint with <F7> and remove all breakpoints with <Shift> + <F7>.
As soon as your scripts start to encompass more than a few functions, much less multiple classes, it’s time to start checking out code folding. This feature allows the display of a class, method, or function as a two lines, one with the definition line and another showing length:
With a simple key command, you can display or hide the entire block. There are a number of built-in commands to create and work with folds. I prefer using this plugin to allow vim to automatically know how to fold Python code. Once that is loaded, newly opened Python files will have all their classes and functions already folded, making it much faster to review files. <Shift> + f toggles all folds, while f toggles the fold under the cursor.
This script provides some advanced controls for selecting, navigating within, and acting upon blocks of code. You can jump to the top or bottom of a block, select it, even comment it out all with a few keystrokes.
Nerdtree allows a window to be added to your vim display showing other files in your project. A “project” can either be the contents of your current directory, or you can define its members manually. This allows you to jump around your project, and open multiple files at once:
There are many, many more customizations possible concerning vim and Python. Check around the vim scripts pages if you have a particular itch to scratch. And if you know some good tricks that I didn’t list, please add them via comments!