Installing and configuring nixvim entirely from home-manager

Hi all. I’m fairly new to modules, home manager and flakes in NixOS, and I’m trying to get nixvim to work entirely from my home-manager module. I want to be able to configure nixvim in my home-manager module home.nix like this since I keep all other configurations there:

programs.nixvim = {
    enable = true;
    # more options...
};

I use flakes for the home-manager module, but I’m not sure how to make the option programs.nixvim... available in home.nix. When I try to rebuild I get this error:

error: The option `home-manager.users.default.programs.nixvim' does not exist.

To me it’s not crystal clear how I should “add” nixvim to the home manager module. My flake.nix looks like this at the moment:

{
  description = "Nixos config flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    hyprland.url = "github:hyprwm/Hyprland";
    hyprland-plugins = {
      url = "github:hyprwm/hyprland-plugins";
      inputs.hyprland.follows = "hyprland";
    };

    nixvim = {
      url = "github:nix-community/nixvim";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, ... }@inputs:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
      };
    in
    {
      nixosConfigurations.default = nixpkgs.lib.nixosSystem {
          specialArgs = {inherit inputs;};
          modules = [ 
            ./configuration.nix
            inputs.home-manager.nixosModules.default
          ];
        };
	
      homeConfiguration.default =
        inputs.home-manager.lib.homeManagerConfiguration {
	 inherit pkgs;
	 modules = [
	   ./home.nix
	 ];
	 extraSpecialArgs = { inherit inputs; };
	};
    };
}

Any help is greatly appreciated!

my first idea would be that you need to pass the nixvim input as a module into the home manager config

homeConfigurations = {
  mee = home-manager.lib.homeManagerConfiguration {
    inherit pkgs;
    extraSpecialArgs = {
    };
    modules = [
      ./home.nix
      nixvim.homeManagerModules.nixvim
    ];
  };
};

here something about it:
https://nix-community.github.io/nixvim/

I would suggest to use nixvim.nix module in your home.nix like this:

imports = [
  .nixvim.nix
];

Thanks for the reply! Since I declared nixvim as part of inputs I need to add it with

inputs.nixvim.homeManagerModules.nixvim

in the modules list of homeConfigurations output. However, in home.nix i get

error: undefined variable 'nixvim'

(after removing the dot in front because of syntax error). If I change the import value in home.nixto something like inputs.nixvim I instead get the error

error: Could not load a value as a module, because it is of type "flake"

I guess I’m not sure how I should properly declare the <nixvim_import> value as described in the guide you linked.

I was under the impression that the nixvim flake would be passed to home manager with inputs in extraSpecialArgs, but if so I don’t know how to access it in home.nix file.

Have you tried to use it like in my config without inputs. ?

Yes that generated an undefined variable error. If I add it to modules with

inputs.nixvim.homeManagerModules.nixvim

and also use the same value for importing in home.nix, I instead get a collison error

error: collision between `/nix/store/...neovim-0.9.5/bin/nvim' and `/nix/store/...neovim-0.9.5/bin/nvim'

which are two different items in /nix/store, not sure how to interpret that error.

  outputs = { self, nixpkgs, nixvim, ... }@inputs:

Add nixvim to outputs. This should fix undefined variable error.

So adding it to outputs like you suggested, adding it to modules list with

nixvim.homeManagerModules.nixvim

and importing with

nixvim.nix

generates undefined variable 'nixvim, and so does adding it to modules list with

inputs.nixvim.homeManagerModules.nixvim

which leads me to think that the import is still not correct somehow. It might be worth noting that I don’t intend to create a nixvim.nix file but rather pass nixvim to homemanager directly with extraSpecialArgs, if that’s something reasonable to do.

Yes that generated an undefined variable error. If I add it to modules with

inputs.nixvim.homeManagerModules.nixvim

and also use the same value for importing in home.nix, I instead get a collison error

I do have only 1 line in flake.nix, so maybe this is causing some collision? I’m just a newbie that had similar problem as you not a long ago ; ) . Maybe post those 2 configs and it would be more clear where are u now.

I can use configuration like this:

programs.nixvim = {
    enable = true;
    # more options...
};

but it will clutter home.nix so I suggested using it as module

I see, nice know to you figured it out, I’m also very new to this so framing questions correctly is a bit of a challenge. A don’t mind cluttering home.nix so if it works to configure nixvim there I’d like to do that. These are my home.nix and flake.nix at the moment, generating the collision error:

home.nix

{ config, pkgs, inputs, ... }:

  imports = [
    inputs.nixvim.homeManagerModules.nixvim
  ];

  programs.nixvim = {
    enable = true;
  };

  # more configurations

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;

flake.nix

