Python and vim: Make your own IDE
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. 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.
- Syntax highlighting
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:1syntax onto 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
1:colorschemeThe various colorschemes will appear as you tab.
- Line numbering
Having line numbers displayed with code makes it easier to reference and move around in. It’s easy to add. In ~/.vimrc:1
2
3
4# Turn on line numbers:
set number
# 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>:1filetype plugin indent onAdditionally, 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.
- 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:1
2" 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.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>.
- Code folding
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.
- Block navigation
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. - Project navigation
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:
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:
1 | autocmd FileType python set complete+=k~/.vim/syntax/python.vim isk+=.,( |
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!
Possibly Related (no promises):
- More efficient HTML editing in vim
- Printing tabular data attractively in Python
- A better way to search for methods of Python objects
- Simple and effective Python logging
- Script to find longest running events in log files
Related posts brought to you by Yet Another Related Posts Plugin.
February 16, 2009 - 2:28 AM








Morgan Goose
April 17, 2009 | 10:17 AMsome of your examples are displaying incorrectly:
<Shift> + f
instead of
+ f ?
REd
April 17, 2009 | 2:39 PMmap :w:!/usr/bin/env python %
doesn’t seem to do anything….
mico
April 17, 2009 | 7:31 PMman it’s hard to read with > everywhere
Davos
April 17, 2009 | 8:24 PMsome great tips here, nice post!!
Morgan Goose
April 17, 2009 | 9:27 PMWorking though these tips, make me love vim even more. I’d seen some of these but not all, and had not realized how useful they would be until now. Thanks for the tips.
Samuel Huckins
April 18, 2009 | 9:41 AMSorry everyone, it seems I opened this post once in WYSIWYG mode, and Wordpress made a mess of some of the characters. I believe I have fixed them all.
Glad the tips were useful! I am still finding more all the time.
@REd: The above-mentioned code mangling messed that part up as well. Check the fixed code above and give it a try, I just tested and it does work.
Tim
April 19, 2009 | 7:55 AMThere is a different way to run the script that you are editing.
First line of the script has to be something like:
#!/usr/bin/env python
You have to make the script executable:
chmod a+x scriptname
Then while you are editing:
:w
:!scriptname
Sérgio Luiz Araújo Silva
April 19, 2009 | 6:16 PMSnipMate
http://www.vimeo.com/3535418
site: http://www.vim.org/scripts/script.php?script_id=2540
Sérgio Luiz Araújo Silva
April 19, 2009 | 6:17 PMFor execute current file do:
:!%
% is the name of current file
Samuel Huckins
April 20, 2009 | 6:56 AM@Tim and Mr. Silva:
The advantage of using the method mentioned in the post to execute the script being edited is that you don’t need to save (the shortcut does that), and you don’t need to make the script executable (the shortcut calls the script with Python). Just open a file ending in .py, type something that can execute, and then Shift + e. Seems like the shortest possible method to me, and I dislike typing
Samuel Huckins
April 21, 2009 | 6:34 AMI have been quite impressed with TextMate’s features, which one of my co-workers of the Mac persuasion has been eagerly showing me. SnipMate looks like a good start, I shall check it out, thanks!
sasa
April 26, 2009 | 2:52 PMI had problems with:
nnoremap :set nonumber!
Solution for me was:
set number
nnoremap :set nonumber!
Source:
http://stackoverflow.com/questions/762515/vim-remap-key-to-toggle-line-numbering/762633
Samuel Huckins
April 26, 2009 | 4:47 PM@sasa Yep, sorry about that. I assumed people would first add the “set number” mentioned, then add the toggle. Glad you got it working!
John
May 4, 2009 | 5:23 PMI think your definition of the gd command is missing the (C-R)(C-W)(CR) (where ( and ) are supposed to be angle brackets, but since I’m guessing that it got lost as part of the double entity conversion, I’m not using the angle brackets).
But more importantly, isn’t that gd command, and the Shift + e command, both already implemented as part of the “Efficient python folding” script you link to?
Anyway, my suggestions are to get an updated syntax/python.vim (it can go in your .vim/syntax folder and will override the older version shipped as part of runtime). Though if you’re using a heavily patched Linux distribution, this might already be present instead of the upstream vim version. Also watch that you download the python.vim from there, since there are also python3.0.vim scripts on the same page for Python 3.0.
Either way, be sure to add “let python_highlight_all = 1″ to your .vimrc (I couldn’t get it to work when inside ~/.vim/ftplugin/python.vim, but I don’t even really understand the difference between let and set, and why some lets have g: in front of the option name). It adds nice extra highlighting like showing when you have excess spaces on the ends of lines or incorrect indentation (with bright red backgrounds on my color scheme). And I suspect “let python_slow_sync = 1″ helps fight against the loss of syntax highlighting that happens sometimes when editing a large file.
Also adding an indent/python.vim makes it much nicer, though you might want to follow this blog post with instructions for fixing comment indentation, or just “set nosi” for python files which also fixes it. That blog post also mentions some PEP-8-compatible tab settings which you might want to add to your suggestions.
Also, I like to always have line numbers on in gVim but never in vim, so I use something like:
if has("gui_running")
set number
set numberwidth=4
set columns=84
endif
I haven’t really gotten into folding, though reading this post has made me more interested, especially since a quick browse of the vim help has shown me “set foldlevelstart=99″ for never starting with stuff folded. I’ve added “set foldcolumn=1″ and upped the columns to 85 for my GUI to see if I start using it.
Samuel Huckins
May 5, 2009 | 8:48 PMJohn,
Goodness! Thanks for all that information.
You are correct about the command duplication. I collected these things from a variety of sources, and didn’t have everything quite straight.
That link for the latest Python syntax file is quite helpful. I was concerned about a good way to keep that updated.
Concerning folding: I have had one major qualm thus far. When I have multi-line strings, aside from docstrings, I have to start consecutive lines at the far left, to avoid unintended indentation in the actual string. This has foiled the folding methods I have tried thus far. They fold the parent function to the point of the string, and then just stop the fold. It’s very disconcerting, almost to the point where I have considered disabling folding altogether. Perhaps your not folded by default fix will be enough.
Thanks again!
octopusgrabbus
May 25, 2009 | 1:44 PMThank you. This was a very helpeful post. The only thing I had to change was to remove comments. They caused errors on startup on python 2.6.2.
Samuel Huckins
May 25, 2009 | 2:27 PM@octopusgrabbus Not sure what you meant about removing comments. Could you post the error you were seeing? The box I work on most with this configuration has Python 2.6.2, and I don’t get any errors.
Glad it was otherwise helpful!
alterecco
May 26, 2009 | 3:54 AM:set invnumber
that should do the trick for numbers, whether you have numbers on or off