Skip to content

Instantly share code, notes, and snippets.

@nat-418
Last active November 12, 2024 13:39
Show Gist options
  • Save nat-418/493d40b807132d2643a7058188bff1ca to your computer and use it in GitHub Desktop.
Save nat-418/493d40b807132d2643a7058188bff1ca to your computer and use it in GitHub Desktop.
Advanced Neovim configuration with Nix and Home Manager

From init.lua to default.nix

In a previous post I explained how to manage Neovim plugins with Nix and Home Manager. In this post I want to go further and show how to migrate Neovim configuration from ~/.config/nvim to ~/.config/home-manager entirely. The end result will be to split our Neovim setup into multiple modules that colocate plugin sourcing and configuration.

If you haven't read the post linked above, do so now. We will assume the configuration of that post as the basis for the rest of the steps.

  1. First, create a new directory at ~/.config/home-manager/nvim and move your existing Home Manager Neovim config to ~/.config/home-manager/nvim/default.nix:
{ 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

{
  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. Next, edit ~/.config/home-manager/home.nix and import the new file. Note that Nix looks for default.nix in the directory automatically, so we don't have to specify it.
{ ... }:

{
  imports = [
    ./nvim
  ];

  home = {
    username = "test";
    homeDirectory = "/home/test";
  };
}
  1. Now make a ~/.config/home-manager/functions directory and split out the fromGitHub function into a new file at ~/.config/home-manager/functions/fromGitHub.nix. This will make the function reusable across multiple files.
{user, repo, ref ? "HEAD", buildScript ? ":"}:

let
  pkgs = import <nixpkgs> {};
in

pkgs.vimUtils.buildVimPlugin {
  pname = "${pkgs.lib.strings.sanitizeDerivationName repo}";
  version = ref;
  src = builtins.fetchGit {
    url = "https://github.com/${user}/${repo}.git";
    inherit ref;
  };
  inherit buildScript;
}
  1. Modify ~/.config/home-manager/nvim/default.nix to use the new function file.
# [...]
let
  fromGitHub = import ../functions/fromGitHub.nix;
in
# [...]
  1. Write a new file at ~/.config/home-manager/nvim/colorscheme.nix. The /* lua */ comment will allow LSP and Treesitter to work within the following multiline string, assuming your Neovim configuration is setup correctly.
{ pkgs, ... }:

{
  programs.neovim = {
    plugins = with pkgs.vimPlugins; [
      gruvbox-material
    ];
    extraLuaConfig = /* lua */ ''
      vim.o.termguicolors  = true
      vim.cmd('colorscheme gruvbox-material')
      vim.g.gruvbox_material_background = 'hard'
    '';
  };
}
  1. Import the new file from default.nix and remove the colorscheme plugin from the plugins list.
{ config, pkgs, lib, ...}:

let
  fromGitHub = import ../functions/fromGitHub.nix;
in

{
  imports = [
    ./colorscheme.nix
  ];
  programs.neovim = {
    enable = true;
    defaultEditor = true;
    viAlias = true;
    vimAlias = true;
    vimdiffAlias = true;
    plugins = with pkgs.vimPlugins; [
      nvim-lspconfig
      nvim-treesitter.withAllGrammars
      plenary-nvim
      mini-nvim
      (fromGitHub "HEAD" "elihunter173/dirbuf.nvim")
    ];
  };
}
  1. Repeat the above pattern of moving plugins and config to various imports until all your Neovim configuration is fully within Home Manager. Then run $ home-manager switch -b nvim-backup to let Home Manager produce your Neovim configuration programatically. Now you can stop backing up ~/.config/nvim and rollback your configuration whenever something goes wrong.
@samueljoli
Copy link

@nat-418 Curious as to why you wouldn't recommend using flakes. Super new to nix and allow it flakes aren't stable, everyone seems to use/recommend them.

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