{
  description = "Nixos config flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    hyprland.url = "github:hyprwm/Hyprland";
    hyprland-plugins = {
      url = "github:hyprwm/hyprland-plugins";
      inputs.hyprland.follows = "hyprland";
    };

    nixvim = {
      url = "github:nix-community/nixvim";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, ... }@inputs:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
      };
    in
    {
      nixosConfigurations.default = nixpkgs.lib.nixosSystem {
          specialArgs = {inherit inputs;};
          modules = [ 
            ./configuration.nix
            inputs.home-manager.nixosModules.default
          ];
        };
	
      homeConfigurations.default =
        inputs.home-manager.lib.homeManagerConfiguration {
	 inherit pkgs;
	 modules = [
	   ./home.nix
	   inputs.nixvim.homeManagerModules.nixvim
	 ];
	 extraSpecialArgs = { inherit inputs; };
	};
    };
}
  imports = [
    inputs.nixvim.homeManagerModules.nixvim
];

I don’t have it in home.nix at all. So it looks like here is that collision.

Ok that’s reasonable. My first idea from watching some tutorials was to simply add nixvim to my flake inputs and doing nothing else to flake.nix, and then nixvim would be available automatically in home.nix by passing extraSpecialArgs with inputs in it. This hower leads to

error: The option `home-manager.users.default.programs.nixvim' does not exist.

when trying to run

programs.nixvim = {
    enable = true;
  };

in home.nix.

The last thing that I could suggest is to try again that line without inputs. on the beginning. Over than that it’s beyond my newbie skill.

One difference I noticed is that you use

home-manager.lib.homeManagerConfiguration {

in your flake.nix while I use

inputs.home-manager.lib.homeManagerConfiguration {

Maybe that has something to do with it.

Yes I don’t have inputs there just like in this line:

    modules = [
      ./home.nix
      nixvim.homeManagerModules.nixvim
    ];

Just try it without those inputs. :smiley:

Would you mind sharing your config? Maybe I can deduce the problem from there.

Yes, but I moved nixvim.homeManagerModules.nixvim to home.nix yesterday.

{
  description = "Configurations";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nixvim = {
      url = "github:nix-community/nixvim";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { nixpkgs, home-manager, nixvim, ... }:
    let
      system   = "x86_64-linux";
      pkgs     = nixpkgs.legacyPackages.${system};
      username = "mee";
      hostname = "nixos";
    in
    {
      nixosConfigurations = {
        nixos = nixpkgs.lib.nixosSystem {
          specialArgs = { 
            inherit username; inherit hostname;
          };
          modules = [
            ./configuration.nix
            ./hardware-configuration.nix
            ./modules/system/bash.nix
            ./modules/system/fish.nix
            ./modules/system/thunar.nix
          ];
        };
      };
      homeConfigurations = {
        mee = home-manager.lib.homeManagerConfiguration {
          inherit pkgs;
          extraSpecialArgs = {
            inherit username; inherit hostname; inherit nixvim;
          };
          modules = [
            ./home.nix
          ];
        };
      };
    };
}

and home.nix

{ config, pkgs, username, nixvim, ... }:

{
  home.username = "${username}";
  home.homeDirectory = "/home/${username}";
  home.stateVersion = "23.11";
  news.display = "silent";
  
  imports = [
    ./modules/home/nixvim.nix
    ./modules/home/nnn.nix
    nixvim.homeManagerModules.nixvim
  ];

In home.nix you don’t need to import nixvim.nix like me, and instead use what u wanted:

programs.nixvim = {
    enable = true;
    # more options...
};

For anyone else who is stuck on this, you’re probably looking for home-manager.sharedModules, at least that’s what I ended up going for. Personally I’d like to just include it in my own user.nix but there seems to be a problem with installing in standalone mode for now:

{
  description = "NixOS configuration";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";

    home-manager = { 
      url = "github:nix-community/home-manager/release-23.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    nixvim = {
      url = "github:nix-community/nixvim/nixos-23.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs@{ nixpkgs, nixvim, home-manager, ... }: {
    nixosConfigurations = {
      nixos = nixpkgs.lib.nixosSystem {
        system = "aarch64-linux";
        modules = [
          ./configuration.nix
          ./machines/vm/aarch64.nix
          ./graphical.nix

          home-manager.nixosModules.home-manager
          {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true
            home-manager.sharedModules = [
              nixvim.homeManagerModules.nixvim
            ];
            home-manager.users.user = ./user.nix;
          }
        ];
      };
    };
  };
}

3 Likes

Thanks for the code snippet! I’m glad I’ve stumbled upon it, since nixvim readme doesn’t quite mention anything about home-manager.sharedModules. Following your example, it worked for me!

At a risk of driving the original discussion sideways, a separate question: in this setup, how would use neovim from unstable branch of nixpkgs? :thinking:

I use NixOS stable 24.05, but want to grab neovim recent 0.10 that won’t be backported. What I tried is adding unstable-nixpkgs to my flake, made nixvim flake follow unstable-nixpkgs and… obviously, that alone did nothing, neovim stays at 0.9.5. I need to tell programs.nixvim to use neovim from unstable, but I am not quite sure how to express this