How to see default values?

I was wondering the default value of a setting (nix.optimise.automatic, to be specific, but the specific doesn’t matter here)

Apart from asking nix contributors about it, I do not know how to easily check the default value by myself

I don’t want to read source code to find every single default value either

Also, it should be able to track default value change made by importing modules using lib.mkDefault, of course

Is there a way to easily find default values of settings?
Perhaps using nixd I guess?

1 Like
~ took 1m1s 
❯ nixos-rebuild repl
building Nix...
Nix 2.28.3
Type :? for help.
Loading installable ''...
Added 6 variables.
nix-repl> :p options.nix.optimise.automatic.default
false

nix-repl> :p options.nix.optimise.automatic.value  
false

nix-repl> :p options.nix.optimise.automatic.declarationPositions
[
  {
    column = 7;
    file = "/nix/store/c3337ikprkhsyajgr9wwi19rx89j64iq-source/nixos/modules/services/misc/nix-optimise.nix";
    line = 10;
  }
]

nix-repl>

I find the repl super helpful, I use it all the time for this!

5 Likes

Also option search.

3 Likes

Most of the time, you can check the option search or man 5 configuration.nix.

https://search.nixos.org/options

2 Likes

option search is indeed user-friendly and interesting!

But it would not track non-std (user-made module) options

Nor if a default value has been changed using lib.mkDefault

Will nix repl do that?

Otherwise, what’s the alternative?

~ took 2s 
❯ nix repl --file '<home-manager/modules>' \
        --arg configuration /home/ben/.config/home-manager/home.nix \
        --arg pkgs 'import <nixpkgs> {}'

Nix 2.28.3
Type :? for help.
Loading installable ''...
Added 8 variables.
nix-repl> :p options.homeManagerSource.value
/home/ben/.local/share/home-manager/source

nix-repl> :p options.homeManagerSource.description
The location of the home manager tree.

Yes it will. This is home manager, but it’s doing the same thing. You will find that this variable is from my config, not from home-manager (I don’t have any custom modules in my base system otherwise I would have just used nixos-rebuild repl).

1 Like

Thanks a lot!

It would be super useful to integrate it in Nix LSPs, such as nixd

I think default values don’t really fit into the standard lsp symbol definitions types. I mean nixd will sub in the default value on autocomplete I believe under most circumstances. Most of the time you can just go to definition and immediately see the option. You just need to make sure you’ve taught nixd how to load your option sets.

EDIT: the docs are a little lacking for nixos, if you don’t use flakes. See my comments here on how to make it work for custom modules with non-flake nix.

1 Like

That’s fair.

This is a little unfair, though, because lib.mkDefault, despite its name, doesn’t ‘change’ a default value. It acts like any other definition, just with a larger override priority value (meaning, lower priority).

Edit: Welp, I just learned that default option values are actually implemented just like mkDefault, but with an even larger value (1500 vs 1000)! So never mind. It’s all definitions.

1 Like

Submitted a feature request :

There is also nixos-option which comes enabled by default

$ nixos-option nix.optimise.automatic
Value:
  false

Default:
  false

Type:
  boolean

Description:
  Automatically run the nix store optimiser at a specific time.

Declared by:
  /nix/store/dydg48djlykksz8cxq0xjplyxpa9pvf4-source/nixos/modules/services/misc/nix-optimise.nix

Defined by:
  /nix/store/dydg48djlykksz8cxq0xjplyxpa9pvf4-source/nixos/modules/services/misc/nix-optimise.nix
4 Likes

Nice!

Would it do this?

Is there a way to provide a path to this command so it adapts to changed default value in its scope?

What exactly is a changed default value though? Is the important difference that a module sets it and not ‘your’ code, or is any definition anywhere with override priority 1000 or larger a ‘changed default’?

Does seem to work, for eg. a custom option I defined in my system flake.

$ nixos-option -F . docker-opts.nameservers
Value:
  [
    "1.1.1.1"
    "100.100.100.100"
    "8.8.8.8"
  ]

Type:
  list of string

Declared by:
  /nix/store/pnsaxxphjhqbxjacrcfqls3pfwyrg1ym-source/nixos/modules/virtualisation/docker.nix

Defined by:
  /nix/store/pnsaxxphjhqbxjacrcfqls3pfwyrg1ym-source/hosts/iron/configuration.nix

I don’t know about your second question about mkDefault

Doesn’t look like it’s been mentioned before, but you can get the full options list including custom modules (not sure if I grabbed all the needed parameters, but the important ones are there):

{ config, ... }:
{
  config = {
    # enable docs in general
    documentation.nixos.enable = true;
    # enable *all* the modules
    documentation.nixos.includeAllModules = true;


    # put this anywhere you can reasonably find it, be it hosted by a webserver, a CI pipeline output, or just this quick&dirty etc symlink (which allows you to open "/etc/nixos-docs/options.html" in your browser)
    environment.etc.nixos-docs.source = "${config.system.build.manual.manualHTML}/share/doc/nixos/";
  };
}

Edit: big thanks to @bme, I did not know nixos-rebuild had a repl target. I always went out of by way to get to those options, that makes it a lot easier, thanks!

2 Likes

I am mentioning it to make sure the solution I am seeking tracks imported modules with new options or lib.mkDefault overrides;

Basically that the lsp will return the proper default value evaluated by nix before a reassignement

1 Like

I think we’re miscommunicating.

Say a module you import has a definition foo.bar.baz = 5. You didn’t write that definition; the module did. Should the tool you’re looking for identify that as a ‘changed default’? Or should it be ignored?

Now say that you have, somewhere in your configuration, defined alpha.bravo.charlie = lib.mkDefault "stuff". That definition is part of your own configuration code. Should the tool you’re looking for identify that as a ‘changed default’?

What if instead you had alpha.bravo.charlie = lib.mkOverride 200 "stuff"? It is higher priority than something written with lib.mkDefault, but lower than the default priority of a definition. Does that count as a ‘changed default’?

The person implementing such a tool would need answers to these questions, because mkDefault isn’t singular and special like the actual default value of an option is—it’s just another way to make a definition. What are the answers you expect?