nix-community.nixvim/docs/lib/function-locations.nix
Matt Sturgeon dfaea5982e
docs/lib: init
Generate reference docs for functions that have RFC145 style
doc-comments.

1. function locations

  `docs/lib/function-locations.nix` scans nixvim's extended lib,
  extracting "position entries" via `unsafeGetAttrPos`.

  This is then converted into a nixdoc `locations.json` map of
  "function name" → "markdown location string".

2. mdbook menu

  `docs/lib/menu.nix` renders a mdbook menu representing all page
  entries.

3. markdown pages

  `docs/lib/default.nix` expects a set of "page entries", which come
  from `docs/lib/pages.nix` by default. It passes this data to
  `function-locations.nix` and `menu.nix`, and uses it internally to
  render markdown pages.

  Page entries can contain a `file` to render using `nixdoc`, and also a
  `markdown` attribute which will be included at the top of the docs.

  Additionally, a `title` can be included. This forms the heading
  `$name: $title`, where `name` is derived from the page's attr-path.

  See https://github.com/nix-community/nixdoc
2025-05-19 00:19:56 +01:00

85 lines
2.5 KiB
Nix

# Generates an attrset of "function name" → "markdown location",
# for use with nixdoc's `--locs` option.
#
# {
# "lib.nixvim.foo.bar" = "[lib/foo.nix:123](https://github.com/nix-community/nixvim/blob/«rev»/lib/foo.nix#L123) in `<nixvim>`";
# }
{
rootPath,
lib,
functionSet,
pathsToScan,
revision,
functionSetName ? "lib",
url ? "https://github.com/nix-community/nixvim/blob",
}:
let
rootPathString = toString rootPath;
urlPrefix = "${url}/${revision}";
sanitizeId = builtins.replaceStrings [ "'" ] [ "-prime" ];
# Like `isAttrs`, but returns `false` if `v` throws
tryIsAttrs = v: (builtins.tryEval (builtins.isAttrs v)).value;
# Collect position entries from an attrset
# `prefix` is used in the human-readable name,
# and for determining whether to recurse into attrs
collectPositionEntriesInSet =
prefix: set:
builtins.concatMap (
name:
[
{
name = lib.showAttrPath (
builtins.concatMap lib.toList [
functionSetName
prefix
name
]
);
location = builtins.unsafeGetAttrPos name set;
}
]
++ lib.optionals (prefix == [ ] && tryIsAttrs set.${name}) (
collectPositionEntriesInSet (prefix ++ [ name ]) set.${name}
)
) (builtins.attrNames set);
# Collect position entries from each `pathsToScan` in `set`
collectPositionEntriesFromPaths =
set:
builtins.concatMap (loc: collectPositionEntriesInSet loc (lib.getAttrFromPath loc set)) pathsToScan;
# Remove the tree root (usually the top-level store path)
removeNixvimPrefix = lib.flip lib.pipe [
(lib.strings.removePrefix rootPathString)
(lib.strings.removePrefix "/")
];
# Create a name-value-pair for use with `listToAttrs`
entryToNameValuePair =
{ name, location }:
{
name = sanitizeId name;
value =
let
file = removeNixvimPrefix location.file;
line = builtins.toString location.line;
text = "${file}:${line}";
target = "${urlPrefix}/${file}#L${line}";
in
"[${text}](${target}) in `<nixvim>`";
};
in
lib.pipe functionSet [
# Get the entries
collectPositionEntriesFromPaths
# Only include entries that have a location
(builtins.filter (entry: entry.location != null))
# No need to include out-of-tree entries
(builtins.filter (entry: lib.strings.hasPrefix rootPathString entry.location.file))
# Convert entries to attrset
(builtins.map entryToNameValuePair)
builtins.listToAttrs
]