Intro

Call me crazy, but I decided to have a look at using NeoVim in this the year of our lord and saviour 2022. NeoVim is a minimal fork of VIM which supports LUA as a scripting engine.

In this post, I will show you how to install and configure NeoVim with some fancy plugins and a smattering of TMUX configs to make it all look nice.

Software

The following software was used in this post.

  • NeoVim - 0.7.0
  • vim-plug - 0.11.0
  • tmux - 3.0a
  • Ubuntu - 2004

Install NeoVim

Download and install NeoVim.

Note

NeoVim >= 0.6.1 is required for this post.

cmd
curl -L -O https://github.com/neovim/neovim/releases/download/nightly/nvim-linux64.deb
sudo apt install -y ./nvim-linux64.deb

Clean up .deb file.

cmd
rm ./nvim-linux64.deb

Make the required directories and the NeoVim configuration file. The NeoVim configuration file is located at ~/.config/nvim/init.vim .

cmd
mkdir -p ~/.config/nvim
touch ~/.config/nvim/init.vim

VIM Modes

VIM has two modes: COMMAND mode and INSERT mode. You start out in COMMAND mode. You can press i to enter INSERT mode. To return to COMMAND mode press ESC .

At this point, if you want to rage quit, you can press ESC and type :q! then press ENTER to exit VIM without having to burn your computer.

Still with me? Good, let's carry on.

VIM-Plug

I am using vim-plug as the VIM plugin manager.

cmd
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'

Now lets setup vim-plug. Pluggins will be installed in the ~/.local/share/nvim/plugged directory.

cmd
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \\
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

NeoVim Config File

Initially, lets setup the NeoVim config file to install the plugins with vim-plug. Edit the ~/.config/nvim/init.vim file and add the follow block of code to the top.

To open a file with NeoVim you use the nvim <filename> command.

~/.config/nvim/init.vim
call plug#begin('~/.local/share/nvim/plugged')

" https://sharksforarms.dev/posts/neovim-rust/
" Collection of common configurations for the Nvim LSP client
Plug 'neovim/nvim-lspconfig'

" Completion framework
Plug 'hrsh7th/nvim-cmp'

" LSP completion source for nvim-cmp
Plug 'hrsh7th/cmp-nvim-lsp'

" Other usefull completion sources
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-buffer'

" See hrsh7th's other plugins for more completion sources!

" To enable more of the features of rust-analyzer, such as inlay hints and more!
Plug 'simrat39/rust-tools.nvim'

" Snippet engine
Plug 'dcampos/cmp-snippy'
Plug 'dcampos/nvim-snippy'
Plug 'honza/vim-snippets'

" Fuzzy finder
" Optional
Plug 'nvim-lua/popup.nvim'
Plug 'nvim-lua/plenary.nvim'
Plug 'nvim-telescope/telescope.nvim'

" Jinja syntax highlighting
" https://github.com/lepture/vim-jinja
Plug 'lepture/vim-jinja'

" colour schemes
" http://neovimcraft.com/plugin/marko-cerovac/material.nvim/index.html
Plug 'marko-cerovac/material.nvim'

" File explorer
Plug 'kyazdani42/nvim-web-devicons' " for file icons
Plug 'kyazdani42/nvim-tree.lua'

" Format on save
" https://github.com/vim-autoformat/vim-autoformat
Plug 'Chiel92/vim-autoformat'

call plug#end()

Now, from COMMAND mode type :w and hit ENTER to save the file.

Now type :PlugInstall and hit ENTER to install the plugins. You should see a screen similar to the below.

cmd
Updated. Elapsed time: 2.005071 sec.                        │call plug#begin('~/.local/share/nvim/plugged')
[===========]                                               │
                                                            │" Collection of common configurations for the Nvim LSP clie- Finishing ... Done!                                       │nt
