Home Configuring Neovim as Rust IDE
Post
Cancel

Configuring Neovim as Rust IDE

If you read my article Configuring Neovim as Python IDE, you already know that one of mi favorite editors is [neo]vim. Between other reasons, when I’m using [neo]vim I feel more focused, I don’t know why.

One of my open fronts, in my spare time, is learn Rust, and neovim (in this case) seems a great IDE to do it. I have to say that programming in rust using neovim it reminds me of the old days programming in (ANSI) C using vim.

Convert neovim in a Rust IDE it’s very fast and very straightforward. After installing Rust, we only will need rust-analyzer and three vim plugins.

rust-analyzer

rust-analyzer is an implementation of Language Server Protocol (LSP) for the Rust programming language. It provides features like completion and goto definition for many code editors.

rust-analyzer needs the sources of the standard library, we can install them via rustup:

rustup component add rust-src

Now, we can install rust-analyzer via rustup:

rustup component add rust-analyzer

[Neo]vim base configuration

As allways, I’ll part from my base configuration. This is my configuration for all, in all my computers, no matter the purpose.

~/.config/nvim/init.vim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
syntax on                       "syntax highlighting
filetype plugin indent on       "file type detection
set number                      "display line number
set path+=**                    "improves searching
set noswapfile                  "disable use of swap files
set wildmenu                    "completion menu
set backspace=indent,eol,start  "ensure proper backspace functionality
set incsearch                   "see results while search is being typed, see :help incsearch
set smartindent                 "auto indent on new lines, see :help smartindent
set expandtab                   "expanding tab to spaces
set tabstop=4                   "setting tab to 4 columns
set shiftwidth=4                "setting tab to 4 columns
set softtabstop=4               "setting tab to 4 columns
set showmatch                   "display matching bracket or parenthesis
set hlsearch incsearch          "highlight all pervious search pattern with incsearch
"set list                        "show all whitespaces (uncomment without Better Whitespace plugin)

[Neo]vim plugin manager

As plugin manager, my choice is vim-plug, and its installation it’s very straightforward:

Unix/linux:

1
sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'

Plugins

I install four plugins:

  • nvim-lspconfig Configs for the Nvim LSP client.

  • nvim-cmp A completion engine plugin.

  • rust-lang Provides Rust file detection, syntax highlighting, formatting, Syntastic integration, and more.

  • Vim Better Whitespace This plugin highlights all trailing whitespaces. It’s totally optional and can be substituted by the option “lines” in the vim.init file, but I like it.

nvim-lspconfig

To install it, we add the plugin to our init.vim file, into the call plug#begin('/home/rubenhortas/.config/nvim/plugins') section, below all the lines:

1
2
3
4
5
6
call plug#begin('/home/rubenhortas/.config/nvim/plugins')
...

Plug 'neovim/nvim-lspconfig'

call plug#end()

We will also pass LSP settings to the server adding:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
lua << EOF
local lspconfig = require'lspconfig'

local on_attach = function(client)
    require'completion'.on_attach(client)
end

lspconfig.rust_analyzer.setup({
    on_attach = on_attach,
    settings = {
        ["rust-analyzer"] = {
            imports = {
                granularity = {
                    group = "module",
                },
                prefix = "self",
            },
            cargo = {
                buildScripts = {
                    enable = true,
                },
            },
            procMacro = {
                enable = true
            },
        }
    }
})
EOF

nvim-cmp

If you already have installed this plugin, you only need to add the set up lspconfig section for rust_analyzer:

1
2
3
  require('lspconfig')['rust_analyzer'].setup {
    capabilities = capabilities
  }

A completion engine plugin for neovim written in Lua. Completion sources are installed from external repositories and “sourced”. To install it we need to add the following to our init.vim file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
call plug#begin('/home/rubenhortas/.config/nvim/plugins')
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'hrsh7th/nvim-cmp'

" For vsnip users.
Plug 'hrsh7th/cmp-vsnip'
Plug 'hrsh7th/vim-vsnip'

call plug#end()

lua <<EOF
  -- Set up nvim-cmp.
  local cmp = require'cmp'

  cmp.setup({
    snippet = {
      -- REQUIRED - you must specify a snippet engine
      expand = function(args)
        vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
        -- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
        -- require('snippy').expand_snippet(args.body) -- For `snippy` users.
        -- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
      end,
    },
    window = {
      -- completion = cmp.config.window.bordered(),
      -- documentation = cmp.config.window.bordered(),
    },
    mapping = cmp.mapping.preset.insert({
      ['<C-b>'] = cmp.mapping.scroll_docs(-4),
      ['<C-f>'] = cmp.mapping.scroll_docs(4),
      ['<C-Space>'] = cmp.mapping.complete(),
      ['<C-e>'] = cmp.mapping.abort(),
      ['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
    }),
    sources = cmp.config.sources({
      { name = 'nvim_lsp' },
      { name = 'vsnip' }, -- For vsnip users.
      -- { name = 'luasnip' }, -- For luasnip users.
      -- { name = 'ultisnips' }, -- For ultisnips users.
      -- { name = 'snippy' }, -- For snippy users.
    }, {
      { name = 'buffer' },
    })
  })

  -- Set configuration for specific filetype.
  cmp.setup.filetype('gitcommit', {
    sources = cmp.config.sources({
      { name = 'git' }, -- You can specify the `git` source if [you were installed it](https://github.com/petertriho/cmp-git).
    }, {
      { name = 'buffer' },
    })
  })

  -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
  cmp.setup.cmdline({ '/', '?' }, {
    mapping = cmp.mapping.preset.cmdline(),
    sources = {
      { name = 'buffer' }
    }
  })

  -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
  cmp.setup.cmdline(':', {
    mapping = cmp.mapping.preset.cmdline(),
    sources = cmp.config.sources({
      { name = 'path' }
    }, {
      { name = 'cmdline' }
    })
  })

  -- Set up lspconfig.
  local capabilities = require('cmp_nvim_lsp').default_capabilities()
  -- Replace <YOUR_LSP_SERVER> with each lsp server you've enabled.
  require('lspconfig')['rust_analyzer'].setup {
    capabilities = capabilities
  }
EOF

rust-lang

To install it, we add the plugin to our init.vim file, into the call plug#begin('/home/rubenhortas/.config/nvim/plugins') section, below all the lines:

1
2
3
4
5
6
call plug#begin('/home/rubenhortas/.config/nvim/plugins')
...

Plug 'rust-lang/rust.vim'

call plug#end()

Vim Better Whitespace

This plugin causes all trailing whitespace characters to be highlighted. Whitespace for the current line will not be highlighted while in insert mode. It is possible to disable current line highlighting while in other modes as well. A helper function :StripWhitespace is also provided to make whitespace cleaning painless.

This plugin is optional, and can be substituded by the “lines” option in the vim.init file. But, I like it, and the :StripWhitespace function is very useful.

To install it we add the plugin to our init.vim file, into the call plug#begin('/home/rubenhortas/.config/nvim/plugins') section, below all the lines:

1
2
3
4
5
6
call plug#begin('/home/rubenhortas/.config/nvim/plugins')
...

Plug 'ntpeters/vim-better-whitespace'

call plug#end()

Install the plugins

To install the plugins we open nvim and run:

:PlugInstall

Screenshots

Example of autocompletion Example of autocompletion

Example of linting errors and trailing whitespaces Example of linting errors

Enjoy! ;)

This post is licensed under CC BY 4.0 by the author.