Setup Neovim With Zig

ยท 495 words ยท 3 minute read

Here is what I do to configure Neovim to work with Zig for syntax highlighting and the language server:

Skip to just the files

You will need the following: ๐Ÿ”—

  • A MacOS device
  • Neovim >=0.8 installed
  • Zig installed
  • zls version that matches the Zig version above installed
  • tree-sitter-cli installed (can use homebrew: brew install tree-sitter)

Configuration: ๐Ÿ”—

1. Install a Neovim package manager ๐Ÿ”—

I used the lazy.nvim package manager for Neovim. Install it like this:

git clone --filter=blob:none https://github.com/folke/lazy.nvim.git ~/.local/share/nvim/lazy/lazy.nvim

Then we configure Neovim to use lazy.nvim. Edit the file ~/.config/nvim/init.lua and add:

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

Restart Neovim to check if the installation succeeded. You should be able to bring up the lazy.nvim interface by typing :Lazy in Neovim. Exit it by using :q

2. Add the relevant plugins for Zig ๐Ÿ”—

We are going to use the nvim-lspconfig to setup zls and tree-sitter for syntax highlighting. So let’s first install those as plugins from lazy.nvim.

Add these lines to your ~/.config/nvim/init.lua:

1require("lazy").setup({
2    { "neovim/nvim-lspconfig" },
3    {
4        "nvim-treesitter/nvim-treesitter",
5        build = ":TSUpdate",
6    },
7})

Restart your Neovim and let the plugins get installed.

3. Configure the plugins ๐Ÿ”—

We only need to setup nvim-lspconfig so create a directory called lua in your ~/.config/nvim directory. Create a file lsp.lua in that directory:

~/.config/nvim/lua/lsp.lua contents:

 1local lspconfig = require("lspconfig")
 2lspconfig.zls.setup {
 3  cmd = { "zls" },
 4  filetypes = { "zig", "zir" },
 5  root_dir = lspconfig.util.root_pattern("build.zig", ".git") or vim.loop.cwd,
 6  single_file_support = true,
 7}
 8
 9vim.api.nvim_create_autocmd("LspAttach", {
10  callback = function(args)
11    local opts = { buffer = args.buf }
12    vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) -- Go to definition
13    vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)       -- Hover info
14  end,
15})

Next we have to edit our ~/.config/nvim/init.lua to use the plugins in neovim. Add the following to your init.lua:

require("lsp")

require("nvim-treesitter.configs").setup {
    ensure_installed = { "zig" },
    highlight = { enable = true },
}

Restart your Neovim if you had it open and you should be all set. Here’s the full contents of all files:

TL;DR Just the contents of the files: ๐Ÿ”—

~/.config/nvim/init.lua:

 1local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
 2if not vim.loop.fs_stat(lazypath) then
 3  vim.fn.system({
 4    "git",
 5    "clone",
 6    "--filter=blob:none",
 7    "https://github.com/folke/lazy.nvim.git",
 8    lazypath,
 9  })
10end
11vim.opt.rtp:prepend(lazypath)
12
13-- Setup plugins
14require("lazy").setup({
15    { "neovim/nvim-lspconfig" },
16    {
17        "nvim-treesitter/nvim-treesitter",
18        build = ":TSUpdate",
19    },
20})
21
22require("lsp")
23
24require("nvim-treesitter.configs").setup {
25    ensure_installed = { "zig" },
26    highlight = { enable = true },
27}

~/.config/nvim/lua/lsp.lua:

 1local lspconfig = require("lspconfig")
 2lspconfig.zls.setup {
 3  cmd = { "zls" },
 4  filetypes = { "zig", "zir" },
 5  root_dir = lspconfig.util.root_pattern("build.zig", ".git") or vim.loop.cwd,
 6  single_file_support = true,
 7}
 8
 9vim.api.nvim_create_autocmd("LspAttach", {
10  callback = function(args)
11    local opts = { buffer = args.buf }
12    vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) -- Go to definition
13    vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)       -- Hover info
14  end,
15})