Pssst, here’s the YouTube version if you would rather?

I revisit Neovim every so often to see how things are evolving. I’ve been using the nightly build for a few weeks and as the 0.5 milestone has just been released, it seemed like a good point to take stock and share what an up to date Neovim experience looks like. Install will vary based on your OS but for me on macOS it is as easy as brew install neovim.

No more Vimscript

Firstly, Vimscript is gone. Well, not actually gone, but as there is so much support for Lua in Neovim 0.5, many plugins that were once Vimscript are being re-written in Lua. And, as we’ll see when I take you through my plugins, even long established plugins are getting re-imagined in Lua.

While that won’t make much difference to the casual user, the ability to write your config in Lua, rather than Vimscript does. As such, I’ve moved my init.vim to a init.lua file.

Now, I hadn’t written a line of Lua before this little adventure but I’ve managed to limp through, thanks in large part to some of the resources linked below.

But, what I can tell you from this escapade is: if you can write JavaScript to some degree of competency, you’ll likely get by fine understanding Lua, for as much as you need to understand it, to write/copy/paste your config in a init.lua file. Plus there are tools like luafmt which, like Prettier for front-end languages, will tell you what you are doing wrong, syntax wise.

To give you a taste, here is a sample of how you set options (double dash starts a comment in Lua) in the init.lua:

opt.expandtab = true -- Use spaces instead of tabs
opt.hidden = true -- Enable background buffers
opt.backspace = {"indent", "eol", "start"}
opt.ignorecase = true -- Ignore case
opt.incsearch = true -- Shows the match while typing
opt.hlsearch = true -- Highlight found searches
opt.joinspaces = false -- No double spaces with join
opt.list = false -- Show some invisible characters
opt.number = true -- Show line numbers
opt.linebreak = true -- Stop words being broken on wrap
opt.numberwidth = 5 -- Make the gutter wider by default
opt.relativenumber = true -- Relative line numbers

If you are interested in how any of these things are setup, there’s a link to my init.lua below. Bottom line is, that for a modern setup, there is nothing I needed in my init that I wasn’t able to do in Lua. Plus, it actually seemed to make more sense to me than Vimscript ever did.

Treesitter

Neovim 0.5 can make use of Treesitter, albeit with the caveat that it is experimental until 0.6 is released.

Nvim-treesitter is based on three interlocking features: language parsers, queries, and modules, where modules provide features – e.g., highlighting – based on queries for syntax objects extracted from a given buffer by language parsers.

For practical purposes, the takeaway is you get better language parsing and syntax highlighting in your files. Here, for example, is my current Treesitter compatible theme of choice in Everforest:

syntax highlighting of Vim language file
Much more nuance to language syntax highlighting with Treesitter

There are obviously greater implications of Treesitter, beyond mere colour schemes but I’m not qualified to explore them with you. It’s a case of Treesitter is good, ‘mkay’ (Southpark Mr Mackey style).

Built in LSP

Vim interface showing code completion
The built in LSP makes adding code completion fairly trivial

When I last wrote about Vim, I was using the, unfortunately abbreviated, Conqueror of Completion (CoC) plugin to make use of Language Server Protocol, which is the engine behind the code completion you get in VSCode. In Neovim 0.5, CoC can be supplanted by lighter tools thanks to Neovim now having a built-in Language Server Protocol client. In my case I’m, now using lsp-config as a way to setup the language servers I’m interested in, and then nvim-compe, as the completion plugin, again, written mostly in Lua. At the minute, I haven’t bothered adding anything, completion wise, beyond what the LSP server provides as its serving me well enough.

You need to install the language servers if you want to see anything so it’s a case of following the instructions for your language here.

I’ve also got Lspsaga in there to give me a basic UI to navigate the LSP features and diagnostics. By default, once you get LSP setup, you get all the errors/warnings inline in the buffer. As someone who tends to write TypeScript a little cowboy style at the outset, that got old fast so by adding this to my init.lua:

vim.lsp.diagnostic.show_line_diagnostics()
vim.lsp.handlers["textDocument/publishDiagnostics"] =
  vim.lsp.with(
  vim.lsp.diagnostic.on_publish_diagnostics,
  {
    virtual_text = false
  }
)

It stopped the errors in line and I’m using Lspsaga to have a hover shortcut instead, and show the Diagnostic messages in a hover window. And I have shortcuts for next/previous message too. Mine are set for leader, ‘c’ (for Code), and then say, ‘h’ for hover, or ‘n’ for next and ‘r’ for rename etc.

