I’m trying to transition my pkgs from brew to nix using nix-env -I. I installed the bash-completion pkg via nix-env. At runtime, it appears to correctly locate user completions under ~/.local/share/bash-completion/completions as well as its own plethora of bundled completion scripts. However, after installing a pkg (with nix-env -I) which installs its own completion script (e.g. as git does when installed this way), these new scripts aren’t getting sourced/found by bash-completion at runtime, and as a result there is no completion for the git command. This is strange because the file ~/.nix-profile/share/bash-completion/completions/git exists?
In my .bashrc, I am using this:
# Bash Completions
if [ -n "$BASH" ]; then
# [[ -r "$HOMEBREW_PREFIX/etc/profile.d/bash_completion.sh" ]] \
# && . "$HOMEBREW_PREFIX/etc/profile.d/bash_completion.sh"
[[ -r ~/.nix-profile/etc/profile.d/bash_completion.sh ]] \
&& . ~/.nix-profile/etc/profile.d/bash_completion.sh
fi
that file getting sourced is this:
# shellcheck shell=sh disable=SC1091,SC2039,SC2166
# Check for interactive bash and that we haven't already been sourced.
if [ "x${BASH_VERSION-}" != x -a "x${PS1-}" != x -a "x${BASH_COMPLETION_VERSINFO-}" = x ]; then
# Check for recent enough version of bash.
if [ "${BASH_VERSINFO[0]}" -gt 4 ] ||
[ "${BASH_VERSINFO[0]}" -eq 4 -a "${BASH_VERSINFO[1]}" -ge 2 ]; then
[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] &&
. "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
if shopt -q progcomp && [ -r /nix/store/jyrf6lp9qfnh1iw2lilp5krgh1kxr27y-bash-completion-2.11/share/bash-completion/bash_completion ]; then
# Source completion code.
. /nix/store/jyrf6lp9qfnh1iw2lilp5krgh1kxr27y-bash-completion-2.11/share/bash-completion/bash_completion
fi
fi
fi
I was able to fix it for the most part, although I’m not sure if it’s the correct/best solution.
I ended up putting this directly into my ~/.bashrc instead:
# shellcheck shell=sh disable=SC1091,SC2039,SC2166
# Check for interactive bash and that we haven't already been sourced.
if [ "x${BASH_VERSION-}" != x -a "x${PS1-}" != x -a "x${BASH_COMPLETION_VERSINFO-}" = x ]; then
# Check for recent enough version of bash.
if [ "${BASH_VERSINFO[0]}" -gt 4 ] ||
[ "${BASH_VERSINFO[0]}" -eq 4 -a "${BASH_VERSINFO[1]}" -ge 2 ]; then
[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] &&
. "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
if shopt -q progcomp && [ -r /nix/store/jyrf6lp9qfnh1iw2lilp5krgh1kxr27y-bash-completion-2.11/share/bash-completion/bash_completion ]; then
# Source completion code.
- . /nix/store/jyrf6lp9qfnh1iw2lilp5krgh1kxr27y-bash-completion-2.11/share/bash-completion/bash_completion
+ . ~/.nix-profile/share/bash-completion/bash_completion
fi
fi
fi
It appears that when bash_completion is sourced via the store path, it will only use its static/bundled completions dir instead of the correct one at ~/.nix-profile/share/bash-completion/completions. The latter is the correct one because it is the one which receives updates when new packages are installed with nix-env, while the former does not. For whatever reason, when sourcing it as ~/.nix-profile/share/bash-completion/bash_completion it uses the correct completions dir, but not when sourcing it via the store path. I assume that the bash_completion script is using a relative path to locate its main completions dir.
I’m sharing all of this just in case it helps someone else out, or if someone knows of a better solution or a more proper way to set this up? I’m not really sure why nix is creating ~/.nix-profile/etc/profile.d/bash_completion.sh and patching it to use the static dir (at the store path, which does not receive installed completion scripts from newly installed pkgs) by default.