Home

How to use private NeoVim plugins on NixOS

Over time my config changed a lot since the early days, as of now I'm using a combination of Flakes and home-manager to manage my workstations. I try not to overthink too much when it comes to Nix, my current Neovim setup is pretty simple, lua-based, yet, fully nixified.

dotfiles
├── (...)
├── nvim
│   ├── files.lua
│   ├── line.lua
│   ├── lsp.lua
│   ├── settings.lua
│   ├── tabs.lua
│   └── treesitter.lua
├── (...)
└── zsh
    └── zshrc

I do it by having a simple directory where all my Neovim derivations stand.

home
├── (...)
├── development
│   ├── cloud.nix
│   ├── default.nix
│   ├── git.nix
│   ├── iac.nix
│   ├── kubernetes.nix
│   └── programming.nix
├── editors.nix
├── (...)
├── neovim
│   ├── default.nix
│   ├── packages.nix
│   └── private.nix
├── (...)
└── zshell.nix

here's an example of what a private.nix file would look like, this is useful when you want to use some package that's not available yet into nixpkgs.

{ pkgs, config }:

let
    plugin = pkgs.vimUtils.buildVimPlugin;
in
{
    vim-taskjuggler = plugin {
	name = "vim-taskjuggler";
	src = pkgs.fetchFromGitHub {
	    owner = "kalafut";
	    repo = "vim-taskjuggler";
	    rev = "e94c9a0b06022d11a34310ad5f82c1c2bcd86fb7";
	    sha256 = "0f8smjl6wi52p8n1hhl5zhk8i3lpsfndxxdammyybw2vz17s0j8q";
	};
    };
}

then you can just import it from other files:

{ pkgs, config, lib, ... }:

let
  plugins = pkgs.vimPlugins;
  private = import ./private.nix { inherit pkgs config; };
in
{
  base = with plugins; [
    nvim-surround
    vim-which-key
    vim-visual-multi
    hologram-nvim
  ];
  eyecandy = with plugins // private; [
    kanagawa-nvim
    nvim-colorizer-lua
    nvim-cursorline
    nvim-web-devicons
    tokyonight-nvim
  ];
  ui = with plugins; [
    # File Tree
    nvim-tree-lua
    # Find/Filter
    plenary-nvim
    telescope-nvim
    # Status Line
    lualine-nvim
    # Tabs
    barbar-nvim
  ];
  lsp = with plugins // private; [
    nvim-cmp
    nvim-lspconfig
    (nvim-treesitter.withPlugins (p:
      [
	p.c
	p.bash
	p.dockerfile
	p.gitignore
	p.lua
	p.markdown
	p.nix
	p.proto
	p.scheme
	p.sql
	p.terraform
	p.yaml
      ]
    ))
    # Snippets
    luasnip
    cmp-git
    # CMP Plugins
    cmp-cmdline
    cmp_luasnip
    cmp-nvim-lsp
    cmp-path
    cmp-treesitter
  ];
  tooling = with plugins; [
    direnv-vim
    Ionide-vim
    vim-nix
    vim-terraform
  ];
}

and since Neovim has an awesome module in home-manager, make sure to use it:

programs.neovim = {
  enable = true;

  # (...)
  plugins = vimPlugins.base ++ vimPlugins.eyecandy ++ vimPlugins.ui ++ vimPlugins.lsp ++ vimPlugins.tooling;
};

If you want to see an up-to-date version of these dotfiles, feel free to steal take a look here.