map("n", "<Leader>cf", ":Lspsaga lsp_finder<CR>", {silent = true})
map("n", "<leader>ca", ":Lspsaga code_action<CR>", {silent = true})
map("v", "<leader>ca", ":<C-U>Lspsaga range_code_action<CR>", {silent = true})
map("n", "<leader>ch", ":Lspsaga hover_doc<CR>", {silent = true})
map("n", "<leader>ck", '<cmd>lua require("lspsaga.action").smart_scroll_with_saga(-1)<CR>', {silent = true})
map("n", "<leader>cj", '<cmd>lua require("lspsaga.action").smart_scroll_with_saga(1)<CR>', {silent = true})
map("n", "<leader>cs", ":Lspsaga signature_help<CR>", {silent = true})
map("n", "<leader>ci", ":Lspsaga show_line_diagnostics<CR>", {silent = true})
map("n", "<leader>cn", ":Lspsaga diagnostic_jump_next<CR>", {silent = true})
map("n", "<leader>cp", ":Lspsaga diagnostic_jump_prev<CR>", {silent = true})
map("n", "<leader>cr", ":Lspsaga rename<CR>", {silent = true})
map("n", "<leader>cd", ":Lspsaga preview_definition<CR>", {silent = true})

That covers things directly related to the latest release. I want to show you next some of the more recent plugins made possible with Neovim and the Lua support.

Formatter

I’ve long waxed lyrical about Prettier. I’m a huge fan of formatters that auto format code when you save. I used to use the vim-prettier plugin for the task but I was getting lots of Errors around Treesitter while using that so I have switched to Formatter. It’s described as work in progress but I’ve found it great for my needs. I was able to hook up Prettier easy enough and also luafmt for Lua (for the sole purpose of helping me write a working init.lua).

I’m aware of other projects that actually spin up a daemon process to make Prettier even faster – it can feel slow occasionally because it has to spin up Node to run, not because Prettier itself is slow. But I’ve just not found it a problem with Formatter so haven’t pursued it.

Telescope

The plugin that makes the biggest difference for me is Telescope. It wraps up a few of the features I have previously had to cobble together with separate plugins. To oversimplify, it’s a tool that creates lists and then lets you Preview the contents of those lists and manipulate them.

The Telescope plugin for Vim
Use Telescope for grepping, file finding, buffer switching and more.

You can use Telescope as your file finder and preview. Your quick buffer switcher. Your grepping tool, using something like Ripgrep in the background. Your Git summary tool.

Not only that, but to give you some idea of its power, you can use it to grep (search), project wide for a string, then pipe those results (using Ctrl+q) into a quickfix list, and use :cdo s/StringOne/StringTwo/g | update to operate on them all in one go and save the files! Hat tip to ThePrimeagen for detailing how to do that.

Plus Telescope just works out of the box. No endless messing around trying to bring it to life. Just install it, copy paste the config and you’re away. Just an incredible plugin.

Minimap

This is actually a great implementation of a minimap. I don’t tend to have it on by default as for the most part it’s just extra noise and it is another buffer so occasionally gets problematic when you switch windows but as it’s occasionally useful to see the shape of a large file I toggle it on when needed. Mostly I just keep it around because it’s cool!

Minimap in text editor
No slowdown whatsoever but you still get the issue of the minimal being a window

Lualine

As the name suggests, Lualine is a statusline written in Lua. If you’ve ever used Airline or Lightline, you will be instantly familiar with Lualine. There are some great examples out there of what you can do with it. I might have also chosen Galaxyline, I just found the documentation a bit better for Lualine. As ever I’ve taken from other peoples examples and got a functional statusline for now. I have my mode, filename, git status, LSP info, file type and percentage etc. I’d like to go further in this regard when I have time. Perhaps adding a word count when I’m editing Markdown or text files and tweaks like that.

Hop

Last but not least, Hop will be familiar if you’ve used AceJump or EasyMotion. The premise is, you hit a shortcut (I have mine on <leader>j), and the visible area of the buffer gets a series of marks next each word. You then type those letters to jump to that point. If you don’t need it that granular, you can use it for a quick line jump too. Perhaps cleverest though is that you can use it to extend a visual range. So, say I have a file open in a buffer, I can enter visual mode, fire Hop and then extend my selection area to that point. I haven’t quite got the muscle memory there for Hop yet but I’m working on it!

a text editor annotated with hop points
Hop is a great implementation of AceJump or EasyMotion

Summary

There are more plugins in my init.lua, that support the fancier plugins I’ve shown here but I wanted to concentrate on showing you the headline stuff; the things that might make you raise an eyebrow if you’ve never used Neovim 0.5.

I’ve listed the GitHub repos for all the plugins I’ve covered below but let me know if you have something better in the comments.

There’s also a link to my init.lua and a few reading resources if you want to give any of these things a try.

If this was useful please give it a like so others can find it and if you’d like more tech, web and keyboard videos, please subscribe!

My init.lua

@benfrain init.lua https://gist.github.com/benfrain/97f2b91087121b2d4ba0dcc4202d252f

List of Plugins

Neovim resources