Read my book

I wrote books about Webpack and React. Check them out!

Tuesday, July 10, 2012

Vim - A Programmer's Best Friend

What is the easiest way to generate a random string? Tell a freshman to quit vim. That's the joke anyhow. There's some truth to it. Vim can seem somewhat alien at first.

I have used Vim as my main editor for around a year now. I still have plenty to learn about it. I believe it takes a lifetime to master it and to make it truly your tool. Vim is one of those tools you really have to retrofit to suit your purposes.

I used to swear by real IDEs before. These days I pretty much use Vim solely. I have a couple of terminals on my screen estate in which I perform various tasks (revision control etc.) and have editors open on demand. Usually I have a web browser right next to these terminals.

Some people use just a single terminal and navigate within Vim. I guess that can work too. It's really depends on what kind of workflow you prefer. There are guys that like to use some more graphical version (gVim, macvim, recently open sourced Vico come to mind). You can even get Vim bindings for the most popular IDEs so there is really no excuse to at least learn a little bit about it. Be careful, though. You just might get vimfected. :)

In this post I aim to provide you some basic knowledge on Vim. I will go through the basic philosophy and show you how to untap some of its power using various options and a couple of plugins.

What Makes Vim So Great?

Switching from Vim to Emacs by Abstruse Goose
To be honest, the first time you start using Vim it's going to be somewhat underwhelming. Despite this there is an immense amount of power beyond that simple shell you see. If you can access even a small amount of functionality in Vim, you'll be way more productive than in your regular editor.

Say goodbye to your Notepad (most modern IDEs are just glorified Notepads) and enter the era of productivity! Even if Vim isn't your thing, perhaps Emacs is. You are in a winning team either way. You can even use Vim bindings in Emacs if you really want to or the other way around.

The greatness of Vim lies in its extensibility and configurability. Most of the magic happens in your .vimrc and .vim directory. Especially configuring your .vimrc file right is one of the keys in unlocking its power. .vim directory is used for storing your plugins. I have set up Pathogen, a package manager as instructed by Mir Nazim to make it easier for me to deal with that.


Lord of the Modes


Keyboard from ADM-3A computer terminal. Source.
When you start Vim, you'll find yourself in normal mode. It is effective to traverse in this mode. You can jump around quite effectively and search (/) fast using regular expressions. In addition to search, I use :, gg (jump to start) and G (jump to end) a lot.

If you haven't used Vim before, you probably should go through vimtutor to get some idea of the basic navigation. You might also find Vim Adventures and Openvim tutorial interesting.

The image above contains the reason why hjkl are bound as arrows. The idea is that it's more effective to use the home row as your fingers don't have to travel a lot that way. That's why hjkl are so popular amongst vimists.

I think hjkl is not ideal. You still have to move your fingers around a little bit. That is why I have remapped the keys to jklö on my Finnish layout. You might want to do something similar if you feel uncomfortable with the default hjkl.

Insert and Visual Modes

As just hopping around is kind of boring, there is also a insert mode (enter using i) and a visual mode (enter using v). The latter is used for selections and moving fragments around. Insert mode is where you produce your magnificent code, text or whatever it is you do.

Commonly your workflow might look like this while performing some Copy-Paste Coding™:
  1. Navigate to selection start in normal mode
  2. Enter visual mode (hit v)
  3. Select some fragment using your navigation skills
  4. (y)ank or e(x)tract it. After doing this you should find yourself at the normal mode again.
  5. Navigate to where you want to add the fragment
  6. (p)aste
