_nix_storepath_in_cmd() (
  set -euo pipefail
  declare nix="${1:-}"
  declare cmd="${2:-}"
  # declare arg2narg="${3:-}"

  declare nth
  # for nth in 1st 2nd 3rd; do
  for nth in 1st 2nd; do
    if [[ -z "${1:-}" ]] && ! shift; then
      echo >&2 "_nix_storepath_in_cmd() ERROR: missing $nth param"
      false
    fi
  done

  if [[ $# -lt 2 ]]; then
    printf >&2 "%s\n" "ERROR: not enough args"
    false
  fi

  target_nix=0
  in_cmd_nargs=false # TODO: turn into countdown
  cmd_pattern=()
  cmd_flags=()
  nix_args=()
  nix_flags=()

  # set -x
  for arg in "$@"; do
    # separator - swaps target
    if [[ "$arg" = "--" ]]; then
      if "$in_cmd_nargs"; then
        in_cmd_nargs=false
      fi
      ((target_nix ^= 1)) || :

    # flag
    elif [[ "$arg" =~ ^- ]]; then
      if [[ $target_nix -eq 0 ]] || $in_cmd_nargs; then
        cmd_flags+=("$arg")
        if [[ "$arg" = "-x" ]]; then
          in_cmd_nargs=true
        fi
      else
        nix_flags+=("$arg")
      fi

    # arg
    elif [[ ! -v cmd_pattern[0] ]]; then
      cmd_pattern+=("$arg")
    elif $in_cmd_nargs; then
      cmd_flags+=("$arg")
    elif [[ $target_nix -ne 0 ]]; then
      nix_flags+=("$arg")
    elif [[ "${arg}" =~ ^.*[#:/].*$ ]]; then
      nix_args+=("$arg")
    else
      nix_args+=("nixpkgs#$arg")
    fi
  done

  # echo + "$nix" build "${nix_args[@]}" "${nix_flags[@]}"
  # echo + fd "${cmd_pattern[@]}" ... "${cmd_flags[@]}"
  # return

  readarray -d $'\n' -t storepaths < <(
    "$nix" build "${nix_args[@]}" "${nix_flags[@]}" --print-out-paths --no-link
  )
  if [[ "${#storepaths[@]}" -gt 0 ]]; then
    fd "${cmd_pattern[@]}" "${storepaths[@]}" "${cmd_flags[@]}"
  fi
)

if command -v fd >/dev/null; then
  __fd_arg2narg() {
    case "$1" in
    -x) echo '+' ;;
    # TODO:
    # ) echo 1 ;;
    *) ;;
    esac
  }
  # nix-fd() { _nix_storepath_in_cmd "nix" "fd" __fd_arg2narg "$@"; }
  nix-fd() { _nix_storepath_in_cmd "nix" "fd" "$@"; }
  if command -v nom >/dev/null; then
    nom-fd() { _nix_storepath_in_cmd "nom" "fd" "$@"; }
  fi
fi

if command -v rg >/dev/null; then
  __rg_arg2narg() {
    case "$1" in
    -e | --regexp) echo 1 ;;
    -f | --file) echo 1 ;;
    --pre) echo 1 ;;
    --dfa-size-limit) echo 1 ;;
    -E | --encoding) echo 1 ;;
    --engine) echo 1 ;;
    -m | --max-count) echo 1 ;;
    --regex-size-limit) echo 1 ;;
    -j | --threads) echo 1 ;;
    -g | --glob | --iglob) echo 1 ;;
    --ignore-file) echo 1 ;;
    -d | --max-depth) echo 1 ;;
    --max-filesize) echo 1 ;;
    -t | --type) echo 1 ;;
    -T | --type-not) echo 1 ;;
    --type-add) echo 1 ;;
    --type-clear) echo 1 ;;
    -A | --after-context) echo 1 ;;
    -B | --before-context) echo 1 ;;
    --color) echo 1 ;;
    --colors) echo 1 ;;
    --colors) echo 1 ;;
    -C | --context) echo 1 ;;
    --context-separator) echo 1 ;;
    --field-context-separator) echo 1 ;;
    --field-match-separator) echo 1 ;;
    --hostname-bin) echo 1 ;;
    --hyperlink-format) echo 1 ;;
    -M | --max-columns) echo 1 ;;
    --path-separator) echo 1 ;;
    -r | --replace) echo 1 ;;
    --sort) echo 1 ;;
    --sortr) echo 1 ;;
    --generate) echo 1 ;;
    *) ;;
    esac
  }
  # nix-rg() { _nix_storepath_in_cmd "nix" "rg" __rg_arg2narg "$@"; }
  nix-rg() { _nix_storepath_in_cmd "nix" "rg" "$@"; }
  if command -v nom >/dev/null; then
    # nom-rg() { _nix_storepath_in_cmd "nom" "rg" __rg_arg2narg "$@"; }
    nom-rg() { _nix_storepath_in_cmd "nom" "rg" "$@"; }
  fi
fi

nixfd() {
  echo >&2 "did you mean 'nix-fd'?"
  false
}
