Neovim via Nixos (but not too much)
Thinner wrappers, impure symlinks

- neovim-with-plugins.nix is a neovim-wrapper heavily inspired by @viperML's blog post
- symlink.nix is a very basic symlinking mechanism that allows for nix-based (copied to /nix/store, immutable) and regular filesystem (symlinked from wherever, impure) sources, heavily inspired by (and borrowing code from) @jade's blog post
I've been using nixpkgs' programs.neovim
module happily for a while now, with an init.lua
packaged as a plugin, for nice lua editing experience. However, the edit / build / debug iteration cycle of this setup is quite slow.
Overall, this kind of wrapper feels quite "thick"; which can be a benefit, as mentioned by @fzakaria 's post', since you're pushing a whole executable and configuration as a program.
I wanted something halfway in between, using nixpkgs' vimPlugin infrastructure, but supplying my own ~/.config/nvim
for config.
@viperML had a great post on writing your own neovim wrapper, from which I borrowed heavily in writing neovim-with-plugins. It's basically a thinner wrapper, you give it a list of vimPlugins you want included in the wrapped packpath; not-yet-packaged vimPlugins can be defined witih vimUtils.buildVimPlugin
:
# nvim-config.nix
{ pkgs, ... }:
{
environment.variables = { EDITOR = "nvim"; };
programs.neovim-with-plugins = {
enable = true;
startPlugins = with pkgs.vimPlugins; let
vim-godot = pkgs.vimUtils.buildVimPlugin {
name = "vim-godot";
src = pkgs.fetchFromGitHub {
owner = "habamax";
repo = "vim-godot";
rev = "1c8385789f7f4558bdbbf6e75033b34b4727944b";
sha256 = "sha256-uqe954fyDK5d5D+Tm/iDLXHfxFYO7BiLdQYyS4UGFMs=";
# sha256-uqe954fyDK5d5D+Tm/iDLXHfxFYO7BiLdQYyS4UGFMs=
};
};
in [
nvim-treesitter.withAllGrammars
telescope-nvim
vim-godot
];
};
}
For config, I took inspiration (and the bash script) from @jade 's post on supplying configs through non-nix means. symlink.nix is a very basic symlinking mechanism that allows for nix-based (copied to /nix/store, immutable) and regular filesystem (symlinked from wherever, impure) sources.
I use it this way to symlink directly from my nixos config repo checkout to ~/.config/nvim
; changes take effect immediately, and are checked in / pulled along with the nixos configuration repo:
{
services.symlink = {
enable = true;
entries = {
"/home/alexou/.config/nvim" = {
sourcePathImpure = "/home/alexou/dev/amp/nix_hosts/self/modules/config/nvim";
};
};
};
}
For my servers where I don't have a full checkout of my nixos repo, I would do something similar but with sourcePath
, which would copy nvim/
into /nix/store
and link it to ~/.config/nvim
, as home-manager.file
would do:
{
services.symlink = {
enable = true;
entries = {
"/home/deploy_user/.config/nvim" = {
sourcePath = ./nvim;
};
};
};
}
Some caveats:
For neovim python, I copied what nixpkgs' programs.neovim
does for python -- wrap a pythonEnv that has pynvim. But as I wasn't generating the config in nix, I have to set it manually in init.lua
:
vim.. = '/run/current-system/sw/bin/nvim-python3'
Could not for the life of me figure out how to properly escape the single quotes to set it in the wrapper.
I would also not recommend using my flake and importing these modules -- they're small enough that you can just read and write your own versions. Or better yet, go read the blog posts linked above, they're better and more original.