If you're like me and use nixos, you might've wondered, how can i configure my editor, neovim, with nix? Well, there are multiple approaches, one of them being configuring programs.neovim
with nix and then configuring plugins itself in lua. While it's alright, I like the other approach more, nixvim.
For me, I started migrating to nix-colors to declaratively color my setup. When I've already migrated a lot of things, I needed to color my neovim. I tried to add some extra lua config with nix itself. I couldn't get it to work. Moreover, my config was getting too bad and unmaintained throwing errors at me on every keypress. So, i decided to try out nixvim.
Keep in mind that as of writing those lines, I'm still learning nixvim and configuring neovim with it, so I might update this post.
Let's start
Installation
So, You have your nixos config working and now it's time to migrate the editor. First of all, you should start by adding nixvim to your configuration.
With flakes:
Without flakes:
With this done, you should now have nixvim installed. If you plan on using nixvim in your home configuration itself, don't forget to remove your old way of installing neovim and your config, as it can (and probably will) break nixvim's generated config.
While we're at it, I should mention caveats of nixvim, being:
- No lazy loading
- Not all plugins are packaged (have to use lua)
While the second caveat is not that significant, first can be a deal-breaker for you. While I notice quite a big difference (~20 vs ~200 ms) in loading time compared to my old vim config, it's not that bad. If you have an older pc and rely on lazy loading a lot, you might want to keep using your old config.
While there is work going on about adding lazy-loading, there is not a lot of progress at the moment of writing.
Usage
To actually use nixvim you can either use it as a home-manager module or as a standalone flake. While being able to download and use your flake on any nix system in one command, home-manager module can provide a better integration with your config. I use a home-manager module approach as I use base16. If you dont need such functionality i highly advise you on using a separate flake.
For this guide i will use nixvim as a home-manager module. When using nixvim as a flake, it's almost the same, the only difference being is not to use programs.nixvim
for your nixvim-related config. To init a nixvim flake you can use
This will initialize a nixvim flake template in the current directory. The config is located inside config
directory with bufferline already being in a separate file. If you look into any file, you will see that it's just plugins.something
and not programs.nixvim.plugins.something
. This is the only difference (not counting having to use nix run
, of course). The rest is (hopefully) the same.
Let's install a few plugins, shall we? To do so, create a file for nixvim in your nix config. Then enable nixvim like so:
Now you should be able to access unconfigured nvim
if you rebuild. Let's go further from here.
To install plugins and colorschemes, configure neovim and do something with nixvim in general, you should refer to the documentation. It's good and there's a lot of info here.
For now I'll add a colorscheme. I will use catppuccin mocha. Then I'll install lualine. Our file now looks like this
Now, rebuild. You should see neovim with a colorscheme now and lualine installed. Wonderful.
Neovim themed with catppuccin mocha
Nixvim also has options
. They are your neovim opts
. If you want to show relative line numbers, set shiftwidth to 2 and use termguicolors:
As you can see, this is pretty simple.
Same with seting the clipboard to the system clipboard:
Or setting leader to space:
With this in mind you can now configure neovim. For example, let's install lsp and autocomplete to be able to edit our config with it.
Our entire config file looks like this:
That's it! You can now write your nixvim config with neovim itself. Find more options in the documentation
But, there is a problem. What if your package is not packaged in nixvim?
Extra plugins
Nixvim supports adding extra plugins and configuring them with lua. I will use smart-splits as an example, as it's not yet packaged as of writing this (but there is work ongoing that started after I've filled an issue)
PS: It's now in nixvim!
Plugins that are in nixpkgs
Packaging extra plugins is pretty simple. The file looks like this:
Notice here how we are adding a plugin packaged in nixpkgs but not in nixvim itself (highlighted lines). Then we add extraConfigLua
to nixvim so that we can setup the plugin. It's pretty simple if you know lua.
But what if you have some niche plugin that's not in nixpkgs?
Plugins that are not in nixpkgs
For this example I will add [ultimate-autopair] which is actually already in nixpkgs, but let's pretend it isn't.
We can use buildVimPlugin
function to install the plugin like this:
As you can see, you install the plugin similar to one in nixpkgs, it's just buildVimPlugin that's different.
The problem with this approach is that you need to manually change rev
and sha256
to update the plugin. I suggest you to request it to be packaged in nixvim if you think that it should be packaged.
Another thing to keep in mind with installing plugins from nixpkgs/github directly is that breaking changes can occur and that you will need to change your lua code. If you can, try to find an alternative plugin. If you can't, try to package it in nixvim if you have the knowledge. If not, file an issue.
Modularizing the config
If you look at our config file now, it's quite big. And our config is very simple! Imagine what would happen if your config would be ten times bigger? This is no good. That's why you should modularize the config.
I personally separate it in multiple directories and then files inside, but for this guide i will just separate them into files with no directories. Create another file, say, bufferline.nix
. In it we can just write something like this:
Then, we need to import the file in the main config.
As you can see, modularizing your config is as simple as having multiple programs.nixvim
entries (same but without programs.nixvim
in a separate flake).
My config structure is as follows:
You can find the config on my github
Useful snippets
After using nixvim for a while I've added some cool stuff to my nixos config. Here are all the snippets of them:
Exit telescope on single escape press.
To do so, just add this to your telescope config:
Then it should just work after a rebuild
Customizing which-key groups
Groups in which-key are something like +prefix
by default. I have them like so:
Which-key buffer with a nerd-font emoji and custom text
To do the same (for this example to add Find
one from my config) just include this piece of code in your config:
And if you want to get the same circle separator:
Using neovim from master (0.10 for now)
If you want to use neovim compiled from master (say, to get inlay hints), it's possible.
If you use flakes the process is simple. Just add a new input like so:
And then, add an overlay:
If you don't use flakes, just add the overlay from github:
After that just set package in nixvim:
After that, rebuild. You should now have latest neovim.
Using base16 colorscheme
If you're like me and use nix-colors for your colorscheme (or any base16 colorscheme for that matter), you might want to rice your nixvim automatically. Nixvim has such option, being colorschemes.base16.
To use it, all you need to do is:
Usage with nix-colors:
If you don't use nix-colors, process is same. You just set customColorScheme to an attrset of values like this one:
There is also an option of using colorScheme
(naming is strange, I know) which accepts a string of the colorscheme itself and then uses base16 variant. For example, you can set it to catppuccin-mocha
or gruvbox-dark-medium
.