Old habits die hard. I have been using 3 space indents for C and C++ code for as long as I have been a programmer. A little over a year ago I dove head-first into Python, and eventually discovered PEP 8. PEP 8 is basically the style guide for the Python community. I read it with great interest and took just about everything to heart, except for the recommended 4-space indents. I just could not shake my old habit.
Eventually as I got more and more excited about Python I decided to wholly embrace the customs of the community. But how could I easily tell my favorite editor Vim to use 4-space indents for just Python code? I still do a lot of C++ at work, and I still like 3-space indents in other file types.
My first attempt was to use a Vim modeline embedded right in my source files. At the bottom of my Python files I placed this line:
# vim: set sw=4 ts=4:
When Vim first opens a file, it scans the first and last few lines in the file, looking for modelines, and will use the settings just for that file.
This obviously worked, but soon I found it ugly and distracting to have that at the bottom of each file. And sometimes I would forget to put it there, and not realize it until a bunch of code had been written.
It turns out there is a far easier way, but it took some digging to discover. Vim has a very elaborate system of determing file types. If you peek into your Vim installation directory, you’ll see a ftplugin directory. This directory is full of little files that get executed once the type of a file has been determined. Some people on the Web suggest that you should modify these files directly. Thus I could modify the ftplugin/python.vim file, and place my tabstop and shiftwidth settings in there. But you would be modifying a Vim file, and your changes would get lost the next time you upgrade Vim.
There is a much better solution. After Vim executes the python.vim file in the ftplugins directory, it looks for a file called ~/.vim/after/ftplugin/python.vim (on Unix; on Windows I’ve had luck with C:\Progam Files\Vim\vimfiles\after\ftplugin\python.vim). If this file exists, it will be executed after the “official” python.vim file.
Inside your personal python.vim file, the documentation says to use the “setlocal” instead of “set” command. Thus, my file looks like:
setlocal tabstop=4 setlocal shiftwidth=4
Although to be honest, I’ve used the regular set for some time (by accident) without seeing any strange effects.
Happy Vimming!
Tags: vim
I love the text editor Vim. I started using Vi because I really didn’t know any better around 1988 when I was first teaching myself C on my trusty Amiga 500. Not long after that I discovered Vim which sported many improvements over the venerable Vi. Sometime around 1993-1994 I started hacking Vim. I added a complete ARexx port to Vim so that you could script it. Alas, a new version of Vim came out right after I finished, and author Bram Moolenaar had changed the code so much I felt it was impossible to merge my changes into the new version. This was when I was a young pup programmer, and I was unfamiliar with revision control and difference/merging tools. I had fun doing it anyway, so I just chalked it up to experience.
I have used Vim on every programming task at every job I’ve had. I’m constantly learning new things about it, and the commands and keystrokes are now part of my DNA. I don’t even think how to execute commands anymore and I am often hard pressed to recall them to others learning Vim. I have to sit at a keyboard with Vim running in order to understand what my fingers are doing.
A while back, I discovered the auto-complete feature, where you type Ctrl-n in insert mode and Vim will attempt to complete the word you are typing based on all the words in all buffers and how frequently they occur. This is incredibly handy when programming to quickly pound out those function and variable names. I used “imap <S-Tab> <C-n>” in my .vimrc file to map this to shift-tab, which I felt was more convenient.
I also picked up a really handy way to cycle through all your buffers. I used the tab and shift-tab mapping mentioned in that Vim tip. Combine that with Vim’s tab feature I can very easily find the file I am looking for.
And finally I had another big “wow, Vim can do that?” moment just last week. Since version 7, Vim has sported an “omni-complete” framework. Basically it is an architecture for people to hang code completion routines into Vim. In fact, right out of the box, Vim 7 has support for Javascript, CSS, and yes, even Python! Python completion is only available if you are using a version of Vim that has been compiled with Python support (e.g. on Ubuntu). Imagine my shock when I was editing a CSS file and I typed “display:” and then hit Ctrl-X Ctrl-O for the first time and a drop down list of all the possible values (inline, block, none, etc) appeared! No more hunting for that w3schools website. And the Python support is just as handy. Type “os.path.” followed by Ctrl-X Ctrl-O and you can see all the entities and function in the os.path module. I had no idea!
So all of this reminds me it is time to once again donate to the Vim project. Thanks Bram for all your amazing work you do on this invaluable tool.
P.S. I have no interest in the great editor holy war. Use a tool that you find intuitive and useful and learn it, back to front. I’m sure there is nothing wrong with other popular editors. But for me, Vim is it. I can’t imagine how many hours of productivity it has given me over the years.
Tags: vim