I use direnv
to automatically set environment variables per directory.
It's great, but there's no elegant solution for aliases with direnv
.
So I rolled my own, inspired by this answer on Ask Ubuntu.
Add a few lines to your .bashrc
and place custom aliases into a .aliases
file in any directory.
Those aliases will be set when you enter that dir, and unset when you leave.
It's certainly not perfect and there are doubtless some gotchas, but it's pretty handy.
Add the following to your .bashrc
so whenever you start a shell, it will load the .aliases
file in whichever dir your shell has started. You should add it somewhere after your other aliases are defined/loaded.
function _aliases_add() {
source ./.aliases 2>/dev/null || :
}
function cd() {
# Before leaving dir, unset aliases.
if [[ -f ./.aliases ]]; then
# Remove custom aliases
kill_list=$(sed -re 's/^alias ([^=]+).+/\1/g' ./.aliases | tr $'\n' ' ')
echo "Reverting aliases: ${kill_list}"
unalias $kill_list || :
# Then restore all previous aliases:
source ~/.bash_aliases 2>/dev/null || :
fi
# Do the actual "cd".
[[ -z "$*" ]] && builtin cd $HOME >/dev/null || :
[[ -n "$*" ]] && builtin cd "$*" >/dev/null || :
# Add local aliases.
if [[ -f ./.aliases ]]; then
add_list=$(sed -re 's/^alias ([^=]+).+/\1/g' ./.aliases | tr $'\n' ' ')
echo "Aliasing: ${add_list}"
_aliases_add
fi
}
# Hook to ensure aliases are added whenever prompt is displayed.
_aliases_hook() {
# This inspired by (lovingly copied off from) direnv.
local previous_exit_status=$?;
trap -- '' SIGINT;
_aliases_add
trap - SIGINT;
return $previous_exit_status;
};
if ! [[ "${PROMPT_COMMAND:-}" =~ _aliases_hook ]]; then
PROMPT_COMMAND="_aliases_hook${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
fi
The .aliases
file should contain standard bash aliases, so for example something like this:
alias go=go1.24.4
alias ag="ag --python"
alias tree="tree --gitignore --ignore-case -I venv -I 'venv*'"