My Learning Experience with Vim
I’m not going to go into the details of how to use Vim – there are plenty of tutorials out there already for that. I will briefly explain how I started and learned vim.
My entire curiosity with it started from hearing stories from co-workers about people who could code extremely quickly using vim. I always assumed it would be a lot faster than a regular IDE, but I never wanted to invest the time into learning it. Then one day I went to a hackathon where I worked, and one of the coding challenges was to swap halfway with the developer sitting behind you.
Most everybody in that room used the standard Eclipse IDE (including myself), but the guy behind me was using vim. The next 20-30 minutes featured a very embarrassed Tim asking aloud how I was even supposed to save my code. Not one to be tripped up so easily, this was the turning point for me. I would learn vim!
I saw that the Eclipse IDE has a plugin for Vim. This was perfect. I could still use all the hotkeys I already used in Eclipse, and, over time, swap from using so many Eclipse hotkeys to using Vim. As a general rule of thumb, I strongly recommend this approach to tackling any problem – try to find the tiniest, simplest thing you can tackle first and build up from there.
So I found my entry point. Fast forward about a year or two later and I used vim entirely for development. I wanted to make sure my Vim learning did not affect the pace of my development, so I never did a deep dive until I had some downtime for a few days.
Now I can open multiple code panes, swap between them, and several other shortcuts in vim. But in this post I would specifically like to talk about my test setup using some hotkeys.
Using an IDE for Development and Testing
To begin, let’s describe some other IDEs and common things in them. Generally they have a way to build code, and often they will have a way to run and debug code (for the record, I still have not learned debugging through Vim). This can get bad if any of those things (building/running/debugging) becomes specific to that IDE. For example, if you let Eclipse generate your makefiles and other developers don’t use Eclipse, your commits to version control could potentially (and unintentionally) overwrite others’ manual edits that they committed. We ran into this at one of my previous jobs. The result was developers using Eclipse sometimes didn’t compile in new source files. Developers shouldn’t be forced to use an IDE – it should be a choice. Code should be able to be built and tested outside of that IDE (especially when you take into consideration build servers).
Some IDEs will allow you to specify your own commands for building or testing. In a similar way, Vim will allow you to map a custom hotkey to certain commands (anything you can execute in the shell). This provided me potentially one of my most productive TDD development environments I’ve ever had.
TDD and Vim
Vim allows you to define custom hotkeys in a ~/.vimrc file. The one I’ve used was mapping the “,r” keys (that’s a comma followed by a lowercase r) to run nosetests (and save all the currently open files). Specifically…
<span class="pl-c1">nnoremap</span> ,<span class="pl-c1">r</span> :<span class="pl-c1">wa</span> <span class="pl-c1"><bar></span> <span class="pl-k">!</span>nosetests <span class="pl-k">--</span>exe <span class="pl-k">--</span>nocapture <span class="pl-k">--</span>with<span class="pl-k">-</span>coverage <span class="pl-k">--</span>cover<span class="pl-k">-</span>branches <span class="pl-k">--</span>cover<span class="pl-k">-</span>inclusive <span class="pl-k">--</span>cover<span class="pl-k">-</span>html tests<span class="pl-c1"><CR></span>
(you can actually see my vimrc in on my Github repo: https://github.com/tscott8706/vim)
Since I’ve written that code, I’ve realized I can put all that nosetests setup stuff in a config file (and I’ve also experimented with running a Docker container, but sometimes even that is too slow for me – I don’t want to wait 1 or 2 seconds for the container to run… yes, it’s ridiculous. I don’t care. I like to go extremely fast in these TDD cycles.) If I have that config file in a directory, I can start Vim in that directory, use the Ctrl-P plugin to open any file in that directory. Then the ,r shortcut can be used to just run nosetests.
So I open up two files, the source file and the test file, side-by-side within Vim. It looks similar to the following picture (see how two files are open side-by-side?).
Here’s my workflow using hotkeys and using the principles of TDD:
- Start in the test file. Write a failing unit test.
- ,r to run the unit tests and verify it fails.
- Press a key to exit the nosetests results and get back into Vim.
- Press Ctrl+W+K (assuming the source code is the window pane on the right) to get to the source code file.
- Type the code to get the test to pass.
- ,r to run the unit tests and verify the unit test now passes.
- Refactor any of my tests or source code as necessary. ,r to verify unit tests still pass after the refactoring.
The magic sauce in all of this is that I usually don’t touch the mouse. It seems trivial, but I type around 80 WPM (last time I checked, who knows if I’m faster or slower at this point). Reaching for the mouse takes away time from my flow. When I can use hotkeys to almost instantly run tests after source code or test code edits, and the unit tests run quickly, there is no interruption in my concentration. I don’t have to wait for more than a second or two for anything to happen. So I still maintain that highly focused state.
As a future exercise, I may try something like tmux or another terminal with nose-watch running (nose-watch runs tests automatically with every filesystem change). This would eliminate me even having to do the ,r hotkey. Every time I saved my file, I could see the results of my test run. This works well when your tests run quickly, but not as well when your tests take a while. So keep your unit tests short and sweet like they are supposed to be!
You do not have to learn Vim to gain the advantages I discuss in this post. My main purpose is to promote the use of hotkeys and automation where you aren’t having to point and click so much to do things you do several times in a day. Don’t force yourself to scroll your mouse up to a button in an IDE to build code or run a test; this is something you (hopefully) do many tens of times a day. You can make that process save you a second or two every time, which can add up when you consider the concentration you will be maintaining and not losing focus.
Personally, I really, really, REALLY enjoy when I get into a state like this. I develop code extremely rapidly in this state and it’s very rewarding and fun. Others may not get the same enjoyment that I do from something like this… but why not give it a try?
What tricks or tips have you used with your IDE to speed up your development workflow?