Kinbiko

Vim: My Shiniest Gems

December 16, 2017

Vim is highly customisable, and I recommend everyone tailor their config according to their own preferences. That being said, here are some bits I think people may want to steal from my .vimrc. I tried to avoid the more common options you'd find in similar articles written by others, such as enabling line numbers, tpope's surround plugin, or sane backspacing, and focus on the lesser-known tricks and settings.

General settings

Highlight the current column

Immediately find exactly where your cursor is, using set cursorcolumn. This will highlight the column you're currently on, similar to how you might also do set cursorline to highlight the row (line). I have cursorline disabled as I rely on by color scheme's highlighting of the line number in the gutter instead.

Make whitespace visible

Show invisible characters using set listchars=tab:>-,trail:· This means that tabs should be shown as > followed by a stream of - characters. The number of - characters depends on how many spaces a tab should be as defined by your tabstop setting. Any trailing whitespace shows up as an interpunct (·). To get this working you'll need to follow the above config with set list. Pretty rock 'n roll.

Sane line joins

You're probably aware that J in normal mode tries to join the next line with your current line removing the newline. This tends to work in a very awkward manner with comments. Normally, pressing JJ on the first line of:

/**
 * Creates a User entity using the default parameters.
 */

results in

/**  * Creates a User entity using the default parameters.  */

However, this inconvenience has been fixed as an optional setting as of version 7.3.541, and can be enabled as follows:

if v:version > 703 || v:version == 703 && has('patch541')
  set formatoptions+=j
endif

Now, assuming your version of Vim is relatively recent, the same example will be formatted as:

/** Creates a User entity using the default parameters.  */

Much better.

Highlight ugly code:

I don't like excessively long lines of code (120+ in most languages), and I don't like trailing whitespace. You can easily mark these using the following two commands:

match ErrorMsg '\%>120v.\+'
match ErrorMsg '\s\+$'

Plugins

I like my plugins, and these are my favourites, in no particular order.

Terminus

This plugin is basically enables stuff you probably want, but don't bother to look for individually: Mouse support, different cursor shapes for insert, normal and replace mode, and paste convenience.

fzf.vim

This plugin assumes you have fzf installed locally, as you should. Chances are you're already using it, but it's by far the best fuzzy finder around. More on how I use it for quick lookups in the mappings section below.

Ag

For what fzf can't handle, i.e. text-inside-file search. Assumes you have The Silver Searcher. Faster than ack.

EasyMotion

Super easy navigation to anywhere in the buffer. Similar to the f option in the Vimium Google Chrome extension.

Tabular

This plugin allows you to align a block of text according to a pattern. Suppose for example we have the following annoyingly-formatted JSON objects:

{"name": "River Tam", "skills": ["Cockney accent", "Ability to kill you with her brain"], "Age":19}
{"name": "Jayne Cobb", "skills": ["Extreme confidence", "Naming guns"], "age":33}

You know that there's an inconsistency somewhere in here, but you can't spot it by looking at how the code is formatted right now. Run Tabular /, to align by commas and you quickly spot that the key for age is inconsistently formatted.

{"name": "River Tam"  , "skills": ["Cockney accent"     , "Ability to kill you with her brain"] , "Age":19}
{"name": "Jayne Cobb" , "skills": ["Extreme confidence" , "Naming guns"]                        , "age":33}

Prettier

I remember spending a bit more time than I'd like trying to get this up and running, but, really, once you try prettier you won't write JavaScript/Markdown the same way again. It is such a relief not having to worry about formatting ever again.

vim-go

There are many plugins designed to make certain programming languages easier to write in. Nobody has quite managed to get the full immersion as this plugin has though. Golang comes with the go command-line tool, which has a lot of features built-in that in other languages would be third party tools. For example formatting, organising imports, running tests etc. This plugin handles all of that, and then some(Going to declarations, adding new movement objects, going to alternative files). I like Go as a language, but sometimes I want to write Go just so I can use this plugin.

Mappings

Normal mode

Search the Git repository for filename with ?

nnoremap ? :GFiles<CR>

This mapping relies on GFiles from fzf.vim, and saves a lot of time. Much more efficient than ctrl+p or cmd+t, and since it's only looking for files that aren't .gitignored you don't get all the clutter you might get with node_modules or build/ directories.

Handle Git hunks with <CTRL>n and <CTRL>p and <CTRL>u

nnoremap <c-N> :GitGutterNextHunk<CR>
nnoremap <c-P> :GitGutterPrevHunk<CR>
nnoremap <c-U> :GitGutterUndoHunk<CR>

Relies on the GitGutter plugin. Moves to the next/previous hunk using <CTRL>n/<CTRL>p, and when the cursor is on a hunk, <CTRL>u will revert that hunk. Safer than doing it from the command line as your revert is undoable as it's in your Git undo tree.

Easy-peasy in-file navigation with Enter and Backspace

Have you noticed that both the enter key and the backspace key are basically unused in normal mode. They just go down one line or back one character respectively. Well, we've got j and l for that, so let's rebind them to move a little further (one paragraph):

nnoremap <BS> {
onoremap <BS> {
vnoremap <BS> {

nnoremap <expr> <CR> empty(&buftype) ? '}' : '<CR>'
onoremap <expr> <CR> empty(&buftype) ? '}' : '<CR>'
vnoremap <CR> }

The onoremap basically ensures that the paragraph word object is also respected, E.g. when you type d<CR> you delete from the current position to the next paragraph. The empty check is to ensure that you can still use the enter key in Quickfix windows as you would normally.

Move precisely to any position in the visible buffer

nmap F <Plug>(easymotion-prefix)s

References the EasyMotion plugin mentioned above. Hit F followed by the value of the character you want to move to. One of two things will happen. You will either be taken to where you want to go (usually for rare characters) or you'll be shown a map of all of these characters currently visible, with the keys you need to hit to navigate there. This is one of those tools that's really easy to understand once you start using it, but hard to explain in text. Try it out! You won't be sorry.

Other mappings

Keep selected text selected when fixing indentation

vnoremap < <gv
vnoremap > >gv

Self explanatory, but did you notice that gv takes you to the last visually selected text?

Make quotes and square brackets into movements

onoremap q i'
onoremap Q i"

onoremap ia i]
onoremap aa a]

This simplifies actions such as di" to dQ, and di] to dia.

Conclusion

This of course reflects only some of my .vimrc at this point in time. Head over to my dotfiles repository to browse my current dotfiles, among them my .vimrc.


Roger Guldbrandsen

Written by Roger Guldbrandsen. You can rant at/follow me on Twitter and GitHub.