Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fcoury/dc8d13bdc065130eedb5c5cf623e4e3f to your computer and use it in GitHub Desktop.
Save fcoury/dc8d13bdc065130eedb5c5cf623e4e3f to your computer and use it in GitHub Desktop.
Manage Neovim plugins (and more!) with Nix and Home Manager

Manage Neovim plugins (and more!) with Nix and Home Manager

Highly extensible software like Emacs, Vim, and Neovim tend to grow their own package managers. A software developer, for example, might want to install editor plugins that hook into a particular programming language's linter or language server. The programmer's text editor is therefore extended to support managing additional software to extend the text editor. If this loop continues for too long, the programmer's editor becomes more delicate and complex. The remedy for this problem is to manage software using dedicated tools apart from the programmer's editor itself, and the most powerful tool to do that in 2023 is Nix.

Put simply, using Nix and Home Manager allows users to declaratively configure their software in a reliable, reproducible, and largely self-documenting way. Once set up, a user can easily copy their configuration over to a new machine and get everything working quickly. Nix does have a learning curve, but climbing that curve is worth the effort.

To help newcomers try this, below is an example using Nix with Home Manager to configure Neovim without a Neovim-based plugin manager like packer.nvim or vim-plug. The following steps were tested on Debian 11:

  1. Install Nix. For this guide, we are going to follow the single-user installation instructions:

    $ sh <(curl -L https://nixos.org/nix/install) --no-daemon
  2. Add the Home Manager Nix channel:

    $ nix-channel --add https://github.com/nix-community/home-manager/archive/release-22.11.tar.gz home-manager
    $ nix-channel --update
    
  3. And then add this bit of configuration to your shell:

    export NIX_PATH=$HOME/.nix-defexpr/channels:/nix/var/nix/profiles/per-user/root/channels${NIX_PATH:+:$NIX_PATH}
    
  4. Install Home Manager:

    $ nix-shell '<home-manager>' -A install
    
  5. Edit the Home Manager configuration file found at ~/.config/nixpkgs/home.nix. The default should look something like this:

    { config, pkgs, ...}:
    {
      home.username = "test";
      home.homeDirectory = "/home/test";
      home.stateVersion = "22.11";
      programs.home-manager.enable = true;
    }
    # Comments in this file were removed for brevity.

    Use the Home Manager Option Search to find relevant configuration to add. Let's start with Neovim and git:

    { config, pkgs, ...}:
    {
      home.username = "test";
      home.homeDirectory = "/home/test";
      home.stateVersion = "22.11";
      programs.home-manager.enable = true;
      programs.git.enable = true;
      programs.neovim.enable = true;
    }
  6. Rebuild the Home Manager configuration: $ home-manager switch. This will either throw an error if the configuration file is errant, or spew a bunch of text and successfully install Neovim and git.

  7. Add more Neovim configuration. For this example, we want Neovim to be our default editor, and also be aliased to vi, vim, and vimdiff:

    { config, pkgs, ...}:
    {
      home.username = "test";
      home.homeDirectory = "/home/test";
      home.stateVersion = "22.11";
      programs.home-manager.enable = true;
      programs.git.enable = true;
      programs.neovim = {
        enable = true;
        defaultEditor = true;
        viAlias = true;
        vimAlias = true;
        vimdiffAlias = true;
      };
    }
  8. Rebuild the Home Manager configuration: $ home-manager switch.

  9. Add some plugins:

    { config, pkgs, ...}:
    {
      home.username = "test";
      home.homeDirectory = "/home/test";
      home.stateVersion = "22.11";
      programs.home-manager.enable = true;
      programs.git.enable = true;
      programs.neovim = {
        enable = true;
        defaultEditor = true;
        viAlias = true;
        vimAlias = true;
        vimdiffAlias = true;
        plugins = with pkgs.vimPlugins; [
          nvim-lspconfig
          nvim-treesitter.withAllGrammars
          plenary-nvim
          gruvbox-material
          mini-nvim
        ];
        # Use the Nix package search engine to find
        # even more plugins : https://search.nixos.org/packages
      };
    }
  10. Rebuild the Home Manager configuration: $ home-manager switch.

  11. Not every Neovim plugin is already packaged in the Nix package repository, so let's write a little Nix function to help us download packages hosted on GitHub:

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

let
  fromGitHub = ref: repo: pkgs.vimUtils.buildVimPluginFrom2Nix {
    pname = "${lib.strings.sanitizeDerivationName repo}";
    version = ref;
    src = builtins.fetchGit {
      url = "https://github.com/${repo}.git";
      ref = ref;
    };
  };
in

{
  home.username = "test";
  home.homeDirectory = "/home/test";
  home.stateVersion = "22.11";
  programs.home-manager.enable = true;
  programs.git.enable = true;
  programs.neovim = {
    enable = true;
    defaultEditor = true;
    viAlias = true;
    vimAlias = true;
    vimdiffAlias = true;
    plugins = with pkgs.vimPlugins; [
      nvim-lspconfig
      nvim-treesitter.withAllGrammars
      plenary-nvim
      gruvbox-material
      mini-nvim
      (fromGitHub "HEAD" "elihunter173/dirbuf.nvim")
    ];
  };
}
  1. Rebuild the Home Manager configuration: $ home-manager switch.

Hopefully this is enough of an example to give a sense of how working with Nix and Home Manager is a significant improvement over configuring each application individually. Credit to Felix Breuer for that nice GitHub downloading function. There is much more to Nix and Home Manager then what was illustrated above, so please read their manuals, learn, explore, and enjoy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment