diff --git a/.config/fish/conf.d/venv.fish b/.config/fish/conf.d/venv.fish index 4e73535e..9ed02c31 100644 --- a/.config/fish/conf.d/venv.fish +++ b/.config/fish/conf.d/venv.fish @@ -3,28 +3,31 @@ # * Instead of overriding cd, we detect directory change. This allows the script to work # for other means of cd, such as z. # * Update syntax to work with new versions of fish. -# * Handle virtualenvs that are not located in the root of a git directory. function __auto_source_venv --on-variable PWD --description "Activate/Deactivate virtualenv on directory change" status --is-command-substitution; and return - # Check if we are inside a git directory + # Searched directories are the current directory, and the root of the current git repo if applicable + set dirs (pwd) if git rev-parse --show-toplevel &>/dev/null - set gitdir (realpath (git rev-parse --show-toplevel)) - set cwd (pwd -P) - # While we are still inside the git directory, find the closest - # virtualenv starting from the current directory. - while string match "$gitdir*" "$cwd" &>/dev/null - if test -e "$cwd/.venv/bin/activate.fish" - source "$cwd/.venv/bin/activate.fish" &>/dev/null - return - else - set cwd (path dirname "$cwd") - end + set -a dirs (realpath (git rev-parse --show-toplevel)) + end + + # Scan directories for a fish-compatible virtual environment + set VENV_DIR_NAMES env .env venv .venv + for venv_dir in $dirs/$VENV_DIR_NAMES + if test -e "$venv_dir/bin/activate.fish" + break end end - # If virtualenv activated but we are not in a git directory, deactivate. - if test -n "$VIRTUAL_ENV" + + # Activate venv if it was found and not activated before + if test "$VIRTUAL_ENV" != "$venv_dir" -a -e "$venv_dir/bin/activate.fish" + source $venv_dir/bin/activate.fish + # Deactivate venv if it is activated but the directory doesn't exist + else if not test -z "$VIRTUAL_ENV" -o -e "$venv_dir" deactivate end end + +__auto_source_venv