published: 22nd of March 2022
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.
The following software was used in this post.
Download and install NeoVim.
NeoVim >= 0.6.1 is required for this post.
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.
rm ./nvim-linux64.deb
Make the required directories and the NeoVim configuration file. The NeoVim configuration file is located at ~/.config/nvim/init.vim .
mkdir -p ~/.config/nvim
touch ~/.config/nvim/init.vim
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.
I am using vim-plug as the VIM plugin manager.
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.
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \\
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
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.
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.
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.
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.
"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
The next plugin gives us a file explorer.
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
Now for some code snippet goodness. Who doesn't love a bit of auto-completion.
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.
" 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.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Confirm Rust and Cargo are installed.
which rustc
which cargo
Add rustfmt and clippy for formatting and code style linting.
rustup component add rustfmt
rustup component add clippy
Install rust-analyzer .
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.
chmod +x ~/.cargo/bin/rust-analyzer
rust-analyzer must be installed in a location in your $PATH . A reload of your shell may be required.
Finally, I am using TMUX so, I also had to add some settings to make it looks nice with the Material theme.
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"
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 😎
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.
https://github.com/junegunn/vim-plug#installation
https://github.com/neovim/neovim/wiki/Installing-Neovim
https://github.com/neovim/neovim/releases
https://www.reddit.com/r/neovim/comments/aojose/how_to_enable_line_numbering/
http://neovimcraft.com/plugin/marko-cerovac/material.nvim/index.html
https://unix.stackexchange.com/questions/646883/neovim-changes-color-inside-tmux
https://sunaku.github.io/tmux-24bit-color.html#usage
https://jdhao.github.io/2018/10/19/tmux_nvim_true_color/
https://mattermost.com/blog/turning-neovim-into-a-full-fledged-code-editor-with-lua/
https://github.com/kyazdani42/nvim-tree.lua
https://github.com/kyazdani42/nvim-tree.lua/issues/1072
https://github.com/lepture/vim-jinja
https://bhupesh.me/learn-how-to-use-code-snippets-vim-cowboy/