Meta(
    title: "Neovim: init.lua from scratch",
    summary: Some("I tried my usual goto for bootstrapping my NeoVim config on FreeBSD only to find it broken"),
    published: Some(Time(
        year: 2023,
        month: 6,
        day: 19,
        hour: 4,
        minute: 34,
        second: 31,
    )),
    tags: [
        "neovim",
        "vim",
        "lua",
        "compatability",
    ],
)
---
After chucking one of my only remaining Arch installations in favor of FreeBSD (now a dual boot with Void) I've been one by one massaging my dotfiles and fixing software compatibility issues to get my preferred environment up and running. Only yesterday I managed to get my multiplexer, Zellij, up and running by backporting a fix from upstream git to their current release. I've been having trouble getting my NeoVim config setup, in that it was reporting that it couldn't set up language servers, and last night after work I began investigating.

I've been using kickstart.nvim for a while as a jumping off point, as when I made the switch from an init.vim to init.lua I didn't really feel like starting from scratch. But what I found bothered me enough that I chucked it all. About four months ago they switched from the Vim package manager they had always used, Packer, to a new one called Lazy. I've never experienced issues with Packer, but if that was the only change and things were working I'd probably just roll with it. They also switched from just using the NeoVim official lsp support package to a new plugin called Mason which is supposed to make installing new language servers easier. Crap, here we go.

So Mason may or may not actually do what it says it does, ON LINUX. It doesn't even attempt to work on FreeBSD. Once it detects that you're running FreeBSD it exits with an 'Unsupported Platform' error message. I'm getting really tired of this crap. This is the sort of lazy programming that made me throw in the towel ten years ago and switch back to Linux, but I'm kinda pissed about it now and motivated to fix things where I can.

I consider this particular pattern of checking what OS you're running rather than checking for features to be lazy and stupid. There's a great article on exactly this sort of thing by the author of the hobby OS Sortix in relation to GNU Gnulib, where he argues to great effect that instead of checking for the platform one should be checking for features. He's 100% correct, but unfortunately in the real world programmers get lazy about this sort of thing and sometimes programming languages and frameworks are not your friend here.

Anyway, this is in my view another example of piling abstraction on top of abstraction, as Neovim comes out of the box with support for lsp servers and just needs to be properly configured in order to use them. As annoying as the extra layers are, I might have still taken the route of rolling back to an earlier version of Kickstart, except that when I looked at the git history there are literally no releases or even tags to roll back to. I decided in the end this is just not the sort of code I want running on my system if they take such a laissez-faire approach while moving at breakneck speed. So I set out to actually learn how to write an init.lua from scratch, with the hope that what I wound up with would be lighter, easier to maintain, easier to migrate to a new machine and better tailored to how I use my editor.

It turns out that this is not all that hard to do with a little patience and a lot of searching. Some parts of my config are of course still literal cut and paste from project pages for the plugins that I did keep. But I definitely have a better understanding of what's going on overall and there shouldn't be any surprises luring around to bite me later. Lua is such a simple language that if you have any programming experience you'll be off and running without ever having to read the docs, just by looking at code samples.

Right now I've got the plugins list pared down to the following:
* Packer for managing plugins
* nvim-lspconfig to manage lsp configuration
* telescope for quickly navigating between files in a project
* nvim-cmp for snippets and completions
* vim-fugitive for Git integration

I've gotten rid of all the TreeSitter highlighting, as I'm totally fine with Neovim's inbuilt syntax highlighting. Also gone are things like color themes and status line plugins. All told, while Kickstart gives you what they call a "minimal" starting point with a 515 line init.lua mine is currently at 168 lines. I may add a few more leader shortcuts, and possibly futz around with the default colors a bit, but I think I'm mostly done and happy with it.

One feature that I tried to retain is the ability to bootstrap itself just by dropping the init.lua into a new machine and running a couple of commands. The project page for Packer has a suggested function to add to init.lua which, if packer is not installed, shells out to git clone the repository into the correct location. It's a pretty small and easy to understand bit of code, just as it should be.