diff --git a/.gitignore b/.gitignore
index 53442751f..ffaf52be8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,8 @@ perl/Makefile.config
/doc/manual/src/SUMMARY.md
/doc/manual/src/command-ref/new-cli
/doc/manual/src/command-ref/conf-file.md
-/doc/manual/src/command-ref/experimental-features.md
+/doc/manual/src/command-ref/experimental-features-shortlist.md
+/doc/manual/src/contributing/experimental-features
/doc/manual/src/language/builtins.md
# /scripts/
diff --git a/doc/manual/generate-xp-features-shortlist.nix b/doc/manual/generate-xp-features-shortlist.nix
new file mode 100644
index 000000000..b2095bc27
--- /dev/null
+++ b/doc/manual/generate-xp-features-shortlist.nix
@@ -0,0 +1,9 @@
+with builtins;
+with import ./utils.nix;
+
+let
+ showExperimentalFeature = name: doc:
+ ''
+ - [`${name}`](@docroot@/contributing/experimental-features/${name}.md)
+ '';
+in xps: indent " " (concatStrings (attrValues (mapAttrs showExperimentalFeature xps)))
diff --git a/doc/manual/generate-xp-features.nix b/doc/manual/generate-xp-features.nix
index db1ba6092..ff64edcf7 100644
--- a/doc/manual/generate-xp-features.nix
+++ b/doc/manual/generate-xp-features.nix
@@ -1,11 +1,21 @@
+xps:
+
with builtins;
with import ./utils.nix;
let
- showExperimentalFeature = name: doc:
- squash ''
- - [`${name}`](#xp-feature-${name})
+ makePage = { name, value }:
+ {
+ name = "${name}.md";
+ inherit value;
+ feature = name;
+ };
- ${indent " " doc}
- '';
-in xps: indent " " (concatStringsSep "\n" (attrValues (mapAttrs showExperimentalFeature xps)))
+ featurePages = map makePage (attrsToList xps);
+
+ tableOfContents = let
+ showEntry = page:
+ " - [${page.feature}](contributing/experimental-features/${page.name})";
+ in concatStringsSep "\n" (map showEntry featurePages) + "\n";
+
+in (listToAttrs featurePages) // { "SUMMARY.md" = tableOfContents; }
diff --git a/doc/manual/local.mk b/doc/manual/local.mk
index 0d4b9d640..ae55ae4a9 100644
--- a/doc/manual/local.mk
+++ b/doc/manual/local.mk
@@ -81,10 +81,11 @@ $(d)/%.8: $(d)/src/command-ref/%.md
$(d)/nix.conf.5: $(d)/src/command-ref/conf-file.md
@printf "Title: %s\n\n" "$$(basename $@ .5)" > $^.tmp
@cat $^ >> $^.tmp
+ @$(call process-includes,$^,$^.tmp)
$(trace-gen) lowdown -sT man --nroff-nolinks -M section=5 $^.tmp -o $@
@rm $^.tmp
-$(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/command-ref/new-cli
+$(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/command-ref/new-cli $(d)/src/contributing/experimental-features
@cp $< $@
@$(call process-includes,$@,$@)
@@ -93,7 +94,7 @@ $(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/utils.nix $(d)/generate-manpage
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix (builtins.readFile $<)'
@mv $@.tmp $@
-$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/utils.nix $(d)/src/command-ref/conf-file-prefix.md $(d)/src/command-ref/experimental-features.md $(bindir)/nix
+$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/utils.nix $(d)/src/command-ref/conf-file-prefix.md $(d)/src/command-ref/experimental-features-shortlist.md $(bindir)/nix
@cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp
$(trace-gen) $(nix-eval) --expr '(import doc/manual/utils.nix).showSettings { useAnchors = true; } (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp;
@mv $@.tmp $@
@@ -106,11 +107,16 @@ $(d)/conf-file.json: $(bindir)/nix
$(trace-gen) $(dummy-env) $(bindir)/nix show-config --json --experimental-features nix-command > $@.tmp
@mv $@.tmp $@
-$(d)/src/command-ref/experimental-features.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features.nix $(bindir)/nix
+$(d)/src/contributing/experimental-features: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features.nix $(bindir)/nix
@rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features.nix (builtins.fromJSON (builtins.readFile $<))'
@mv $@.tmp $@
+$(d)/src/command-ref/experimental-features-shortlist.md: $(d)/xp-features.json $(d)/utils.nix $(d)/generate-xp-features-shortlist.nix $(bindir)/nix
+ @rm -rf $@ $@.tmp
+ $(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features-shortlist.nix (builtins.fromJSON (builtins.readFile $<))'
+ @mv $@.tmp $@
+
$(d)/xp-features.json: $(bindir)/nix
$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(bindir)/nix __dump-xp-features > $@.tmp
@mv $@.tmp $@
@@ -154,7 +160,7 @@ doc/manual/generated/man1/nix3-manpages: $(d)/src/command-ref/new-cli
done
@touch $@
-$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/command-ref/new-cli $(d)/src/command-ref/conf-file.md $(d)/src/language/builtins.md
+$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/command-ref/new-cli $(d)/src/contributing/experimental-features $(d)/src/command-ref/conf-file.md $(d)/src/language/builtins.md
$(trace-gen) \
tmp="$$(mktemp -d)"; \
cp -r doc/manual "$$tmp"; \
diff --git a/doc/manual/src/SUMMARY.md.in b/doc/manual/src/SUMMARY.md.in
index 5bf274550..298644044 100644
--- a/doc/manual/src/SUMMARY.md.in
+++ b/doc/manual/src/SUMMARY.md.in
@@ -96,6 +96,7 @@
- [Contributing](contributing/contributing.md)
- [Hacking](contributing/hacking.md)
- [Experimental Features](contributing/experimental-features.md)
+{{#include ./contributing/experimental-features/SUMMARY.md}}
- [CLI guideline](contributing/cli-guideline.md)
- [Release Notes](release-notes/release-notes.md)
- [Release X.Y (202?-??-??)](release-notes/rl-next.md)
diff --git a/doc/manual/utils.nix b/doc/manual/utils.nix
index f78e6bb02..82544935a 100644
--- a/doc/manual/utils.nix
+++ b/doc/manual/utils.nix
@@ -5,6 +5,9 @@ rec {
concatStrings = concatStringsSep "";
+ attrsToList = a:
+ map (name: { inherit name; value = a.${name}; }) (builtins.attrNames a);
+
replaceStringsRec = from: to: string:
# recursively replace occurrences of `from` with `to` within `string`
# example:
diff --git a/src/libutil/config.hh b/src/libutil/config.hh
index b21f8a422..6baba0167 100644
--- a/src/libutil/config.hh
+++ b/src/libutil/config.hh
@@ -384,7 +384,7 @@ struct ExperimentalFeatureSettings : Config {
Experimental features available:
- {{#include experimental-features.md}}
+ {{#include experimental-features-shortlist.md}}
Experimental features are [further documented](@docroot@/contributing/experimental-features.md) in the contribution guide.
)"};
diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc
index aa3367639..1cd0dbb79 100644
--- a/src/libutil/experimental-features.cc
+++ b/src/libutil/experimental-features.cc
@@ -57,7 +57,7 @@ constexpr std::array xpFeatureDetails = {{
.name = "flakes",
.description = R"(
Enable flakes. See the manual entry for [`nix
- flake`](../command-ref/new-cli/nix3-flake.md) for details.
+ flake`](@docroot@/command-ref/new-cli/nix3-flake.md) for details.
)",
},
{