mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-11-11 02:07:27 +01:00
What it does: line and column level *declaration* position information:
$ nix repl .
nix-repl> :p nixosConfigurations.micro.options.environment.systemPackages.declarationPositions
[ { column = 7; file = "/nix/store/24aj3k7fgqv3ly7qkbf98qvphasrw9nb-source/nixos/modules/config/system-path.nix"; line = 63; } ]
Use cases:
- ctags over NixOS options, as will be presented at NixCon 2023 ;)
- improving the documentation pages to go to the exact line of the
declarations.
Related work:
- https://github.com/NixOS/nixpkgs/pull/65024
This one does it for all *definitions* rather than declarations, and
it was not followed through with due to performance worries.
- https://github.com/NixOS/nixpkgs/pull/208173
The basis for this change. This change is just a rebase of that one.
I split it out to add the capability before adding users of it, in
order to simplify review. However, the ctags script in there is a
sample user of this feature.
Benchmarks: conducted by evaluating my own reasonably complex NixOS
configuration with the command:
`hyperfine -S none -w 1 -- "nix eval .#nixosConfigurations.snowflake.config.system.build.toplevel.outPath"`
```
Benchmark 1: nix eval .#nixosConfigurations.snowflake.config.system.build.toplevel.outPath
Time (mean ± σ): 8.971 s ± 0.254 s [User: 5.872 s, System: 1.388 s]
Range (min … max): 8.574 s … 9.327 s 10 runs
Benchmark 1: nix eval .#nixosConfigurations.snowflake.config.system.build.toplevel.outPath
Time (mean ± σ): 8.766 s ± 0.160 s [User: 5.873 s, System: 1.346 s]
Range (min … max): 8.496 s … 9.033 s 10 runs
```
Summary of results: it seems to be in the noise, this does not cause any
visible regression in times.
50 lines
1.5 KiB
Nix
50 lines
1.5 KiB
Nix
{ lib, options, ... }:
|
|
let discardPositions = lib.mapAttrs (k: v: v);
|
|
in
|
|
# unsafeGetAttrPos is unspecified best-effort behavior, so we only want to consider this test on an evaluator that satisfies some basic assumptions about this function.
|
|
assert builtins.unsafeGetAttrPos "a" { a = true; } != null;
|
|
assert builtins.unsafeGetAttrPos "a" (discardPositions { a = true; }) == null;
|
|
{
|
|
imports = [
|
|
{
|
|
options.imported.line10 = lib.mkOption {
|
|
type = lib.types.int;
|
|
};
|
|
|
|
# Simulates various patterns of generating modules such as
|
|
# programs.firefox.nativeMessagingHosts.ff2mpv. We don't expect to get
|
|
# line numbers for these, but we can fall back on knowing the file.
|
|
options.generated = discardPositions {
|
|
line18 = lib.mkOption {
|
|
type = lib.types.int;
|
|
};
|
|
};
|
|
|
|
options.submoduleLine34.extraOptLine23 = lib.mkOption {
|
|
default = 1;
|
|
type = lib.types.int;
|
|
};
|
|
}
|
|
];
|
|
|
|
options.nested.nestedLine30 = lib.mkOption {
|
|
type = lib.types.int;
|
|
};
|
|
|
|
options.submoduleLine34 = lib.mkOption {
|
|
default = { };
|
|
type = lib.types.submoduleWith {
|
|
modules = [
|
|
({ options, ... }: {
|
|
options.submodDeclLine39 = lib.mkOption { };
|
|
})
|
|
{ freeformType = with lib.types; lazyAttrsOf (uniq unspecified); }
|
|
];
|
|
};
|
|
};
|
|
|
|
config = {
|
|
submoduleLine34.submodDeclLine39 = (options.submoduleLine34.type.getSubOptions [ ]).submodDeclLine39.declarationPositions;
|
|
};
|
|
}
|