June 28, 2017

Current treats & future wants of Neovim

Neovim bills itself as literally the future of Vim. A bold claim indeed.

For those that haven’t been following, Neovim is a modern fork of the Vim text editor that began in 2014. The Neovim charter outlines the vision of the project quite succinctly.

Having used Neovim for a little while now I decided it would be worthwhile to write a post listing the treats, pains and wants, as I see them, with Neovim.

Note, the features of Neovim discussed below pertain to Neovim version 0.2 as against Vim 8 circa June 2017.

Installation

This page contains installation details for Neovim.

Configuration

Setting up Neovim does require some minor configuration since Neovim, by default, follows the XDG base directory specification unlike Vim which does not

vimrc

I find having one configuration that works for both Vim and Neovim extremely beneficial. Hence, my combined configuration still lives in the traditional ~/.vimrc file; basically I abstract away the XDG base directories.

To connect Neovim to ~/.vimrc create a ~/.config/nvim/init.vim file with the following content:

set runtimepath^=~/.vim runtimepath+=~/.vim/after
let &packpath = &runtimepath
source ~/.vimrc

Inside a vimrc file use the following if style conditional for any Neovim specific statements:

if has("nvim")
  " Neovim
else
  " Traditional Vim
endif

My vimrc is an example of a combined configuration.

Cut n’ paste

Neovim requires an external clipboard provider for seamless cut n’ paste.

That means making sure the following utilities are installed:

Compatibility

Once setup as such, Neovim and Vim will be quite interchangeable.

In my experience, 3rd-party plugin compatibility is excellent and for the most part users will rarely be able to tell the difference between both editors. So why even bother with Neovim at all? Read on and find out.

Minor Neovim features

Note, a full list of Neovim feature differences to Vim is listed here.

Cursor shape changing

Neovim provides terminal cursor shape changing out-of-the-box, no configuration needed.

Basically that means the cursor shape will differ depending on mode:

This works in iTerm2 (on macOS) and gnome-terminal (on Linux). Best of all the cursor shape change will only affect the current Neovim edit session unlike Vim’s crude t_SI/t_EI based cursor shape change functionality which will bleed into all panes and windows of a tmux session.

UPDATE: Cursor shaping work for xterm requires the following setting in your vimrc:

set guicursor=n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20

Whitespace highlight group

Another small, but useful, enhancement is the Whitespace highlight group.

Vim provides only a single highlight group SpecialKey that is used to visibly highlight special characters such as space, tab and return characters (among others).

I like seeing leading whitespaces as I type them in a low contrast color. However, when I want to see trailing returns, done by toggling the list option, I like to use a high contrast color. In Vim this is a challenge since it only provides a single highlight group for both contexts. Neovim provides two highlight groups to solve this dilemma.

Note, my own moonfly colorscheme is Neovim Whitespace aware.

Substitution previews with inccommand

Neovim provides live substitution previews.

To enable, add the following to your vimrc:

if has("nvim")
    set inccommand=nosplit
endif

As you type a substitution the results will immediately be visible in the edit window. This feature is best highlighted in this video:

Neovim incremental substitution

silent make

In Vim invoking an external makeprg tool such as eslint will result in a visible screen flash even when silent is specified. This is due to Vim context switching to the terminal to invoke the tool and then switching back to Vim with the results.

Neovim has no such flashing since it invokes such system commands in the background and uses pipes to connect results back to the edit session.

Note however, modern async-linting plugins such as ALE render this makeprg/ errorformat-based tool launching somewhat moot these days.

Control-q mapping

I have a Control-q mapping to safely quit my Vim session:

noremap <C-q> :confirm qall<CR>

In terminal Vim this mapping does not work unless one launches Vim via stty -ixon && vim. This prevents the terminal from freezing/unfreezing with the Control-s/Constrol-q key combinations.

However, in Neovim, it is not necessary to do anything special. Control-s/Constrol-q mappings are available for use however you see fit, no special stty magic is needed.

Alt based mappings

Somewhat related to the above I assume, Alt based mapping work as one would expect in Neovim.

For example, the following mapping to create a new tab page, via Alt-t, works in Neovim but not in terminal Vim:

nnoremap <silent> <A-t> :$tabnew<CR>

Note, it is possible to configure an Alt-t mapping in terminal Vim, but it involves coding in the specific terminal sequence, this is not as nice nor as intuitive as Neovim’s approach.

Medium Neovim features

Inbuilt terminal

Neovim provides a fully fledged built-in terminal, invoked by the :terminal command (or the :te shorthand).

This feature provides a tmux-lite alternative for those not wanting or needing a full tmux setup.

Tip, I find the following settings result in a nicer Neovim terminal experience:

if has("nvim")
  " Make escape work in the Neovim terminal.
  tnoremap <Esc> <C-\><C-n>

  " Make navigation into and out of Neovim terminal splits nicer.
  tnoremap <A-h> <C-\><C-N><C-w>h
  tnoremap <A-j> <C-\><C-N><C-w>j
  tnoremap <A-k> <C-\><C-N><C-w>k
  tnoremap <A-l> <C-\><C-N><C-w>l

  " Disable certain styling in terminal windows.
  autocmd TermOpen * setlocal conceallevel=0 colorcolumn=0

  " Prefer Neovim terminal insert mode to normal mode.
  autocmd TermOpen *        startinsert
  autocmd BufEnter term://* startinsert
endif

As an ongoing tmux user myself I currently find the Neovim terminal useful for:

Copying large amounts of text from a tmux window into a Vim session can be fiddly. The Neovim terminal however makes this operation a breeze via traditional visual selection and yanking.

The vim-test plugin provides direct Neovim terminal support when running tests. In Vim, by default, when invoking a test through the vim-test plugin, the edit session will context switch to the host terminal and run the test. In that case it is not possible to simultaneously view the test code and invoked test result unless one uses something like vimux. On the other hand, in Neovim such a test will be invoked in a split-below terminal window (if set), hence both test code and test result are visible next to each other. This greatly enhances the code, test, fix cycle.

UPDATE (July 2017): It appears the Vim is getting its own terminal.

Major Neovim features

In the grand scheme the above list of enhancements are, mostly, minor in nature. The more substantive Neovim enhancements are primarily occurring under the covers and in the community at large, some of those enhancements being:

Minor future Neovim wants

Visual block pasting

Visual block pasting is currently broken in Neovim when clipboard=unnamed is set; pastes will incorrectly occur below rather than to the side of the cursor. I hope this issue is fixed soon, when encountered it is very annoying.

UPDATE (Sep 2021): This issue was fixed in Neovim 0.5.

Medium future Neovim wants

Encryption support

I would like encryption support behaviourally similar to Vim’s existing blowfish2 feature. Neovim stripped out all direct encryption support a while ago. I understand why they did that, and I am not asking that encryption code be put back into the core editor. However, it seems possible to seamlessly delegate to an external encryption provider, similar to how Neovim currently delegates to an external clipboard provider. Such an encryption provider could be GPG. Something like the vim-gnupg plugin, but built into Neovim, is what I would like.

Improved relativenumber scroll performance

This performance issue effects both Vim and Neovim. Currently, when relativenumber is enabled any type of scroll event will cause a full redraw for all visible lines which in turn results in every line having its syntax re-evaluated even though no text has actually changed (only line numbers change). For languages like Ruby, with its over 200 regex rules, this does result in visible performance problems when scrolling as noted by these issues: vim #282 and vim-ruby #243. Basically I would like this feature request implemented; please thumb it up if you can.

UPDATE (Sep 2018): Vim patch 8.1.0374 implemented an important relativenumber optimisation, that being to only redraw the number column, not all visible lines. The above listed issue has been fixed.

Major future Neovim wants

Language Server Protocol (LSP)

Integrated Language Server Protocol support. LSP supposedly provides high performance editor-agnostic: code completion, hovered tooltips, jump-to-definition and code refactoring as explained in this Microsoft blog post. Language servers already exist for many languages. A language-client implementation for Neovim is available as a plugin, but in the longer term, once LSP and its clients and servers mature, it would seem desirable to integrate the LSP client directly in core Neovim.

UPDATE (July 2017): Neovim LSP support is already a work in progress.

UPDATE (Sep 2021): Neovim 0.5 provides an integrated LSP client.

Summary

Is Neovim is the future of Vim? I say it can indeed be a part of the future.

As of mid-2017 both the Vim and Neovim projects appear healthy. The competitive tension seems to have benefited the Vim user community at large. Hence, I say that every Vim user should want Neovim to continue and more than that thrive, whether they use Neovim, or they don’t.

P.S. I still continue to use both Vim and Neovim.