Neovim: how I configure my colorschemes
Tags: neovim, colorschemes, lua, configuration
Published: 2023-07-07 12:48:29

This is nothing crazy, but I like the pattern and guess someone might like it too.

I decided I wanted to separate editor config from individual plugin configuration. Editor config (e.g. which colorscheme to use) should be in a config file, and how to use/config that colorscheme should stay in a separate config.

So, I wrote this file under `lua/user/config.lua`:

```lua
-- lua/user/config.lua

return {
	colorscheme = "nightfox",
	variant = "carbonfox",
	filemanager = "mini.files", -- supported: mini.files, oil
	startup = {
		show_diagnostics = true,
		show_git_blame = false,
	},
}
```

It's pretty straight-forward, huh?

Next steps was to write indidividual colorscheme configurations. 

For each colorscheme I defined a file inside `lua/user/colorschemes/` with the individual plugin config.

Here's how I configured nightfox, as an example:

```lua
-- lua/user/plugins/colorschemes/nightfox.lua

local config = require("user.config")
local utils = require("user.utils")

local M = {
	"EdenEast/nightfox.nvim",
	lazy = false,
	priority = 1000,
}

M.supported_variants = { "carbonfox", "dawnfox", "dayfox", "duskfox", "nightfox", "nordfox", "terafox" }
M.default_variant = "nightfox"

M.variant = function()
	if not utils.contains(M.supported_variants, config.variant) then
		vim.notify("Variant " .. config.variant .. " not supported, defaulting to " .. M.default_variant)
	end

	return (config.variant or M.default_variant)
end

M.config = function()
	if config.colorscheme ~= "nightfox" then
		return false
	end

	vim.o.termguicolors = true
	vim.o.cursorline = true
	vim.o.cursorlineopt = "number"

	require("nightfox").setup({
		options = {
			styles = {
				comments = "italic",
			},
			colorblind = {
				enable = true,
				simulate_only = false,
				severity = {
					protan = 0.3,
					deutan = 0.4,
					tritan = 0.3,
				},
			},
			groups = {
				nightfox = {
					["@symbol"] = "palette.orange",
				},
			},
		},
	})

	local setup = [[
       colorscheme @variant@

	     highlight link @symbol String
	     highlight link @boolean @variable.builtin
	     highlight clear CursorLineNr
	     highlight link CursorLineNr String
	     highlight clear VertSplit
	     highlight link VertSplit String
	 ]]

	vim.cmd(string.gsub(setup, "@variant@", M.variant()))
end

return M
```

What's happening here?

- I defined some simple functions to help choosing a variant (`M.variant()`, `M.supported_variants()` and `M.default_variant()`);
- I defined the usual `M.config()` function for lazy.nvim. The interesting parts are:
  - the early exit (`return false`) in the first part of the function allows me to replicate this loading mechanism for all the colorschemes I have set up, but only load the one that's been specified in the `config.colorscheme` variable;
  - the rest of the file is usual stuff - colorscheme setup and some additional highlights to match my preferences.

This way - if I want to change the colorscheme being used at startup - I can edit the `config.lua` file without touching the rest of the config.

Adding a new colorscheme is as simple as adding a new file under `lua/user/colorschemes/`, write some boilerplate code to make it work, and voila, it works.

To see the whole config, here's the link to my dots:

- [dot-files/nvim](https://github.com/metalelf0/dot-files/tree/master/.config/nvim)