mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-21 08:35:43 +02:00
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
This commit is contained in:
parent
563fdaeef9
commit
dfaea5982e
6 changed files with 299 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
helpers,
|
helpers,
|
||||||
system,
|
system,
|
||||||
|
nixvim,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
nuschtosSearch,
|
nuschtosSearch,
|
||||||
}:
|
}:
|
||||||
|
@ -108,6 +109,10 @@ lib.fix (
|
||||||
gfm-alerts-to-admonitions = pkgs.python3.pkgs.callPackage ./gfm-alerts-to-admonitions { };
|
gfm-alerts-to-admonitions = pkgs.python3.pkgs.callPackage ./gfm-alerts-to-admonitions { };
|
||||||
|
|
||||||
man-docs = pkgs.callPackage ./man { inherit options-json; };
|
man-docs = pkgs.callPackage ./man { inherit options-json; };
|
||||||
|
|
||||||
|
lib-docs = pkgs.callPackage ./lib {
|
||||||
|
inherit nixvim lib;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (!pkgs.stdenv.isDarwin) {
|
// lib.optionalAttrs (!pkgs.stdenv.isDarwin) {
|
||||||
# NuschtOS/search does not seem to work on darwin
|
# NuschtOS/search does not seem to work on darwin
|
||||||
|
|
168
docs/lib/default.nix
Normal file
168
docs/lib/default.nix
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
# Generates the documentation for library functions using nixdoc.
|
||||||
|
# See https://github.com/nix-community/nixdoc
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
runCommand,
|
||||||
|
writers,
|
||||||
|
nixdoc,
|
||||||
|
nixvim,
|
||||||
|
pageSpecs ? import ./pages.nix,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
# Some pages are just menu entries, others have an actual markdown page that
|
||||||
|
# needs rendering.
|
||||||
|
shouldRenderPage = page: page ? file || page ? markdown;
|
||||||
|
|
||||||
|
# Normalise a page node, recursively normalise its children
|
||||||
|
elaboratePage =
|
||||||
|
loc:
|
||||||
|
{
|
||||||
|
title ? "",
|
||||||
|
markdown ? null,
|
||||||
|
file ? null,
|
||||||
|
pages ? { },
|
||||||
|
}@page:
|
||||||
|
{
|
||||||
|
name = lib.attrsets.showAttrPath loc;
|
||||||
|
loc = lib.throwIfNot (
|
||||||
|
builtins.head loc == "lib"
|
||||||
|
) "All pages must be within `lib`, unexpected root `${builtins.head loc}`" (builtins.tail loc);
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (shouldRenderPage page) {
|
||||||
|
inherit
|
||||||
|
file
|
||||||
|
title
|
||||||
|
;
|
||||||
|
markdown =
|
||||||
|
if builtins.isString markdown then
|
||||||
|
builtins.toFile "${lib.strings.replaceStrings [ "/" "-" ] (lib.lists.last loc)}.md" markdown
|
||||||
|
else
|
||||||
|
markdown;
|
||||||
|
outFile = lib.strings.concatStringsSep "/" (loc ++ [ "index.md" ]);
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (page ? pages) {
|
||||||
|
pages = elaboratePages loc pages;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Recursively normalise page nodes
|
||||||
|
elaboratePages = prefix: builtins.mapAttrs (name: elaboratePage (prefix ++ [ name ]));
|
||||||
|
|
||||||
|
# Collect all page nodes into a list of page entries
|
||||||
|
collectPages =
|
||||||
|
pages:
|
||||||
|
builtins.concatMap (
|
||||||
|
page:
|
||||||
|
[ (builtins.removeAttrs page [ "pages" ]) ]
|
||||||
|
++ lib.optionals (page ? pages) (collectPages page.pages)
|
||||||
|
) (builtins.attrValues pages);
|
||||||
|
|
||||||
|
# Normalised page specs
|
||||||
|
elaboratedPageSpecs = elaboratePages [ ] pageSpecs;
|
||||||
|
pageList = collectPages elaboratedPageSpecs;
|
||||||
|
pagesToRender = builtins.filter (page: page ? outFile) pageList;
|
||||||
|
pagesWithFunctions = builtins.filter (page: page.file or null != null) pageList;
|
||||||
|
in
|
||||||
|
|
||||||
|
runCommand "nixvim-lib-docs"
|
||||||
|
{
|
||||||
|
nativeBuildInputs = [
|
||||||
|
nixdoc
|
||||||
|
];
|
||||||
|
|
||||||
|
locations = writers.writeJSON "locations.json" (
|
||||||
|
import ./function-locations.nix {
|
||||||
|
inherit lib;
|
||||||
|
rootPath = nixvim;
|
||||||
|
functionSet = lib.extend nixvim.lib.overlay;
|
||||||
|
pathsToScan = builtins.catAttrs "loc" pagesWithFunctions;
|
||||||
|
revision = nixvim.rev or "main";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
passthru.menu = import ./menu.nix {
|
||||||
|
inherit lib;
|
||||||
|
pageSpecs = elaboratedPageSpecs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
''
|
||||||
|
function docgen {
|
||||||
|
md_file="$1"
|
||||||
|
in_file="$2"
|
||||||
|
name="$3"
|
||||||
|
out_file="$out/$4"
|
||||||
|
title="$5"
|
||||||
|
|
||||||
|
if [[ -z "$in_file" ]]; then
|
||||||
|
if [[ -z "$md_file" ]]; then
|
||||||
|
>&2 echo "No markdown or nix file for $name"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [[ -f "$in_file/default.nix" ]]; then
|
||||||
|
in_file+="/default.nix"
|
||||||
|
elif [[ ! -f "$in_file" ]]; then
|
||||||
|
>&2 echo "File not found: $in_file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$in_file" ]]; then
|
||||||
|
nixdoc \
|
||||||
|
--file "$in_file" \
|
||||||
|
--locs "$locations" \
|
||||||
|
--category "$name" \
|
||||||
|
--description "REMOVED BY TAIL" \
|
||||||
|
--prefix "" \
|
||||||
|
--anchor-prefix "" \
|
||||||
|
| tail --lines +2 \
|
||||||
|
> functions.md
|
||||||
|
fi
|
||||||
|
|
||||||
|
default_heading="# $name"
|
||||||
|
if [[ -n "$title" ]]; then
|
||||||
|
default_heading+=": $title"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_heading=true
|
||||||
|
if [[ -f "$md_file" ]] && [[ "$(head --lines 1 "$md_file")" == '# '* ]]; then
|
||||||
|
>&2 echo "NOTE: markdown file for $name starts with a <h1> heading. Skipping default heading \"$default_heading\"."
|
||||||
|
>&2 echo " Found \"$(head --lines 1 "$md_file")\" in: $md_file"
|
||||||
|
print_heading=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $(dirname "$out_file")
|
||||||
|
(
|
||||||
|
if [[ "$print_heading" = true ]]; then
|
||||||
|
echo "$default_heading"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
if [[ -f "$md_file" ]]; then
|
||||||
|
cat "$md_file"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
if [[ -f functions.md ]]; then
|
||||||
|
cat functions.md
|
||||||
|
fi
|
||||||
|
) > "$out_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p "$out"
|
||||||
|
|
||||||
|
${lib.concatMapStringsSep "\n" (
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
file,
|
||||||
|
markdown,
|
||||||
|
outFile,
|
||||||
|
title ? "",
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
lib.escapeShellArgs [
|
||||||
|
"docgen"
|
||||||
|
"${lib.optionalString (markdown != null) markdown}" # md_file
|
||||||
|
"${lib.optionalString (file != null) file}" # in_file
|
||||||
|
name # name
|
||||||
|
outFile # out_file
|
||||||
|
title # title
|
||||||
|
]
|
||||||
|
) pagesToRender}
|
||||||
|
''
|
85
docs/lib/function-locations.nix
Normal file
85
docs/lib/function-locations.nix
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
# 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
|
||||||
|
]
|
31
docs/lib/menu.nix
Normal file
31
docs/lib/menu.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
pageSpecs,
|
||||||
|
indentSize ? " ",
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
pageToLines =
|
||||||
|
indent: parentName:
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
outFile ? "",
|
||||||
|
pages ? { },
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
menuName = lib.strings.removePrefix (parentName + ".") name;
|
||||||
|
children = builtins.attrValues pages;
|
||||||
|
# Only add node to the menu if it has content or multiple children
|
||||||
|
useNodeInMenu = outFile != "" || builtins.length children > 1;
|
||||||
|
parentOfChildren = if useNodeInMenu then name else parentName;
|
||||||
|
in
|
||||||
|
lib.optional useNodeInMenu "${indent}- [${menuName}](${outFile})"
|
||||||
|
++ lib.optionals (children != [ ]) (
|
||||||
|
builtins.concatMap (pageToLines (indent + indentSize) parentOfChildren) children
|
||||||
|
);
|
||||||
|
in
|
||||||
|
lib.pipe pageSpecs [
|
||||||
|
builtins.attrValues
|
||||||
|
(builtins.concatMap (pageToLines "" ""))
|
||||||
|
lib.concatLines
|
||||||
|
]
|
8
docs/lib/pages.nix
Normal file
8
docs/lib/pages.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# This file contains a list of function reference docs pages that should be generated by `nixdoc`
|
||||||
|
#
|
||||||
|
# Note: `nixdoc` uses `rnix` to parse the input file, so the file must return a fairly simple attrset.
|
||||||
|
# If there is an issue parsing the file, the resulting markdown will not contain any function docs.
|
||||||
|
|
||||||
|
{
|
||||||
|
# TODO
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
self,
|
||||||
inputs,
|
inputs,
|
||||||
helpers,
|
helpers,
|
||||||
...
|
...
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
packages = import ../docs {
|
packages = import ../docs {
|
||||||
|
nixvim = self;
|
||||||
inherit helpers;
|
inherit helpers;
|
||||||
inherit system;
|
inherit system;
|
||||||
inherit (inputs) nixpkgs;
|
inherit (inputs) nixpkgs;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue