# TODO: { pkgs, lib, nixpkgs, defaultManualPath, system, json2nix, ... }: let usage = pkgs.writeText "nix-option-search-usage" '' Usage: nix-option-search [ -j | -n ] [-f= [-r=]] Options: -h | --help Display this message. -j | --json Display raw data in json format. -np | --no-preview Don't display a preview. -nc | --no-color Turn off ANSI colors. -f=* | --flake=* Use a flake url to an instance (e.g. a fork) of nixpkgs, generate its options, and use those instead of the global ones. -r=* | --ref=* If a flake url is specified, this option might be used to choose a specific reference (branch, tag, commit, etc.) to use for generating the docs. Example usage: nix-option-search nix-option-search -j nix-option-search --flake="github:NixOS/nixpkgs" nix-option-search --flake="github:NixOS/nixpkgs" --ref="nixos-22.05" ''; inherit (pkgs.callPackage ../internals/lib.nix { }) jq fzf gomplate nixfmt bat perl blinkred bold red green yellow blue magenta clear flatten; # TODO: Preprocess all XML tags in description. substitutionsColor = let s = "\\s*"; in { "([^>]*)" = "${bold}`$1`${clear}"; "([^>]*)" = "${bold}`$1`${clear}"; "([^>]*)" = "${yellow}$1${clear}"; "([^>]*)" = "${bold}$1${clear}"; "([^>]*)" = "${red}$1${clear}"; "([^>]*)" = "${red}$1${clear}"; "" = "\\n"; "]*)\"${s}/>" = "${blue}$1${clear}"; "]*)\"${s}>([^<]*)" = "${bold}$2 ${clear}(${blue}$1${clear})"; "]*)\"${s}/>" = "${blue}$1${clear}"; }; substitutions = let s = "\\s*"; in { "([^>]*)" = "`$1`"; "([^>]*)" = "`$1`"; "([^>]*)" = "`$1`"; "([^>]*)" = "`$1`"; "([^>]*)" = "`$1`"; "([^>]*)" = "`$1`"; "" = "\\n"; "]*)\"${s}/>" = "`$1`"; "]*)\"${s}>([^<]*)" = "`$2 ($1)`"; "]*)\"${s}/>" = "`$1`"; }; perlArgsColor = with lib; pipe substitutionsColor [ (mapAttrsToList (name: value: "s|${name}|${value}|gm")) (concatStringsSep ";") (x: "-pe '${x}'") ]; perlArgs = with lib; pipe substitutions [ (mapAttrsToList (name: value: "s|${name}|${value}|gm")) (concatStringsSep ";") (x: "-pe '${x}'") ]; optionTemplateColor = pkgs.callPackage ../templates/option-preview-template-color.nix { }; optionTemplate = pkgs.callPackage ../templates/option-preview-template.nix { }; # TODO: This preview does not respect the color option... previewJson = pkgs.writers.writeBash "preview-nix-option-attrs-json" '' OPTION_KEY=$1 JSON_MANUAL_PATH=$2 ${jq} -C ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH ''; previewGomplate = isColorized: let # TODO: Color management here needs a refactoring badly... pArgs = if isColorized then perlArgsColor else perlArgs; colorSuffix = if isColorized then "-color" else ""; batColorArg = if isColorized then "--color=always " else ""; template = if isColorized then optionTemplateColor else optionTemplate; in pkgs.writers.writeBash "preview-nix-option-attrs-gomplate${colorSuffix}" '' OPTION_KEY=$1 JSON_MANUAL_PATH=$2 JSON_DATA=$(${jq} ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH) export DESCRIPTION=$(echo $JSON_DATA | ${jq} -r ".description" | ${perl} ${pArgs}) EXAMPLE_DATA=$(echo $JSON_DATA | ${jq} -r ".example.text" 2>/dev/null) if [ $? != 0 ]; then EXAMPLE_DATA=$(echo $JSON_DATA | ${jq} -r ".example" | ${json2nix}/bin/json2nix) fi export EXAMPLE=$(echo $EXAMPLE_DATA | ${nixfmt} | ${bat} ${batColorArg}--style=numbers) export DEFAULT=$(echo $JSON_DATA | ${jq} -r ".default" | ${json2nix}/bin/json2nix | ${nixfmt} | ${bat} ${batColorArg}--style=numbers) echo $JSON_DATA | ${gomplate} --datasource opt=stdin:?type=application/json --file ${template} ''; in pkgs.writers.writeBash "search-nix-option-attrs" '' JSON_MANUAL_PATH="${defaultManualPath}" for i in "$@"; do case $i in -h|--help) cat ${usage} exit 0 ;; -j|--json) PRINT_JSON=1 shift ;; -np|--no-preview) NO_PREVIEW=1 shift ;; -nc|--no-color) NO_COLOR=1 shift ;; -f=*|--flake=*) FLAKE="''${i#*=}" shift ;; -r=*|--ref=*) REF="''${i#*=}" shift ;; *|-*|--*) echo "Unknown option $i" cat ${usage} exit 1 ;; esac done if [ -v PRINT_JSON ] && [ -v NO_PREVIEW ]; then echo "Cannot preview as json with no-preview enabled" cat ${usage} exit 1 fi if [ -v FLAKE ]; then FLAKE_URL="''${FLAKE}" if [ -v REF ]; then FLAKE_URL="''${FLAKE_URL}?ref=$REF" fi echo "Building docs from $FLAKE_URL" OUT_PATH=$(${pkgs.nix}/bin/nix build --impure --no-link --print-out-paths --no-write-lock-file --expr "let nixpkgs=(builtins.getFlake \"$FLAKE_URL\"); in (import \"\''${nixpkgs}/nixos/release.nix\" { inherit nixpkgs; }).options") echo $OUT_PATH JSON_MANUAL_PATH="$OUT_PATH/share/doc/nixos/options.json" echo "Using docs located at $JSON_MANUAL_PATH" fi if [ -v NO_PREVIEW ]; then ${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} elif [ -v PRINT_JSON ]; then ${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewJson} {} $JSON_MANUAL_PATH" elif [ -v NO_COLOR ]; then ${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${ previewGomplate false } {} $JSON_MANUAL_PATH" else ${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${ previewGomplate true } {} $JSON_MANUAL_PATH" fi ''