Roland's homepage

My random knot in the Web

Switching to the vim editor

After having been an emacs user for a long time, I was starting to grow disenchanted with it around version 24. My main problem is that it was starting to get really slow. Not just in starting up, but also in daily use, specially it you kept an instance open for along time. I tried switching off bidirectional rendering, which was helpful but not enough.

So I decided to install vim, and give that a try.

Since I spend most of my time in the X Window System, I compiled vim with X support using the GTK2 toolkit. The other option I enabled was Python support.

Vim is a modal editor. This takes some getting used to. Basically you can be inserting text (insert mode) or you can be executing commands (normal mode). See e.g. the documentation. The upside is that in normal mode, all the keys are available for commands, so you don't have to rely on the mouse or on chords (different keys pressed simultaneously) to execute commands.

Another plus is that vim is fast. It starts up fast and doesn't bog down even with a lot of file open. Of course with the speedy startup, it is not necessary to keep a window open all of the time. And when started in graphical mode from a terminal window (using gvim instead of plain vim) it automatically detaches from the terminal, which is nice.

Plugins

Like emacs, vim is also programmable and extensible via plugins.

Everyone has his own list of favorite plugins. Mine (so far) are;

  • pathogen: easy management of plugins. Since a lot of modules are available on github I use git to manage my .vim directory with most of the plugins as sub-modules. To use pathogen, the first command in my .vimrc file is: execute pathogen#infect().
  • the solarized dark color scheme. It's easy on the eyes.
  • syntastic: syntax checking of source code whenever a file is saved. This gives immediate feedback when you are writing code. Very helpful in fixing code now rather than later.
  • ultisnips: fast insertion of often used fragments. This is a real must-have in my opinion. The snipmate plugin is mentioned more often but Ultisnips is more powerful. It needs a vim compiled with Python support but as an upside you can use python code to generate snippets.
  • fugitive: interface for git.
  • cua-mode: for copying and pasting, basically because I'm used to it.
  • auto-pairs: insert or delete brackets, parens, quotes in pair.
  • vim-vinegar: improvements for netrw.

Configuration

You can download my complete vimrc if you want to. But I want to highlight some settings that I found interesting or difficult to figure out, in the hope it helps.

source:vimrc
GPG signature:
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)

iQIcBAABAgAGBQJTJYTaAAoJEED21dyjijPgGdIP/14nOavCV/v2GwTc2/U+NSdo
MOF0ruknLFkeLEfZhaQ9jQuMp5yN6lpq1MrI0r3TNzQF+lmIY9/7Iq2I9YgHLaZr
tqfVMbjBX5UA7GDQ+WeY9uQMs/CjIh6bzPA2WeSj1Z/zhaFz8QfMdypYlKiSZ0yq
KtwYy+BLUYA+gnYXkQTK/y1DtkF1QQaQ0Qn2gjEL2R/Lzlfz4F9E0Zm3po4CbB4s
4Pvs5MBJVyTXVteyZIho4z8csf7dx+cEvFhjQS8i43RZQGgk5Ox5N5jGKoPxM7Qz
Bz3tKzwYcp+YCGNkMajywLaHu+EnpY6Wvk+Ke2DBFdo/OUAqN3B5JrdkhRnmjtPo
AyznOXI7fey5YYa6durnVI9Go78Wm2Rz8ygYI02UjO5r+Nsmwy1/4bQvbriITh5F
svoTg3UeM4xS4WEhV7zDl7i32s9rv5mEcGcrmMTqcFxYSo5ClY9mVRijGn39T3Nf
isReZ5+XTGOseinbG5jJqv1h7Y612FkVx9KT7LRGCI3rYPht/oE44naxlukUVmxZ
Dmnxjf9+ap15qi36LPE9BwnJpMIQXm+qtfLP5n176vrUmjlVK292VndL1NlFNxHc
IORFArsXPVzz6X/if4xLpu4m3oxnrevs3ITSuZG7638iR8O9CR6FHM6P7h3+f0tq
XBcAhM0IF8HZSMRhJaVH
=DOid
-----END PGP SIGNATURE-----
SHA256 hash:8385ff64f81503f4e20bdea4970b3f72622a1967a2c2127c2861f81309343c21

To make use of the pathogen plugin manager, the _first_ command in your vimrc should be:

execute pathogen#infect()

In normal mode, the <leader> key is used to basically get a whole new namespace to link commands to keys. By default this is mapped to the \ key. I find it more convenient to use the comma key:

let mapleader = ","

Compatibility with the old vi is not really important for me, so I've switched that off.

set nocompatible

Using UTF-8 encoding should be an easy decision these days for someone like me who writes mostly in English or Dutch (or one of several programming languages). Unicode is a widely-used standard (ISO 10646) for encoding text, and UTF-8 is an encoding that is backwards compatible with ASCII and Latin-1 (ISO 8859-1). It is not always straightforward to detect the encoding of a file, so it is good to be explicit about this.

set encoding=utf8

Since I keep stuff I care about under revision control with git, I switched off automatic backups:

set nobackup
set nowritebackup
set noswapfile

You can have vim automatically re-flow paragraphs when you insert or delete text. This does not always work well. E.g. in ReStructuredText it messes up headers. So I wrote the following function to toggle that behavior, complete with a message to the user and a key binding in normal mode:

function Toggle_autofill()
    if &fo =~ "a"
        set formatoptions-=a
        echo "Disabling automatic filling"
    else
        set formatoptions+=a
        echo "Enabling automatic filling"
    endif
endfunction
nnoremap <leader>a :call Toggle_autofill()<cr>

Additionally, I've set up a key binding to format the current paragraph:

nnoremap <leader>f gqap

In normal mode, vim can use the h,j,k,l keys to move the cursor (left, down, up, right. You can also use the arrow keys, of course). To move around windows, you can use the same letter keys but you have to press ctrl-w first. I decided to do some remapping to use crtl+h,j,k,l to move around windows:

noremap <c-h> <c-w>h
noremap <c-j> <c-w>j
noremap <c-k> <c-w>k
noremap <c-l> <c-w>l

The status line in vim is also configurable:

set laststatus=2             " always show the status line
set statusline=
set statusline+=%<%f\ %m%r%h " filename and modified indicator
set statusline+=\ %{fugitive#statusline()} " show git status
set statusline+=\ %y%=0x%04.4B\ %4.4l,%v\ %P " file type, charcode, pos

This looks like:

src/howto/vim.rst [+] [Git(master)] [rst]              0x0000  126,62 85%

From left to right we see;

  • the name of the file
  • a status indicator ([+] is unwritten modifications to the buffer)
  • whether the file is controlled by git, and if so the current branch
  • the file type
  • the hexadecimal code-point of the character under the cursor
  • the cursor position in line,column format
  • the cursor position in % of the length of the file

With regard to ultisnips, by default it uses ctrl-k for the backward jump trigger when inserting snippets. This is unfortunate because the default mapping for that key is to insert digraphs, which is a feature I often use. So I added the following code to my .vimrc to fix that:

let g:UltiSnipsExpandTrigger="<tab>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"

BTW, the default digraphs that vim uses are those from RFC1345.


This article was originally posted on 2013-08-11. Updated 2014-03-16.