Why I can never leave VIM as an IDE
This article is about typical stuff I do in my daily job as a software engineer. It’s about VIM, so I probably get all the EMACS hate here. But, contrary to popular belief I do not think that VIM is awesome. VIM is awesome, but it’s not awesome because it’s VIM. It’s awesome because it’s a tool that gets the job done in less time (at least for me) than any other tool.
It kind of should be a typical argumentative article, so it’s also kind of work-in-progress and I’ll update it whenever people ask me “what’s that” seeing me do stuff in VIM ;-)
Having told you about that makes me feel better, so let’s dig into some neat VIM tricks I’ve learned over the years and that made me more productive.
VIM Plugins
I know there’s a widespread opinion on how to use plugins, how to configure them and how to integrate them with your vimrc. There are lots of different ideas out there on how to structure it, how to use something like event bindings (for active plugins) for overriding settings etc. pp.
But I have to say that Vundle worked best over the years and it probably will work forever (I hope so). The awesome thing about Vundle is that it’s integrated with github directly, so you get clean updates via git (which is probably installed anyways on your system) without having to do anything manually yourself. If you have your own configurations in the right place, everything will work instantly.
Over the years I’ve tried many many plugins to see whether they help me getting more productive. Some plugins helped, others reduced VIM speed so much that everything felt laggy.
If you’re curious about my VIM configuration, you are welcome to fork, modify and use it however you like. I split up everything in a plugins.vim, settings.vim and mappings.vim scheme to keep my head from going insane.
My list of awesome plugins over the years are these:
- Vundle for plugin installation
- editorconfig-vim for automatic tab-mapping and indentation of foreign projects (looking at you, 2 whitespace JS guys -_-)
- supertab for awesome autocompletion reduced to its maximum efficiency
- vim-powerline is a must anyways
- syntastic for syntax sugar and automatic validation
- typescript-vim for typescript integration (daily business job)
- vim-explorer (my private fork of NERDtree, focus on speed and performance and better default settings, also for remote ssh folders using gvfs or mounts on Linux)
Refactoring huge codebases
Sometimes, pretty often, I need to refactor an old codebase and migrate it to modern standards. Regular Expressions are essential knowledge in a daily VIM usage, if you know them well they’re pretty awesome.
In the latest lychee.js Engine release I wanted to migrate to the meanwhile specified and accepted Object.assign ES6 method. The previous method that implemented the identical API was lychee.extend.
When things change in future, we migrate stuff to modern standards. So we do for all polyfills that we have in place. We love Object.map, Object.values, Object.find and other lambda-friendly (arrow functions) helper methods as they lead to better code quality that is easier to read and follow.
In Linux there’s the awesome GNU tool grep which allows you to search pretty much anything in the filesystem using regular expressions. Using sed in the past often have led me to problems with whitespaces and it’s hard to turn your head around with xargs to proper use it, also sed is quite often totally different in the accepted syntax across BSD and GNU/Linux variants.
Luckily, you can edit multiple files in VIM using something like this:
vim file1.js file2.js yougetthepoint.js
As there’s grep, you can also search the filesystem recursively for regular expressions:
grep -R "extend" ./libraries/*/source;
(...) list of a bunch of files
If you now want to use VIM to open all files matching a regular expression pattern, you can use this:
# bash / Shell expands arguments automagically
vim $(grep -rIl "extend" ./libraries/*/source);
You now have opened multiple buffers in VIM (you can switch them via :bn and :bp) and you can also use replacement commands across all opened buffers via:
# Use this inside VIM
:bufdo %s/lychee\.extend/Object.assign/g | update
VIM macros for complex tasks
If you’re unfamiliar with VIM macros, I can really recommend going through this superquick tutorial here. The important part to know beforehand is that VIM macros use registers (imagine them as named variables). VIM macros are very very powerful if you use them for very repetitive tasks. You can use them to select code passages that have a given structure, use regular expressions and pretty anything you can use in VIM (even the go-to line command).
So, for example, if you want to replace lines of a JSON file you could write your own macro for it to replace it line-by-line (somehow stolen from the VIM wikia because the tutorial really covers the strength of macros):
// This is the JSON file
data = {
'foo': 'first',
'bar': 'second',
'qux': 'third'
};
If you want to record a macro for refactoring the JSON data line by line, you can use these steps to do so:
- Put the cursor on the first line (to the beginning)
- Use <q>,<q> to record a macro with the register “q” (qa will use register “a” later to play back the macro).
- Use a regular expression to change the whitespaces to ’: ‘ by using this and press <enter> afterwards.
:s/\s\+/': '
4. Change the start of the line by inserting four whitespaces in the beginning by typeing “<shift>+<i>, <space>,<space>,<space>,<space>” and press <ESC> afterwards.
5. Append a trailing comma by typing <A>,<’>,<,> and press <ESC> afterwards.
6. Correct the cursor to get to the start of each line by typing <0>, <j> (zero-jay)
7. End the macro recording mode by pressing <q> again. Now you can replace lines by using the macro playback binding, which is <@>,<q> (<shift>+<2>, <q>). You can also repeat macros multiple times, for example 13 times by typing “13@q”.
Now, if you figured out how to use macros wisely to refactor a codebase, you can do pretty much anything. If you have a regular expression as a search, you can also jump across the codebase and refactor whole codeblocks, method, for loops without any manual repetition. It takes a while to get your head around it, but VIM macros are pretty awesome.