- cmp-buffer: remote: Total 13 (delta 0), reused 9 (delta 0)│Plug 'neovim/nvim-lspconfig'
- cmp-path: remote: Total 10 (delta 0), reused 7 (delta 0), │
- rust-tools.nvim: remote: Total 72 (delta 17), reused 36 (d│" Completion framework
- nvim-cmp: Resolving deltas: 100% (170/170), done.         │Plug 'hrsh7th/nvim-cmp'
- vim-vsnip: Resolving deltas: 100% (92/92), done.          │
- nvim-lspconfig: Resolving deltas: 100% (128/128), done.   │" LSP completion source for nvim-cmp
- plenary.nvim: Resolving deltas: 100% (155/155), done.     │Plug 'hrsh7th/cmp-nvim-lsp'
- cmp-vsnip: remote: Total 10 (delta 0), reused 8 (delta 0),│
- telescope.nvim: Resolving deltas: 100% (555/555), done.   │" Snippet completion source for nvim-cmp
- cmp-nvim-lsp: remote: Total 11 (delta 0), reused 8 (delta │Plug 'hrsh7th/cmp-vsnip'
- popup.nvim: remote: Total 16 (delta 1), reused 12 (delta 1│
~                                                           │" Other usefull completion sources
~                                                           │Plug 'hrsh7th/cmp-path'
~                                                           │Plug 'hrsh7th/cmp-buffer'
~                                                           │
~                                                           │" See hrsh7th's other plugins for more completion sources!
~                                                           │
~                                                           │" To enable more of the features of rust-analyzer, such as inlay hints and more!
~                                                           │Plug 'simrat39/rust-tools.nvim'
~                                                           │
~                                                           │" Snippet engine
~                                                           │Plug 'hrsh7th/vim-vsnip'
~                                                           │
[Plugins]                                 1,1            All .config/nvim/init.vim                    1,1            Top

Type :q! to close this window. At this point, NeoVim and vim-plug are installed. It's time to configure them.

Material Theme

I like the material theme and I am using the deep ocean colour scheme. Add the following LUA snippet below the call plug#end() statement.

~/.config/nvim/init.vim
"Add config below the 'call plug#end()' statement

" http://neovimcraft.com/plugin/marko-cerovac/material.nvim/index.html
lua <<EOF
-- Set the theme style
vim.g.material_style = 'deep ocean'

require('material').setup({
contrast = {
  sidebars = true,
  cursor_line = true,
  },
italics = {
  comments = true,
  functions = true,
  },
contrast_filetypes = {
  "terminal",
  "packer",
  "qf",
  },
disable = {
  borders = true,
  eob_lines = true
  },
lualine_style = 'stealth'
})

-- Enable the colorscheme
vim.cmd 'colorscheme material'
EOF

File Explorer

The next plugin gives us a file explorer.

~/.config/nvim/init.vim
lua <<EOF
-- setup with all defaults
-- each of these are documented in ':help nvim-tree.OPTION_NAME'
vim.opt.splitright = true

require'nvim-tree'.setup { -- BEGIN_DEFAULT_OPTS
auto_close = false,
auto_reload_on_write = true,
disable_netrw = false,
hide_root_folder = false,
hijack_cursor = false,
hijack_netrw = true,
hijack_unnamed_buffer_when_opening = false,
ignore_buffer_on_setup = false,
open_on_setup = false,
open_on_tab = false,
sort_by = "name",
update_cwd = false,
view = {
  width = 30,
  height = 30,
  side = "right",
  preserve_window_proportions = true,
  number = false,
  relativenumber = false,
  signcolumn = "yes",
  mappings = {
    custom_only = false,
    list = {
      -- user mappings go here
      },
    },
  },
hijack_directories = {
  enable = true,
  auto_open = true,
  },
update_focused_file = {
  enable = false,
  update_cwd = false,
  ignore_list = {},
  },
ignore_ft_on_setup = {},
system_open = {
  cmd = nil,
  args = {},
  },
diagnostics = {
  enable = true,
  show_on_dirs = false,
  icons = {
    hint = "",
    info = "",
    warning = "",
    error = "",
    },
  },
filters = {
  dotfiles = false,
  custom = {},
  exclude = {},
  },
git = {
  enable = true,
  ignore = true,
  timeout = 400,
  },
actions = {
  change_dir = {
    enable = true,
    global = false,
    },
  open_file = {
    quit_on_open = false,
    resize_window = true,
    window_picker = {
      enable = true,
      chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
      exclude = {
        filetype = { "notify", "packer", "qf", "diff", "fugitive", "fugitiveblame" },
        buftype = { "nofile", "terminal", "help" },
        },
      },
    },
  },
trash = {
  cmd = "trash",
  require_confirm = true,
  },
log = {
  enable = false,
  truncate = false,
  types = {
    all = false,
    config = false,
    git = false,
    },
  },
}
-- END_DEFAULT_OPTS
EOF

Code Snippets

Now for some code snippet goodness. Who doesn't love a bit of auto-completion.

~/.config/nvim/init.vim

lua <<EOF
require('snippy').setup({
    mappings = {
        is = {
            [''] = 'expand_or_advance',
            [''] = 'previous',
        },
        nx = {
            ['x'] = 'cut_text',
        },
    },
})
EOF

I got a lot of the configuration and hints for this post from this wonderful blog post. The code below comes from that post and relates to Rust integration.

~/.config/nvim/init.vim

" https://sharksforarms.dev/posts/neovim-rust/
" Set completeopt to have a better completion experience
" :help completeopt
" menuone: popup even when there's only one match
" noinsert: Do not insert text until a selection is made
" noselect: Do not select, force user to select one from the menu
set completeopt=menuone,noinsert,noselect

" Avoid showing extra messages when using completion
set shortmess+=c

" Configure LSP through rust-tools.nvim plugin.
" rust-tools will configure and enable certain LSP features for us.
" See https://github.com/simrat39/rust-tools.nvim#configuration
lua <<EOF
local nvim_lsp = require'lspconfig'

local opts = {
  tools = { -- rust-tools options
  autoSetHints = true,
  hover_with_actions = true,
  inlay_hints = {
    show_parameter_hints = false,
    parameter_hints_prefix = "",
    other_hints_prefix = "",
    },
  },

-- all the opts to send to nvim-lspconfig
-- these override the defaults set by rust-tools.nvim
-- see https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#rust_analyzer
server = {
  -- on_attach is a callback called when the language server attachs to the buffer
  -- on_attach = on_attach,
  settings = {
    -- to enable rust-analyzer settings visit:
    -- https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/generated_config.adoc
    ["rust-analyzer"] = {
      -- enable clippy on save
      checkOnSave = {
        command = "clippy"
        },
      }
    }
  },
}

require('rust-tools').setup(opts)
EOF

Additionally, the following is also required to compete the integration.

Rust needs to be installed, if you don't have that already, best to get that out of the way.

cmd
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Confirm Rust and Cargo are installed.

cmd
which rustc
which cargo

Add rustfmt and clippy for formatting and code style linting.

cmd
rustup component add rustfmt
rustup component add clippy

Install rust-analyzer .

cmd
curl -L https://github.com/rust-analyzer/rust-analyzer/releases/latest/download/rust-analyzer-x86_64-unknown-linux-gnu.gz | gunzip -c - > ~/.cargo/bin/rust-analyzer

Make rust-analyzer executable.

cmd
chmod +x ~/.cargo/bin/rust-analyzer
Note

rust-analyzer must be installed in a location in your $PATH . A reload of your shell may be required.

TMUX

Finally, I am using TMUX so, I also had to add some settings to make it looks nice with the Material theme.

~/.tmux.conf
https://jdhao.github.io/2018/10/19/tmux_nvim_true_color/
set -g default-terminal "screen-256color"
# tell Tmux that outside terminal supports true color
set -ga terminal-overrides ",xterm-256color*:Tc"

# https://cassidy.codes/blog/2019-08-03-tmux-colour-theme/
# https://unix.stackexchange.com/questions/60968/tmux-bottom-bar-color-change
set -g status-style "bg=#282a36"

End Result

I am pretty happy with the result. You can open a directory by using nvim . in the directory.

So, how's it look? Pretty dope 😎

blog/neovim-install-and-configure/neovim.png

Outro

This was a much longer post than I thought it was initially going to be. In this post, we installed and configured NeoVim with vim-plug to manage pluggins. We also setup Rust integration with a sprinkling of TMUX dust. Worth it? Only you can be the judge.

# neovim
# vim
# tmux
# rust