Converting Neovim Config to Lua

neovim logo

I have been using neovim for a while & was excited about the new features coming in 0.5 so started thinking about changing my config to lua a while ago.

Initially I installed neovim 0.5 beta & used it for rust using rust-analyzer with nvim_lsp. ( 11 Apr 2021 /equk/neovim-lua/ )

I was really happy with how it worked but held off of converting my full config to lua until 0.5 was officially released.

Neovim 0.5 New Features

  • Built-in LSP client
  • Tree-sitter
  • Lua API changes

Language Server Protocol (LSP)

The Language Server Protocol (LSP) is an open, JSON-RPC-based protocol for use between source code editors or integrated development environments (IDEs) and servers that provide programming language-specific features.
LSP was originally developed for Microsoft Visual Studio Code and is now an open standard.

Language Server Protocol on Github


Tree-sitter is a parser generator tool and an incremental parsing library. It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited.

Tree-sitter on Github


The biggest thing with Neovim 0.5 is the built-in lsp client as it meant I could replace a lot of language specific plugins with lsp configs.

Being able to use lua for almost everything also meant I could replace python plugins with more performant lua ones.

  • deoplete (python) to cmp (lua)
  • Ultisnips (python) to luasnip (lua).

Config Structure

I first started with a few files to test things but later on I restructured the configs into folders making the configs more modular.

β”œβ”€β”€ init.lua
└── lua
    └── eq
        β”œβ”€β”€ ale
        β”œβ”€β”€ completion
        β”œβ”€β”€ keymap
        β”œβ”€β”€ lightline
        β”œβ”€β”€ lsp
        β”œβ”€β”€ options
        β”œβ”€β”€ plugins
        β”œβ”€β”€ telescope
        └── treesitter

This makes it easier to add features & fix problems with specific plugins.


At first I was using completion-nvim for completion but read a few posts suggesting cmp was more actively developed so ended up changing to that.

---- completion
use {
  requires = {

Using cmp also meant I could use luasnip with snippets from friendly-snippets.

---- snippets
-- use snippets from friendly-snippets
local snip_loader = require 'luasnip/loaders/from_vscode'


Telescope is a fuzzy finder with huge customizability & extensive functionality.

This is probably one of my most used plugins when working on large projects.
It is also performant when used with the fzf-native extension.

I only have a few keys mapped for it so far but will probably add more as I look into it.

So far I have key mappings setup for

  • file searching (without preview)
  • git status (with diff preview)
  • live grep (search within files)
  • git files (without preview)

tjdevries - Why Telescope?
Vim Telescope: The Ultimate Fuzzy Finder


There seem to be a lot of different implementations for linting files but I have kept it simple with lint on save using the plugin ale.

---- ale config
-- only used for linting on save
vim.g.ale_fix_on_save = 1
vim.g.ale_lint_on_enter = 0
vim.g.ale_lint_on_insert_leave = 0
vim.g.ale_lint_on_filetype_changed = 0
vim.g.ale_lint_on_text_changed = 'never'
vim.g.ale_disable_lsp = 1

I notice there are people looking into adding linting using language servers etc so might change later but lint on save seems to work & is performant enough.

Helpful Resources

Most of the configuration was simple using the documentation provided on github by plugin developers but I did read a few articles & browsed other users configs which helped.

tjdevries - config_manager
nanotee - neovim lua guide
sharksforarms - Neovim and Rust
Neovim on Github

Neovim Configs

You can find my dotfiles on github.
I also have a seperate neovim-lua repo which shows how the configs took shape over time while I was testing new features.

dotfiles neovim-lua