diff --git a/docs/default.nix b/docs/default.nix index bbb94d88cc..43f593a96d 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -1,6 +1,7 @@ { helpers, system, + nixvim, nixpkgs, nuschtosSearch, }: @@ -108,6 +109,10 @@ lib.fix ( gfm-alerts-to-admonitions = pkgs.python3.pkgs.callPackage ./gfm-alerts-to-admonitions { }; man-docs = pkgs.callPackage ./man { inherit options-json; }; + + lib-docs = pkgs.callPackage ./lib { + inherit nixvim; + }; } // lib.optionalAttrs (!pkgs.stdenv.isDarwin) { # NuschtOS/search does not seem to work on darwin diff --git a/docs/lib/default.nix b/docs/lib/default.nix new file mode 100644 index 0000000000..a3ef4d0654 --- /dev/null +++ b/docs/lib/default.nix @@ -0,0 +1,94 @@ +# Generates the documentation for library functions using nixdoc. +{ + lib, + runCommand, + writers, + nixdoc, + nixvim, + functionSets ? [ + # TODO: all lib sections + { + name = "utils"; + path = [ + "nixvim" + "utils" + ]; + description = "utility functions"; + } + { + name = "options"; + path = [ + "nixvim" + "options" + ]; + description = "NixOS / nixpkgs option handling"; + } + { + name = "types"; + description = "NixOS / nixpkgs option types"; + } + ], +}: + +runCommand "nixvim-lib-docs" + { + nativeBuildInputs = [ + nixdoc + ]; + + locations = writers.writeJSON "locations.json" ( + import ./function-locations.nix { + inherit lib functionSets; + root = nixvim; + functionSet = lib.extend nixvim.lib.overlay; + revision = nixvim.rev or "main"; + } + ); + + passthru.menu = '' + # Lib + - [lib.nixvim](lib/index.md) + ${lib.concatMapStringsSep "\n" ({ name, ... }: " - [${name}](lib/${name})") functionSets} + ''; + + } + '' + function docgen { + name=$1 + prefix="lib.$2" + baseName=$3 + description=$4 + + file="${nixvim}/lib/$baseName" + if [[ -e "$file.nix" ]]; then + file+=".nix" + elif [[ -e "$file/default.nix" ]]; then + file+="/default.nix" + else + echo "Error: no file for $file" + exit 1 + fi + + nixdoc \ + --prefix "$prefix" \ + --category "$name" \ + --description "$prefix.$name: $description" \ + --locs $locations \ + --file "$file" \ + > "$out/$name.md" + } + + mkdir -p "$out" + + ${lib.concatMapStrings ( + { + name, + path ? [ name ], + baseName ? name, + description, + }: + '' + docgen ${name} ${lib.escapeShellArg (lib.concatStringsSep "." (lib.lists.dropEnd 1 path))} ${baseName} ${lib.escapeShellArg description} + '' + ) functionSets} + '' diff --git a/docs/lib/function-locations.nix b/docs/lib/function-locations.nix new file mode 100644 index 0000000000..abd628cac3 --- /dev/null +++ b/docs/lib/function-locations.nix @@ -0,0 +1,74 @@ +{ + root, + lib, + functionSet, + functionSets, + revision, + functionSetName ? "lib", + url ? "https://github.com/nix-community/nixvim/blob", +}: +let + urlPrefix = "${url}/${revision}"; + + sanitizeId = builtins.replaceStrings [ "'" ] [ "-prime" ]; + + tryIsAttrs = v: (builtins.tryEval (builtins.isAttrs v)).value; + + getDefPositions = + prefix: set: + builtins.concatMap ( + name: + [ + { + name = builtins.concatStringsSep "." ([ functionSetName ] ++ prefix ++ [ name ]); + location = builtins.unsafeGetAttrPos name set; + } + ] + ++ lib.optionals (builtins.length prefix == 0 && tryIsAttrs set.${name}) ( + getDefPositions (prefix ++ [ name ]) set.${name} + ) + ) (builtins.attrNames set); + + getFnSubset = + set: + builtins.concatMap ( + { + name, + path ? [ name ], + ... + }: + getDefPositions path (lib.getAttrFromPath path set) + ) functionSets; + + removeFilenamePrefix = + prefix: filename: + let + prefixLen = (builtins.stringLength prefix) + 1; # +1 to remove the leading / + filenameLen = builtins.stringLength filename; + in + builtins.substring prefixLen filenameLen filename; + + removeNixvimPrefix = removeFilenamePrefix (builtins.toString root); + + toEntry = + { 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 ``"; + }; +in +lib.pipe functionSet [ + getFnSubset + (builtins.filter (elem: elem.location != null)) + # We only want to document functions defined in our tree + (builtins.filter (elem: lib.strings.hasPrefix (builtins.toString root) elem.location.file)) + (builtins.map toEntry) + builtins.listToAttrs +] diff --git a/flake/packages.nix b/flake/packages.nix index a9ba410a5d..03451350c1 100644 --- a/flake/packages.nix +++ b/flake/packages.nix @@ -1,4 +1,5 @@ { + self, inputs, helpers, ... @@ -12,6 +13,7 @@ }: { packages = import ../docs { + nixvim = self; inherit helpers; inherit system; inherit (inputs) nixpkgs;