I’ve been writing a fair amount of mediocre Rust in Neovim. I finally have a setup I like, but to be honest I’m not entirely sure which components I’ve install do what, or if I’ve listed all of the necessary components to reproduce that setup below.

This post represents my best-effort at reproducing the procedure I’d take to get my current setup on a new machine, for when I need to in the future. I broke it into two versions: The first presents a BASH script and a section of my init.vim file (what Neovim uses in place of Vim’s vimrc). The second is a more written-out version of the same procedure.

If you have ideas for how to simplify it, or see redundancies, please let me know on Twitter or Mastodon!

What I’m using

I’m using Kubuntu 18.04 (Linux) and Neovim 0.4.4. I use vim-plug to manage my plugins.

Install necessary programs

Assuming you have Rust installed already (the installation process seems to change over time, so I won’t paste the current process here), via rustup, here’s a BASH script to install all the programs we’ll be using:

#!/bin/bash

if ! command -v rustup &> /dev/null
then
    echo "rustup command could not be found. Install Rust via rustup and try running this script again."
    exit
fi

# Only works for Ubuntu 18.04+
sudo apt install neovim
sudo apt install python-neovim
sudo apt install python3-neovim
# alt:
# pip3 install neovim pynvim

rustup component add clippy
rustup component add rustfmt
rustup component add rust-src


# https://rust-analyzer.github.io/manual.html#rust-analyzer-language-server-binary
git clone https://github.com/rust-analyzer/rust-analyzer.git && cd rust-analyzer
cargo xtask install --server
cd ..
rm -rf rust-analyzer

If python3-neovim didn’t install correctly, or you are running a version of Ubuntu older than 18.04, you may need to install pip and use that to run pip3 install pynvim neovim.

I’d point you to pyenv or pipx. However, in a pinch, these commands have worked for me in the past: sudo apt-get install python3-pip && pip3 install pynvim neovim

Install vim-plug

If you already have a plugin manager for Neovim that you use and like, use that. If you don’t have one installed you’ll need one. I like vim-plug.

Now add this to your init.vim

In ~/.config/nvim/init.vim, paste the following:

call plug#begin('~/.config/nvim/plugged')

" ... other plugins here

" autocomplete
if has('nvim')
  Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
else
  Plug 'Shougo/deoplete.nvim'
  Plug 'roxma/nvim-yarp'
  Plug 'roxma/vim-hug-neovim-rpc'
endif

" Language Server Client
Plug 'autozimu/LanguageClient-neovim', {
\ 'branch': 'next',
\ 'do': 'bash install.sh',
\ }
let g:LanguageClient_serverCommands = {
\ 'rust': ['rust-analyzer'],
\ }

" For improved UI
Plug 'junegunn/fzf'


Plug 'rust-lang/rust.vim',         { 'for': 'rust' }

call plug#end()
" ...

" Configure deoplete
let g:deoplete#enable_at_startup = 1

" note that if you are using Plug mapping you should not use `noremap` mappings.
nmap <F5> <Plug>(lcn-menu)
" Or map each action separately
" nmap <silent> <F2> <Plug>(lcn-rename)
autocmd FileType rust nmap <silent> gr <Plug>(lcn-rename)
" nmap <silent>K <Plug>(lcn-hover)
" nmap <silent> gd <Plug>(lcn-definition)

" Configure Rust formatter https://github.com/rust-lang/rust.vim#formatting-with-rustfmt
" autocmd Filetype rust nnoremap == :RustFmt<CR>
let g:rustfmt_autosave = 1

Now, in Neovim, run :PlugInstall and then :UpdateRemotePlugins. Alternatively, if you want to do this from the command line you can run: nvim +PlugInstall +UpdateRemotePlugins +qa

Next, while still in Neovim, run :CheckHealth to check the “health” of Neovim.


Things to look forward to

From rust-analyzer documentation:

NeoVim 0.5 (not yet released) has built-in language server support. For a quick start configuration of rust-analyzer, use neovim/nvim-lsp. Once neovim/nvim-lsp is installed, use lua require’nvim_lsp’.rust_analyzer.setup({}) in your init.vim.

Longer version of same/similar process

If you want the slightly older, more written-out description of what we’re doing.

Installing some components for this setup

  1. Install Rust. Make sure to add export PATH="$HOME/.cargo/bin:$PATH" to end of ~/.bashrc. Note: you can uninstall at anytime with rustup self uninstall.

  2. Install rustfmt

  3. Install the Rust.vim plugin. I use vim-plug, so that means putting Plug 'rust-lang/rust.vim' in my init.vim and running :PlugInstall.

  4. Check if you have Rust Clippy installed. If you can run cargo clippy on a project, you do have it installed. If you need to install it, you likely do that with rustup component add clippy.

Getting Autocomplete in Neovim with Deoplete

Install Deoplete. This may be difficult!

For example, you may first be required to install a working Python environment. If you’re new to that, I’d point you to pyenv or pipx. However, in a pinch, these commands have worked for me in the past:

# Install pip3 with 
sudo apt-get install python3-pip 
# install the pip package for Neovim
pip3 install neovim 

Then make sure you’ve got all this (or something similar) in your init.vim file:

" Auto-complete
if has('nvim')
  Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
else
  Plug 'Shougo/deoplete.nvim'
  Plug 'roxma/nvim-yarp'
  Plug 'roxma/vim-hug-neovim-rpc'
endif

" then further down
let g:deoplete#enable_at_startup = 1

rust-analyzer and LanguageServer

To get some nice Rust-specific, IDE-esque goodies in Neovim, we’re going to install rust-analyzer. Below, I outline the relatively simple installation option that uses LanguageClient-neovim, though do check documentation for latest instructions.

1. Install rust-analyzer Language Server Binary

Install rust-analyzer Language Server Binary by running the following:

git clone https://github.com/rust-analyzer/rust-analyzer.git && cd rust-analyzer
cargo xtask install --server

The relevant executable is rust-analyzer, so can check that it’s in your PATH by running rust-analyzer --version.

This method appears to install the crate in ~/.config/nvim/rust-analyzer/. Not entirely sure how or if we need to keep this thing up-to-date… I guess a git pull && cargo xtask install --server?

1.5 rust-src?

It’s unclear if you need rust-src to be installed at this point. To do that, try:

rustup component add rust-src

2. Get the neovim LanguageClient installed

Plug 'autozimu/LanguageClient-neovim', {
\ 'branch': 'next',
\ 'do': 'bash install.sh',
\ }

" (Optional) Multi-entry selection UI.
Plug 'junegunn/fzf'

3. Configure rust-analyzer by adding this to your init.vim config file

let g:LanguageClient_serverCommands = {
\ 'rust': ['rust-analyzer'],
\ }

If you already have a Rust-specific line that looks like this in your init.vim file, replace it with these lines.

Then below this in init.vim, let’s add some mappings. The plugin’s readme provides some ideas, but as a minimum:

nmap <F5> <Plug>(lcn-menu)

4. Actually install these plugins

Back in the terminal, run nvim +PlugInstall +UpdateRemotePlugins +qa

Notes on alternative approaches to making Neovim more of a Rust IDE

Alternative methods of installing rust-analyzer

For rust-analyzer, there is an alternative installation process described where it’s integrated with coc.nvim, which you might be using anyway, or like for its other features. To me, right now, it seems a bit intense, and requires Node to be installed.

Racer

There also seems to be another way to “teach” Neovim about the Rust language using Racer (“code completion for Rust”) and its associated Vim plugin. I tried this once and it kept throwing halting errors as I was typing code.