Say, I got my configuration.nix, which is the entry point to the NixOS world, I’ve done a bunch of OS configs and the concept is wonderful and it is working out smoothly. However, to get which options I can set for a certain package, I’d now google up the module declaration on GitHub and read the docs there or guess the types. That’s very indirect and sometimes I get the wrong declaration, however that’s a go.
But now I’m trying to declare a new package for my needs, and place it alongside the configuration.nix and have it tangled in when building my configuration (rather than fork the full package repo and place it there), and things are going very slowly because for each symbol referenced in a normal configuration.nix I do not know a good way to (a) learn its exact type (in terms of typed languages, here that would be the common set of properties probably) and (b) which source file it were declared in, and what exactly the declaration does. Here I mean learning exactly, not guessing by randomly grepping around. I’m much used to good IDEs here, which let you quickly learn stuff incrementally by looking into how others’ things are done and crafting alike. And you get small but useful results on each step, which has a good feeling. Here I feel blindfolded somewhat.
So what are the good ways to explore what I got in expressions?
So you want an intellisense for NixOS configuration? I want that as well!
I hope smbdy writes it, so it will eventually be available to all the munde. Meanwhile, we use nix repl and autocomplete:
$ nix repl '<nixpkgs>' '<nixpkgs/nixos>'
You can now poke around various options:
# in which files is this particular option set
nix-repl> :p options.environment.shellAliases.files
[ "/home/danbst/power-profile/profiles/base.nix" "/nix/var/nix/profiles/per-user/root/channels/nixpkgs/nixos/modules/config/shells-environment.nix" ]
# what values are defined in respective files
nix-repl> :p options.environment.shellAliases.definitions
[ { nix-env = /home/danbst/power-profile/experimental/declarative-env.sh; t = "/home/danbst/dev/todo.txt-cli/todo.sh"; } { l = { _type = "override"; content = "ls -alh"; priority = 1000; }; ll = { _type = "override"; content = "ls -l"; priority = 1000; }; ls = { _type = "override"; content = "ls --color=tty"; priority = 1000; }; } ]
# in which files is this option created (declared)
nix-repl> :p options.environment.shellAliases.declarations
[ "/nix/var/nix/profiles/per-user/root/channels/nixpkgs/nixos/modules/config/shells-environment.nix" ]
# what is the final value of this option (including all the defaults and overrides)
nix-repl> config.environment.shellAliases
{ l = "ls -alh"; ll = "ls -l"; ls = "ls --color=tty"; nix-env = /home/danbst/power-profile/experimental/declarative-env.sh; t = "/home/danbst/dev/todo.txt-cli/todo.sh"; }
# read option description in-place
nix-repl> options.environment.shellAliases.description
"An attribute set that maps aliases (the top level attribute names in\nthis option) to command strings or directly to build outputs. The\naliases are added to all users' shells.\nAliases mapped to <code>null</code> are ignored.\n"
nix-repl! How could I forget. That’s a really good point, thanks. Though not ideal for the very beginning because it does not explain your existing configuration files as they are. But as this is a dynamic language, that would have been a bit too much to expect probably.
Wellll not ultra useful but of a limited use actually. I’ve been able to put together a derivation I needed and mount it locally into configuration.nix without forking nixpkgs, but mostly by copypasting, guesswork, reading error messages of nixos-rebuild process (many of them surprisingly helpful) and googling answers to some other questions. Repl does show something, but first you have to guess how to fire it up for your current configuration, and then it didn’t help me with the error “is not of type package”, like, at all – systemPackages takes what it thinks to be a derivation expression and mine were as well, and I got nowhere close to seeing repl speak any types like package, I still do not quite know what this means, isn’t a nix expression type to my limited knowledge of nix. Fortunately, the error were classic and I could google it. So there’s still a gap between making up your first dozen working configurations and understanding how they actually run behind the curtains, and nix repl isn’t helping much.
It’s not exactly what you are asking for but there is a project for diffing Nix derivations, which can be used to see the differences between two realized configurations.
There are some projects that strive to implement the Language Server Protocol for Nix and thus can enable in the far future, intellisense completion builtin to your $EDITOR, here are implementations I’m aware of: