Files
config/users/pbsds/home/profiles/bashrc.d/nix-shell.sh
T
2025-05-01 16:55:19 +02:00

173 lines
5.7 KiB
Bash

_ns_ohk2aaDu() {
local is_dev=$1; shift # "true" or "false"
if $is_dev; then
local arg_suffix="^*"
else
local arg_suffix=""
fi
local args=()
local pkg
for pkg in "$@"; do
if [[ "$pkg" = -- ]]; then
break
fi
if [[ "$pkg" =~ ^.*[#:/].*$ ]]; then
args+=("${pkg}${arg_suffix}")
else
args+=(nixpkgs#"${pkg}${arg_suffix}")
fi
done
# Run anything after -- as a command
local cmd=("$@")
while [[ "${#cmd[@]}" -gt 1 && "${cmd[0]}" != "--" ]]; do
cmd=("${cmd[@]:1}")
done
cmd=("${cmd[@]:1}")
if [[ ${#cmd[@]} -gt 0 ]]; then
(
_ns_ohk2aaDu false "${args[@]}"
set -x
"${cmd[@]}"
)
return $?
fi
# echo current shell
# TODO: deduplicate repeats, 'x^*' should replace 'x'
# echo >&2 -n + exec nix shell
echo >&2 -n + ns
if [[ -v _PREVIOUS_NS_ARGS ]]; then
echo >&2 -n " ${_PREVIOUS_NS_ARGS:-}"
fi
>&2 printf " %q" "${args[@]}"
echo >&2
if [[ "${#args[@]}" -eq 0 ]]; then
return
fi
local outpaths="$(
export NIXPKGS_ALLOW_BROKEN
export NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM
export NIXPKGS_ALLOW_UNFREE
export NIXPKGS_ALLOW_INSECURE
if [[ -t 2 ]] && command -v nom >/dev/null ]]; then
nom build --extra-experimental-features "nix-command flakes" --impure "${args[@]}" --print-out-paths --no-link
else
nix build --extra-experimental-features "nix-command flakes" --impure "${args[@]}" --print-out-paths --no-link
fi
)"
if [[ $? -ne 0 || -z "$outpaths" ]]; then
return
fi
local -a storepaths_native=()
local -a storepaths_build=()
readarray -d $'\n' -t storepaths_native <<<"$outpaths"
readarray -d $'\n' -t storepaths_build <<<"$outpaths"
# traverse propagated inputs
# this is safe since the store paths form a DAG
# TODO: rethink native logic
local -i idx=-1
while [[ $((++idx)) -lt "${#storepaths_native[@]}" ]]; do
if [[ -f "${storepaths_native[$idx]}"/nix-support/propagated-native-build-inputs ]]; then
storepaths_native+=($(cat "${storepaths_native[$idx]}"/nix-support/propagated-native-build-inputs))
fi
# TODO: needed?
if [[ -f "${storepaths_native[$idx]}"/nix-support/propagated-build-inputs ]]; then
storepaths_build+=($(cat "${storepaths_native[$idx]}"/nix-support/propagated-build-inputs))
fi
done
local -i idx=-1
while [[ $((++idx)) -lt "${#storepaths_build[@]}" ]]; do
if [[ -f "${storepaths_build[$idx]}"/nix-support/propagated-build-inputs ]]; then
storepaths_build+=($(cat "${storepaths_build[$idx]}"/nix-support/propagated-build-inputs))
fi
done
# find things to add to env
local -A seen=()
# for storepath in "${storepaths_native[@]}"; do
for storepath in "${storepaths_build[@]}"; do
if [[ -v seen["$storepath"] ]]; then
continue
fi
seen["$storepath"]=1
# TODO: $dev/lib/cmake
# TODO: source completions from /share/bash-completion/completions/*
if [[ -d "$storepath/bin" ]]; then
export PATH="$storepath/bin${PATH:+":$PATH"}"
fi
if >/dev/null compgen -G "$storepath/lib/*.so*"; then
export LDPATH="-L$storepath/lib${LDPATH:+" $LDPATH"}"
export LD_LIBRARY_PATH="$storepath/lib${LD_LIBRARY_PATH:+":$LD_LIBRARY_PATH"}"
export CMAKE_LIBRARY_PATH="$storepath/lib${CMAKE_LIBRARY_PATH:+":$CMAKE_LIBRARY_PATH"}"
fi
if [[ -d "$storepath/lib/pkgconfig" ]]; then
export PKG_CONFIG_PATH="$storepath/lib/pkgconfig${PKG_CONFIG_PATH:+":$PKG_CONFIG_PATH"}"
fi
if [[ -d "$storepath/share" ]]; then
export XDG_DATA_DIRS="$storepath/share${XDG_DATA_DIRS:+":$XDG_DATA_DIRS"}"
fi
if [[ -d "$storepath/share/man" ]]; then
if [[ ! -v MANPATH ]] && command -v manpath >/dev/null; then
export MANPATH="$(manpath)"
fi
export MANPATH="$storepath/share/man:$MANPATH"
fi
# TODO: see /nix/store/...-bash-completion-2.14.0/etc/profile.d/bash_completion.sh for details on how to source these
# if [[ -d "$storepath/share/bash-completion/completions" ]] && shopt -q progcomp; then
# "$storepath/share/bash-completion/completions/*.bash"
# "$storepath/share/bash-completion/completions/*"
# "$storepath/share/bash-completion/completions/_*"
# fi
if [[ -d "$storepath/share/pkgconfig" ]]; then
export PKG_CONFIG_PATH="$storepath/share/pkgconfig${PKG_CONFIG_PATH:+":$PKG_CONFIG_PATH"}"
fi
if [[ -d "$storepath/lib/pkgconfig" ]]; then
export PKG_CONFIG_PATH="$storepath/lib/pkgconfig${PKG_CONFIG_PATH:+":$PKG_CONFIG_PATH"}"
fi
if [[ -d "$storepath/include" ]]; then
export CPATH="$storepath/include${CPATH:+":$CPATH"}"
export CMAKE_INCLUDE_PATH="$storepath/include${CMAKE_INCLUDE_PATH:+":$CMAKE_INCLUDE_PATH"}"
fi
if >/dev/null compgen -G "$storepath/lib/python*/site-packages"; then
export PYTHONPATH="$(IFS=: ; printf "%s" "$storepath"/lib/python*/site-packages)${PYTHONPATH:+":$PYTHONPATH"}"
# export PYTHONNOUSERSITE=1
fi
done
if [[ -v _PREVIOUS_NS_ARGS ]]; then
export _PREVIOUS_NS_ARGS="$_PREVIOUS_NS_ARGS$(printf " %q" "${args[@]}")"
else
export _PREVIOUS_NS_ARGS="$(printf " %q" "${args[@]}" | cut -c2-)"
fi
}
ns() { _ns_ohk2aaDu false "$@"; }
nd() { _ns_ohk2aaDu true "$@"; }
# TODO: some way to "pop"?
# TODO: support empty args with nix-search
# enter
ne() {
local pkg="$1"
if [[ -z "$pkg" ]]; then
return
fi
if [[ ! "$pkg" =~ ^.*[#:/].*$ ]]; then
pkg=nixpkgs#"${pkg}"
fi
ns "$@"
# storepath="$(nix --extra-experimental-features "nix-command flakes" build --impure "$pkg" --print-out-paths --no-link | head -n1)"
storepath="$(nix --extra-experimental-features "nix-command flakes" eval --impure "$pkg" --raw)"
printf >&2 "+ cd %q\n" "$storepath"
cd "$storepath"
}