Ink's Space

My Neovim Setup

This is being published well after the config was finished, I don’t care much for blogging, so I never properly finished writing this.

So I have, for the last six or so months, been really trying to learn to use Neovim. I started with Vim, as I imagine many people do, and had a simple single file configuration with a couple of plugins and little else interesting going on. This original setup was stolen from Luke Smith, who really introduced me to Vim and why it’s so great. However, it didn’t take me long to learn about Neovim, and quickly I wanted to switch.

I think I got lucky regarding when I learnt about Neovim. It was soon after they integrated Lua into it and people were starting to really explore plugins for Neovim written in Lua. I quickly came across creators like TJ DeVries, chris@machine, and ThePrimeagen. By this point it was too late to turn back.

A Short Timeline

  • Initially I was using plain old vim, a pretty much vanilla experience with much holding of j, k, and the rest of the bad habits. This was based on Luke Smiths setup. My favourite part of this was his autocommand to clear whitespace on write.
  • Following this I moved on to nvim and came across chris@machines config for nvim. I don’t believe he maintains one anymore due to his work on LunarVim. I found his config right as he was making the decision to give up maintaining it, which turned out to be a blessing as I had to figure out many issues and really learned a lot about Lua, Neovim, and their combination. I also learned a lot about the different plugins available for nvim.
  • After getting Chris’s setup functional I quickly realised that much of it was not exactly to my liking, so I took it upon myself to rewrite it. Although I did so from scratch, much of it remained very similar, i.e.: the way he had his LSP setup.
  • I spent a while working on this new config, tinkering with bits here and there. I used/am using it for most of my personal development and my work at University. I was generally very happy with it.
  • About 2 weeks ago, from time of writing, I came across folke’s post on r/Neovim about his new plugin manager lazy.nvim. I had until that point been using packer.nvim and before that I was using vim-plug, which I honestly still love. This is where this story really starts.

My Config

Starting two weeks ago I started a full rewrite of my nvim config based around lazy.nvim and the early commits of LazyVim which is the distribution of nvim folke and others are creating around lazy.

I want to be really honest and clear here, Although I wrote all of my config myself, I leant very heavily on LazyVim. I learn by doing more than I learn by reading. I want to be clear that I am not taking credit for other peoples work. Folke is a wizard of a dev.

In this post I’m only going to cover setting up lazy.nvim in the manner than I have it configured. I will go further into depth about my config in future posts. I will omit things like my utility functions, keymaps, and indepth descriptions of my list of plugins.

File Structure

In the ~/.config/nvim/ folder I have the following items:

lua/
    chris/
        ...
    lazyvim/
        config/
            icons.lua
            autocommands.lua
            keymaps.lua
            options.lua
        plugins/
            core.lua
            ...
        utils/
            init.lua
            ...
        init.lua
init.lua
lazy-lock.json

The chris subdirectory contains my old config which I didn’t want to simply delete before completing my setup with lazy. I won’t be going into detail about what it contains here.

init.lua

Following the design of LazyVim my configuration is in its own module so my init.lua contains only a single line requiring said module. I used to configure each plugin separately and require them all from this file.

lazy-lock.json

This is a file that is automatically generated by lazy.nvim, it allows you to specifically version the plugins you have installed, down to specific commits. I don’t do this. Some people complain about their configurations breaking all the time due to plugin updates however I have had this happen only once so the effort required to version everything just isn’t worth it for me.

lua/lazyvim/

This is where the magic happens. It is a self contained module which describes and defines my config for Neovim.

lua/lazyvim/config

The config directory contains all of my non-plugin related configuration. I treat it like it’s its own module with an init.lua to pull everything together. Icons, keymaps (those not handled within plugin definitions, etc), autocommands, and options are all dealt with here.

Some great keymaps that I value a lot:

-- move lines up and down
map("n", "<C-k>", "<ESC>:m .-2<CR>==", opts)
map("n", "<C-j>", "<ESC>:m .+1<CR>==", opts)

-- center after up and down movements
map("n", "<C-u>", "<C-u>zz", opts)
map("n", "<C-d>", "<C-d>zz", opts)

-- move through quickfix list
map("n", "<C-n>", ":cnext<cr>", opts)
map("n", "<C-p>", ":cprev<cr>", opts)

Also, these autocommands:

-- highlight on yank, thanks stack overflow
vim.api.nvim_create_autocmd('TextYankPost', {
    group = vim.api.nvim_create_augroup('highlight_yank', {}),
    desc = 'Hightlight selection on yank',
    pattern = '*',
    callback = function()
        vim.highlight.on_yank { higroup = 'IncSearch', timeout = 500 }
    end,
})

-- go to last loc when opening a buffer
vim.api.nvim_create_autocmd("BufReadPost", {
    callback = function()
        local mark = vim.api.nvim_buf_get_mark(0, '"')
        local lcount = vim.api.nvim_buf_line_count(0)
        if mark[1] > 0 and mark[1] <= lcount then
            pcall(vim.api.nvim_win_set_cursor, 0, mark)
        end
    end,
})

lua/lazyvim/utils

The utils folder contains some miscellaneous utilities such as a function to get a projects root for Language Server Protocols (LSPs) or a workspace switcher function for Neorg (a org mode like plugin for nvim).

Many of these utils have been pilfered from other Neovim users, thanks everyone. Other peoples configs are always a good place to start learning, especially in the context of Neovim. I hope to greatly expand the content of this folder in the future.

lua/lazyvim/init.lua

This is the primary initialisation for my config, following the lazy.nvim spec, it ensures that lazy is installed and then runs the basic initialisation for lazy, my config, colorscheme, etc.

lua/lazyvim/plugins

This is where all of the specifications for the plugins I use live. I change these a little from time to time, but now everything is set up, I try to limit changes in general. I strongly recommend looking through if you’re interested, here’s a link

Notes

For now, this is where I’m going to leave it at, I might add more in the future though. For the interested individual I think that the best way to learn is to read the code, so I suggest looking at my config on gitlab.