Can you remove the ellipses?

I was wondering if its possible to remove the ellipses in modules and explicitly define all the required arguments?
The idea is that it would be clearer where an option is coming from.

And maybe it would be possible to combine NixOS and home-manager options that way?
For example we could the rename the home-manager services to hm-services?
Like with Python
import foo as bar

Maybe what you want is

let hm-services = import home-manager; in

?
It’s not clear though, what are you trying to achieve. Can you elaborate?

1 Like

I have actually two ideas.
One is just to have cleaner .nix files which explicitly show the options they are using.
E.g. like this:

{ networking, virtualisation }:

{
  networking.hostName = "foo";
  virtualisation.virtualbox.host.enable = true;
}

The other idea is to have home-manager and NixOS options in the same file.
For example the droidcam package has an option from NixOS but the option doesn’t create a desktop file.
I would like to create the desktop file with home-manager and add it to the same .nix file as the NixOS option so that all the droidcam options are in the same file and I only need to add one import to enable droidcam without having two configs one for NixOS and one for droidcam.

pkgs.lib.callPackage will call a function, giving it all the named arguments from nixpkgs it asks for. There are variants of that function that allow you to specify additional/your own scope. Whenever you specify a derivation, using that is a very nice way to achieve this.

For modules this isn’t possible without serious hacking, so using the let inherit ... in pattern is probably the nicest way to achieve the import clarity you’re looking for, combined with the assignment @cab suggests when you need to rename.

I usually depend on the global lib, pkgs, config and such in modules, and then define which exact functions I’ll use before the module definition, like so: dotfiles/pipewire-rnnoise.nix at 645c5996d2f2f63bc139e7abbbefbb641c4c83b2 · TLATER/dotfiles · GitHub

Note that glob imports in Python are mostly discouraged because Python scoping is a mess. Nix isn’t affected by this, so it’s significantly less problematic here, although I agree it’s nice to explicitly state your imports just to make it easier to read. The conventions here probably come from the Haskell world, where glob imports are almost encouraged.

This is possible using the NixOS module. Note that this is a completely separate tree under config, so there’s no need for a renamed import or anything.

Modules are inherently scoped, and there’s no way to define “this file only operates on subtree x of the module tree”, however you can use let bindings on config, which is a common pattern: nixos-hosts/rnnoise-suppression.nix at 0eff339a19d07ef7fe1f81cd962aa08fcc2e255e · TLATER/nixos-hosts · GitHub (still using with lib there, tsk).

I haven’t seen this used to mix two separate trees before, though.

1 Like

I think you have the scope a little backwards. The purpose of the ... is not to bring into scope variables like networking or virtualisation. When you write networking.hostName = "foo";, you aren’t using a variable named networking. A NixOS module is a function that takes certain inputs, and returns an attrset (think dictionary) of configuration definitions. So networking.hostName = "foo"; is actually saying that the attrset returned by this function should contain a key “networking” whose value is another attrset with a key “hostName” whose value is “foo”.

The purpose of the ... is that the NixOS module system provides a bunch of typically unnecessary arguments to your module, so we use ... to say “the system can give me whatever it wants; I only care about the ones I’ve listed here, like pkgs.”

Note that the NixOS module system is a very different system than the callPackage system used within nixpkgs.

3 Likes

Ah so it’s a bit like *args, **kwargs from Python.
So if I understand it correctly the arguments only really matter when I used them again with a with for example?

The arguments matter when they contain something you need. pkgs contains packages, the lib argument contains various utility functions, etc. I recommend reading about the nix expression language.

Thanks I’ll check it out.
But I think understand it now already a bit better.
I’m reading (or read already) a lot of resources (nix pills, nix tour, NixOS manual, etc.) but I’m having some difficulties to understand what parts are relevant at which location or for which task.

Another reason to have the ... in module arguments is it allows us to add additional arguments in the future without rewriting every NixOS module in the world. Also, the module system allows you to have your own custom arguments, though that is a rarely used feature (I think).

With flakes it has become more common, as that’s the only way to thread the inputs through the modules.

2 Likes