Exiting from the insert mode can be troublesome due to the difficult default binding (it's esc). You can also use ctrl-c if you want to. I have bound tab to do the thing for me as it is somewhat conveniently located for my long fingers. Some prefer Caps Lock instead. There are various ways to avoid the dreaded esc key. If you like hardhacks, you could build a clutch to do this.

Basic .vim Settings

By default vim looks and feels somewhat like the good old vi. You will need to manipulate .vim a little bit in order to turn it into something beautiful. I have tried to list some common options next. The listing is likely missing some good ones but at least should give you some starting point or perhaps ideas on how to improve your existing configuration.

Color Scheme

By default Vim looks somewhat bland. It comes with a set of default schemes. You can even create these on your own. I've set the scheme to koehler myself (colorscheme koehler). Some like solarized. If you want to play around with these while in Vim, use :colorscheme . You can try this trick for other options too if you want to.

Syntax Highlighting

As far as I know you will have to use a combination of options to get the best advantage out of Vim's integrated syntax highlighting. The following options should do the trick:
  • filetype on
  • filetype plugin on
  • syntax on

Automatic Indentation

Vim comes with C style automatic indentation. Simply enable it using set cindent. You can also use << to dedent and >> to indent in normal mode. These two, like many commands in Vim, may be combined with a modifier. >5> or 5>> would indent five lines at once. Use % modifier (ie. >%) to modify a whole block at once. Note that you may use sw= option (ie. sw=4) to define how much << and >> shift.

set autoindent is another handy option to be aware of. It simply copies the indentation from the previous line.

The default C style indenter isn't ideal for JavaScript and such. Fortunately there are many other alternatives, such as JavaScript Indent, that should work better. Look around. You might find something fitting for your purposes.

Dealing with Tabs

Vim provides a variety of ways to deal with tabs. I personally have set it up so that tab produces a certain amount of spaces (set tabstop 4 and set expandtab). In case a file happens to contain tabs (argh!), I've set it up so that they are set to a certain width (set tabstop 4). Given I've rebound tab to esc, I don't use "soft tabs". Soft tabs would allow to to indent while still in the insert mode.

Rebinding Keys

There are multiple ways to bind keys in Vim. The complexity has to do with the fact that Vim is a modal editor as mentioned above. You can bind keys to work based on mode. It is also possible that a binding is either a recursive or a non-recursive one. I currently use following bindings:
  • nnoremap <F2> :set nonumber!<CR> - Toggles line numbers. It is handy to have this set so you can copy material outside in a proper format.
  • set pastetoggle=<F3> - This toggle makes it a lot easier to paste material from the system paste buffer to Vim. Note the special syntax!
  • command W w - This allows you to define custom commands. In this case I made W invoke (w)rite. I have this kind of aliases set for (q)uit, wq (write and quit) and wa (write all, handy if you have multiple files open).
  • noremap j h - This remaps j to h non-recursively. As mentioned earlier, I use this kind of mapping to remap hjkl to something more comfortable for me.

Automatic Word Wrapping

It is possible to make it Vim to wrap your text automatically to the next line using set textwidth. I've set it to 79 (ie. set textwidth=79) given I don't like long lines. Edward Yang has covered some of the more advanced options in more detail.

Line Numbers

This is an easy one. All you need to do is to set number. As I mentioned above it can be handy to have a toggle set up for this.

Show Matching Braces

Here's another easy one. Just set showmatch. If you navigate on a begin brace, it will highlight the end one for you automatically.

Show Ruler

set ruler makes some extra user interface available. The ruler visible at the bottom shows some metadata, such as line number, column number, virtual column number and relative position. You can customize the ruler further if you want to.

Better Search

Vim provides two handy options that can make search (/) more powerful. These are set hlsearch and set incsearch. The former enables highlighting while the latter performs a search incrementally while you are typing it.

Abbreviations

If you notice you are typing some specific word a lot, you might want to take advantage of abbreviations. I have set up one for my Javascript coding. abbr fn function makes it possible for me to just enter fn and then expand it to function by pressing space. Super handy!

File Name Completion

This is another one of those tiny yet powerful tricks. Suppose you are opening a file using :e. It would be handy if you could tab complete the file names as in Bash. You can achieve this if you set wildmode=longest,list.

Spell Checking

If you typo a lot, you might want to enable spell-checking. Simply do this with set spelllang=en_us (that's three l's).

Showing Trailing Whitespace

As a programmer it is really handy for me to see any trailing whitespace. This can be done by set list and set listchars=tab:>.,trail:.,extends:#,nbsp:.

My Configuration

I have made my configuration available. It contains the set up above and a couple of extras I didn't cover here. I know many people have way more elaborate .vimrc. I'm pretty happy with my current simple one. Hopefully the above options give you some idea how to improve yours.

In addition I use a couple of plugins particularly suited for web and JavaScript development. As mentioned earlier I prefer to use Pathogen for managing these. Just to give you some idea of plugins I'm currently using, check out closetag, delimitMate and syntastic. syntastic in particular is awesome. I use it with JSHint. It has saved a lot of my time as it allows me to spot certain errors before getting I get myself in a too big a mess.

Conclusion

Lada - From Russia with Love (CC-BY Ellesmere FNC)
Vim definitely has some history behind it. It might look a bit ugly and feel quirky at times. You will get used to its quirks, though, and learn to love it given some time. It's like Lada pictured above. It might not be the prettiest editor around. But you sure can pimp the crud out of it if you want to. Vim is what you make it.

If you still feel like learning Vim or improving your existing skills, be sure to check out this awesome cheat sheet and tutorial, Derek Wyatt's videos and Bram Moolenaar's thoughts on effective text editing. Especially the last article by the creator of Vim should put you in the right set of mind for improving your Vim skills.