---
title: My Life with NeoVim
teaser: Frustrations with Vim lead me briefly to Emacs and ultimately to experiment
  with NeoVim.
tags: vim
author: Derek Prior
published_on: 2016-08-26
---

Early this year, my frustrations with Vim reached a boiling point. I was
frustrated by slow, synchronous [Syntastic] checkers that I had come to rely on.
I wanted the in-editor feedback the checkers provided but many of those checkers
locked up my editor for seconds at a time.

  [Syntastic]: https://github.com/scrooloose/syntastic

I use Vim and tmux to approximate the feeling of a very light-weight IDE, even
[moving between the two as if they were the same program][vim-tmux]. However,
[tmux is not without it's issues][copy-paste]. My frustrations with Vim made me
see that tmux is something I deal with to overcome a shortcoming of my editor
rather than a tool I value on its own.

  [vim-tmux]: https://thoughtbot.com/blog/seamlessly-navigate-vim-and-tmux-splits
  [copy-paste]: https://thoughtbot.com/blog/tmux-copy-paste-on-os-x-a-better-future

I even started to wonder if those Emacs users among us had it right. I
downloaded and installed [Spacemacs], probably all while I was waiting on
synchronous Vim plugins to complete, and tried to make heads or tails of it
all. Emacs quickly proved to be too much of a change and I wasn't prepared to
commit to it.

  [Spacemacs]: http://spacemacs.org

## Enter NeoVim

I then remembered the announcement of [NeoVim](https://neovim.io), a fork of Vim
that promised to modernize the plugin architecture, and provide a better
out-of-the-box experience for Vim users, including a built in terminal emulator.

I was surprised to find that NeoVim was already reported to be in a very usable
state, supporting asynchronous plugins and operating as a drop-in replacement
for Vim. I decided to give NeoVim a whirl.

## Installing and Configuring NeoVim

NeoVim has packages available for Homebrew, MacPorts, Ubuntu, Debian, Arch, and
many other environments. Installing on OS X with Homebrew was a `brew install
neovim/neovim/neovim` away. That's right, the way to summon NeoVim is to [say
its name three times]. See the [installation instructions] for details on
installing in your environment, but it probably won't be as much fun as that.

  [say its name three times]: https://images.thoughtbot.com/blog-vellum-image-uploads/dm8SPoozQAbH8LZYX4O4_beetlejuice.jpg
  [installation instructions]: https://github.com/neovim/neovim/wiki/Installing-Neovim

NeoVim does not load your `.vimrc` file, nor does it use `.nvimrc`, as I had
guessed it might. As a result, none of my configuration was carried over when I
launched NeoVim for the first time.

NeoVim supports the [XDG Base Directory Specification], which among other things
attempts to standardize where user configuration files should live and their
order of precedence. With an assist from `:help nvim-from-vim`, I ran the
following commands which allow me to share a configuration between Vim and
NeoVim.

    mkdir -p ${XDG_CONFIG_HOME:=$HOME/.config}
    ln -s ~/.vim $XDG_CONFIG_HOME/nvim
    ln -s ~/.vimrc $XDG_CONFIG_HOME/nvim/init.vim

  [XDG Base Directory Specification]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

## Overcoming Muscle Memory

Years of editing files with the `vim` command made learning to use `nvim` a
challenge. For all intents and purposes, `nvim` is Vim for me, so where it is
installed, I want to use it all the time. To make this a reality, I added the
following alias to my ZSH configuration:

```zsh
if type nvim > /dev/null 2>&1; then
  alias vim='nvim'
fi
```

This allows me to continue to use `vim` on, for example, my home machine where I
hadn't yet installed NeoVim.

## Asynchronous Checkers

To my surprise and delight, NeoVim worked well with my configuration, which is
based on the [thoughtbot dotfiles] with [my own customizations] applied.
Unfortunately, Syntastic style checkers were still blocking, just as they were
under Vim. Syntastic does not take advantage of the asynchronous architecture
exposed by NeoVim.

  [thoughtbot dotfiles]: https://github.com/thoughtbot/dotfiles
  [my own customizations]: https://github.com/derekprior/dotfiles

[NeoMake] was built from the ground up to perform similar tasks while taking
advantage of NeoVim's asynchronous jobs. I added the plugin to my configuration,
but due to the fact that I inherit Sytastic from the thoughtbot dotfiles, I had
to get creative to keep them both from running. I configured Syntastic and
NeoMake like so:

```vim
" Run NeoMake on read and write operations
autocmd! BufReadPost,BufWritePost * Neomake

" Disable inherited syntastic
let g:syntastic_mode_map = {
  \ "mode": "passive",
  \ "active_filetypes": [],
  \ "passive_filetypes": [] }

let g:neomake_serialize = 1
let g:neomake_serialize_abort_on_error = 1
```

  [NeoMake]: https://github.com/neomake/neomake

With that configuration loaded, slow checkers no longer locked my editor. While
results may take a moment to be reflected in my editor, I'm free to go about my
business in NeoVim while the work is done in the background.

NeoMake does not match Syntastic in terms of the sheer number of checkers
supported out of the box. New makers, as they are called in NeoMake, are added
regularly and can be added via configuration if desired. The languages and tools
I most cared about were supported out of the box.

## About That Terminal Emulator

You can open a terminal emulator from any NeoVim split with `:terminal` or
`:te`. I tried to use this in place of tmux for a bit, but found there were
enough cases where it didn't behave as I would like that I went back to tmux
within a week. Your experience may vary, though other NeoVim users in the office
report that they don't get much use from `:terminal` either.

I'd like to dedicate some time to the tmux replacement experiment again in the
near future. Most of my terminal use while editing is dedicated to git
operations, and I bet I could get that to work mighty nicely with NeoVim.

## My Only Workaround

I found that my mapping for `CTRL-h` did not work from NeoVim when working from
tmux. I use this mapping from both Vim and tmux to seamlessly and quickly switch
between splits and panes. I worked around this issue with the following in my
`.vimrc`:

```vim
nnoremap <silent> <BS> :TmuxNavigateLeft<cr>
```

The NeoVim FAQ has since been updated with a [different workaround] that is
likely more correct, but I haven't a clue what it means, so I've stuck with my
own workaround for the time being.

  [different workaround]: https://github.com/neovim/neovim/wiki/FAQ#my-ctrl-h-mapping-doesnt-work

## A Successful Experiment

I've been using NeoVim for eight months now without giving it much thought at
all beyond the initial configuration. I enjoy that NeoMake gives me asynchronous
feedback as I work, but beyond that nothing else has changed about my Vim usage.
If you're not bothered by the things NeoVim purports to fix, then there's no
need to change a thing, but in my case the asynchronous job support was enough
to justify the small price of admission.
