Configuration

pedantix is configured with a TOML file (see config discovery).

Individual values can also be passed on the command line with --set, e.g. pedantix --set lets.sort=true file.nix, or the whole document inline with --config-toml.

preset

This applies a base layer of configuration which you can layer your own config atop of - see Presets.

preset = "nixos-module"

Reference

Top-level keys

KeyTypeDefaultDescription
format-after-sortbooltrueRun the base formatter again after sorting.
format-before-sortbooltrueRun the base formatter before sorting.
formatterFormatterChoice"nixfmt"Base formatter run before and after sorting.
formatter-commandlist of stringArbitrary stdin -> stdout command; overrides formatter. Because it runs an external program, it is only honored from configs named explicitly (--config, --config-toml, --set, the global XDG config); an auto-discovered config requires --allow-formatter-command.
inherit-placementInheritPlacement"front"Where inherit statements land relative to ordinary bindings.
top-level-blank-linesintExact number of blank lines between the bindings of the file's outermost attribute set. Unset keeps existing blank lines as-is.
top-level-blank-lines-depthint1How deep the top-level spacing reaches: 1 is only the outermost set, 2 also covers the sets its bindings define, and so on. In flake.nix, inputs and outputs always count as top-level sets.
top-level-blank-lines-modeBlankLinesMode"multiline"Which top-level bindings receive the blank-line spacing.

Construct rules ([args], [attrs], [lets], [inherits], [lists])

The merge, flatten, and blank-lines* keys only apply to [attrs].

KeyTypeDefaultDescription
blank-linesint(attrs only) Number of blank lines between the set's bindings. Unset keeps the existing spacing.
blank-lines-depthint1(attrs only) How deep the spacing reaches; wrappers such as functions and lets do not count as levels.
blank-lines-modeBlankLinesMode(attrs only) Which bindings receive the blank-line spacing.
firstlist of string[]Names pinned to the front, in the given order. The sentinel "<defaulted>" stands for all arguments with a default value (name ? value); "..." is the ellipsis.
flattenboolfalse(attrs only) Flatten a binding whose value is an attrset holding a single binding into one attrpath: a = { b = 1; }; becomes a.b = 1;. Overrides match the path of the set being flattened.
lastlist of string[]Names pinned to the end, in the given order.
mergeboolfalse(attrs only) Merge bindings sharing their first attrpath component into one nested set: a.b = 1; a.c = 2; becomes a = { b = 1; c = 2; };.
sortbooltrueWhether to reorder this construct at all.

Override keys ([[overrides]])

KeyTypeDefaultDescription
argspartial rulesFunction-argument rules to apply to matched paths.
attrspartial rulesAttribute-set rules to apply to matched paths.
inheritspartial rulesinherit rules to apply to matched paths.
letspartial ruleslet-binding rules to apply to matched paths.
listspartial rulesList-element rules to apply to matched paths.
pathstringGlob over dot-separated attribute paths. * matches exactly one component, ** any number (including zero).

FormatterChoice values

ValueDescription
"nixfmt"
"alejandra"
"nixpkgs-fmt"
"off"Disable the base formatter; only reorder.

BlankLinesMode values

ValueDescription
"multiline"Space bindings whose text spans several lines; keep consecutive single-line bindings together.
"all"Apply spacing to all bindings.
"off"Suppress spacing entirely.

InheritPlacement values

ValueDescription
"front"Pin `inherit lines to the top of the set.
"last"Pin `inherit lines to the bottom of the set.
"sorted"Sort `inherit lines alphabetically among the bindings.

Notes

The five construct tables share one shape

[args], [attrs], [lets], [inherits], and [lists] all take the same sort rules keys. Names not listed in first / last are sorted alphabetically between them. The merge, flatten, and blank-lines* keys are only meaningful under [attrs].

[args]
first = ["self", "lib", "config", "pkgs"]
last  = ["<defaulted>", "..."]

[attrs]
first = ["imports", "enable", "package"]

[lets]
sort = true

[lets], [inherits], and [lists] are off by default. List sorting in particular is best enabled per-path via an override rather than globally, since list order is often significant.

merge shared attribute paths

[attrs]
merge = true

turns a.b = 1; a.c = 2; into a = { b = 1; c = 2; };. This does not fix broken evaluation by e.g. dynamically derived attribute set names.

flatten single-binding attribute sets

[attrs]
flatten = true

turns a = { b = 1; }; into a.b = 1;, provided b is the only binding in the set. This skips on rec, inherit, dynamic keys, and comments around binding.

Top-level blank lines vs. [attrs] blank-lines

The top-level-blank-lines* keys and the [attrs] blank-lines* keys look similar but do slightly different things:

top-level-blank-lines does not descend into function-call sets, and treats a flake.nix inputs/outputs body as its own top-level set.

[attrs] blank-lines applies to every attrset the [attrs] rules match, at any nesting depth (including sets inside function calls), and can be targeted per path via [[overrides]].

A reordered set by default drops all blank lines, so set one of these to restore spacing.

[inherits] vs. inherit-placement

[inherits] sorts the names inside an inherit. The top-level inherit-placement key is separate: it controls where the whole inherit statement sits relative to other bindings.

Per-path overrides

The [[overrides]] array lets you change any of the rules above for specific attribute paths — see Overrides.