bemenu is currently only available in home-manager unstable. So, I can not do the following: programs.bemenu.enable = true; (Note: the solution described here will not work, as it will throw a …programs.bemenu does not exist error). But, maybe there is a way to do something like unstable-programs.bemenu.enable = true;?
But, with my limited Nix understanding, I have not managed to create a similar overlay for home-manager programs, as for nixpkgs. Is it possible to reach unstable home-manager programs in a stable version (like unstable-programs.bemenu.enable = true;)? If yes, does anyone know how to achieve this?
I might to be wrong, but I don’t think it’s possible. In fact, I’d be happy to be wrong here as I don’t like the solution I have used for this.
The reason I think this way is that programs.foo is a concept of the module system, not packages – so overlays are not applicable for the configuration side. Of course you can pass derivation from an overlay to programs.foo.package, but the option programs.foo.package needs to exist in the modules.
It’s just not possible to set up “these modules’ options will now be called programs-foo and services-foo and whatnot” in Nix module system. Maybe it’s possible with some gnarly lib.evalModules trickery but that feels more brittle than the solution below.
One approach for your use-case is to try to import the module by hand. You could try importing the programs.bemenu module by specifying the path inside home-manager-unstable input. However, this would not bring the closure of the module in. I.e. if programs.bemenu would rely on some base home-manager machinery that is not present in stable – an error would be thrown.
It is possible with the NixOS module system: NixOS Manual
I don’t remember off the top of my head if the home-manager module system permits the same thing. May need to check the source code if the attribute is named differently or something if it doesn’t just work
that’s not the same thing though, is it? Replacing modules is a combination of disabling a module through .disabledModules and then importing its replacement. This is not a mechanism to mass-rename options coming from an import – which is what I was referring to as not being possible, at least trivially.
In this case, bemenu module does not exist in stable home-manager, so there is nothing to disable and the code in my post provides an example of importing a module by path from a flakeref.
For simple “leaf” modules like bemenu it works. However, say, foo.nix module depends on options’ values from bar.nix and both foo.nix and bar.nix are only present in unstable – then the consumer would need to manually import the “closure” of necessary options. Or, maybe, try lib.evalModules and extracting its results.
I think the poetic waxing made my first post confusing. Sorry about that
Specifically for your use-case – importing bemenu module from unstable – it seems perfectly possible. You’d need to have an extra input pointing to just home-manager (you have that already) and you would need to import the module by path like so:
home-manager.users.alice =
_: # { config, ... }: # config is home-manager's config, not the OS one
{
imports = [ (inputs.home-manager-unstable + "/modules/programs/bemenu.nix") ];
home.stateVersion = "23.11";
programs.bemenu.enable = true;
};
The code sample in that post was of a flake that showcases this import and one could run as nix run -L .#checks.x86_64-linux.test.driverInteractive.
As usual – real code would depend on where you’re doing the import and how home-manager-unstable is passed to the import site.
Ah, yep, but if you’re ok with programs.bemenu simply referring to the unstable version instead of the stable version that’s all there is to it. You shouldn’t need the original anyway.
No worries, @VTimofeenko. It is due to my lack of understanding of Nix that it was confusing to me. I appreciate the clarification, and feeding me the simple solution to my problem.
Side note:
When I implemented the solution, I ended up with:
… while evaluating the module argument `inputs` in ":anon-5:anon-1":
error: infinite recursion encountered
I realised I had forgotten this line: home-manager.extraSpecialArgs = {inherit inputs;};
Rebuilding with that in place, it worked like a charm. No idea why, but I am sure there is a logical explanation to that as well.
It’s hard to say for certain but it’s most likely related to the way home-manager is imported. Check this thread for a similar error in similar context