Skip to main content

fish_functions/auto_activate_venv.fish

1# This tells fish to auto-activate my virtualenvs when I change directories.
2#
3# I have a fairly simple naming convention for my virtualenvs: I put
4# them in the root of the Git repo for each project, and I always
5# name them `~/.venv`. This means it's pretty easy to work out if
6# a virtualenv exists for the current directory.
7#
8# See https://alexwlchan.net/2023/fish-venv/
9#
10function auto_activate_venv --description "Auto activate/deactivate virtualenv when I change directories"
12 # Get the top-level directory of the current Git repo (if any)
13 set REPO_ROOT (git rev-parse --show-toplevel 2>/dev/null)
15 # Case #1: cd'd into a folder which has a .venv in its root.
16 #
17 # Activate this virtualenv if it's not already activated.
18 if test -d "$(pwd)/.venv"
19 if [ "$VIRTUAL_ENV" != "$(pwd)/.venv" ]
20 source "$(pwd)/.venv/bin/activate.fish" &>/dev/null
21 end
23 return
24 end
26 # Case #2: cd'd to a folder which isn't a Git repo and doesn't
27 # have a .venv at its root.
28 #
29 # Deactivate any virtualenv which is already active.
30 if test -z "$REPO_ROOT"; and test -n "$VIRTUAL_ENV"
31 deactivate
32 end
34 # Case #3: cd'd folders within the same Git repo
35 #
36 # The virtualenv for this Git repo is already activated, so there's
37 # nothing more to do.
38 if [ "$VIRTUAL_ENV" = "$REPO_ROOT/.venv" ]
39 return
40 end
42 # Case #4: cd'd from a non-Git folder into a Git repo
43 #
44 # If there's a virtualenv in the root of this repo, we should
45 # activate it now.
46 if [ -d "$REPO_ROOT/.venv" ]
47 source "$REPO_ROOT/.venv/bin/activate.fish" &>/dev/null
48 end
49end