diff --git a/users/pbsds/home/profiles/bashrc.d/nix-search.sh b/users/pbsds/home/profiles/bashrc.d/nix-search.sh new file mode 100644 index 0000000..e857f8f --- /dev/null +++ b/users/pbsds/home/profiles/bashrc.d/nix-search.sh @@ -0,0 +1,97 @@ +nix-search() ( + set -euo pipefail + flake="${1:-nixpkgs}" + + trace(){ + if [[ -t 2 ]]; then + printf >&2 "%s\n" "$@" + fi + } + die() { + printf >&2 "%s\n" "$@" + exit 1 + } + command -v nix >/dev/null || die "ERROR: 'nix' not in PATH" + command -v jq >/dev/null || die "ERROR: 'jq' not in PATH" + command -v fzf >/dev/null || die "ERROR: 'fzf' not in PATH" + command -v bat >/dev/null || die "ERROR: 'fzf' not in PATH" + command -v tr >/dev/null || die "ERROR: 'tr' not in PATH" + command -v sed >/dev/null || die "ERROR: 'sed' not in PATH" + command -v grep >/dev/null || die "ERROR: 'grep' not in PATH" + command -v sort >/dev/null || die "ERROR: 'sort' not in PATH" + + nixpkgs=$(nix eval "$flake"#path --json | jq . -r) # --raw hangs? + cache="${XDG_CACHE_HOME:-"$HOME/.cache"}/nix-search-sh" + + export storepath="$cache"/"${flake//"/"/--}"/path + export packages_json="$cache"/"${flake//"/"/--}"/packages.json + export packages_tsv="$cache"/"${flake//"/"/--}"/packages.tsv + + if [[ ! -f "$storepath" || "$nixpkgs" != "$(cat "$storepath")" ]]; then + mkdir -p "$cache"/"$flake" + + # TODO: somehow inherit if user has configured allowUnfree and such in any file + trace "Indexing..." + # true || \ + ( + system="$(nix config show system)" + set -x + time nix-env >"$packages_json" \ + --extra-experimental-features no-url-literals \ + --option system "$system" \ + -f "$nixpkgs" \ + -qaP \ + --json \ + --meta \ + --show-trace \ + --no-allow-import-from-derivation \ + --arg config '{ allowAliases = false; }' + ) + + trace "Preprocessing..." + trace "+ jq ..." + jq <"$packages_json" 'to_entries[] | "--\t\(.key)\t\((.value.meta.description // .value.meta.longDescription // "" | split("\n") | .[0]))\t\(({version: (.value.version)} // {}) + (.value.meta // {}))"' -r \ + | tr '0123456789' '9876543210' | sort | tr '0123456789' '9876543210' \ + > "$packages_tsv" + + printf "%s\n" "$nixpkgs" > "$storepath" + fi + + show-package() { + local attrpath="$(head -n1 <<<"$1")" + printf "%s\n" "(toggle preview with 'alt-enter')" + printf "\n" + + grep -F -- $'--\t'"$attrpath"$'\t' "$packages_tsv" | cut -f4 | jq '. | [ + "version : \(.version)", + "homepage : \(.homepage // "")", + "changelog : \(.changelog // "")", + "unfree : \(.unfree)", + "broken : \(.broken)", + "insecure : \(.insecure)", + "", + "\(.longDescription // .description)", + "", + "source: \(.position // "")", + "license:", ([if (.license|type)=="array" then .license[] else .license // [][] end | "- \(.fullName // .)"] | join("\n")), + "", + "platforms:", ([(.platforms // [])[]|"- \(.)"]|join("\n")) + ] | join("\n") + ' -r | bat --style=plain --language yaml --color=always + } + + # attrpaths=$( + cut <"$packages_tsv" -f2-3 | tr '\n' '\0' | tr '\t' '\n' \ + | fzf --read0 --print0 --gap 1 --reverse --bind 'ctrl-a:toggle-all' --bind 'alt-enter:toggle-preview' --multi --tiebreak=begin --preview "$(declare -f show-package); show-package {}" \ + | tr '\n\0' '\t\n' | cut -f1 + # ) + + # if [[ "$(wc -l <<<"$attrpaths")" -eq 1 ]]; then + # trace " nix profile install $flake#$attrpaths" + # trace " nix run $flake#$attrpaths" + # trace " nix shell $flake#$attrpaths^*" + # trace " nix-shell '<$flake>' -A $flake#$attrpaths" + # fi + + # cat <<<"$attrpaths" +)