Every time you cd into a Python project, you manually run source .venv/bin/activate.fish.
Leaving means remembering to deactivate.
Jumping with z is worse β the venv never activates at all.
auto-venv handles all of it. Enter a directory and the venv activates. Leave and it deactivates.
Installation
With fisher:
| |
Or manually:
| |
Restart your terminal or run source ~/.config/fish/config.fish to apply.
How It Works
Watching PWD Instead of Overriding cd
This is the most important design decision. Most venv auto-activation tools override the cd builtin, which means tools like z, zoxide, and pushd bypass the hook entirely β the venv never activates.
auto-venv watches Fish’s special $PWD variable instead. Any directory change, regardless of how it happened, fires the handler:
| |
The status --is-command-substitution; and return guard prevents it from firing inside $(...) subshells.
Using the Git Root as the Lookup Base
| |
Inside a git repository, the venv is always looked up at the repo root β not the current subdirectory. So navigating from myproject/ into myproject/src/utils/ keeps the venv active. Outside a git repo, it falls back to pwd.
Recognizing Four venv Names
| |
It searches env, .env, venv, .venv in that order, checking for the existence of bin/activate.fish. Returns the first match.
Activation and Deactivation Logic
| |
Three cases:
- Venv found, different from current β activate it (
activate.fishdeactivates the old one internally) - Venv found, same as current β do nothing (navigating within the same project doesn’t re-source)
- No venv found β deactivate if one is active
In Practice
| |
Configuration
auto-venv has no configuration. The venv directory names are hardcoded (env, .env, venv, .venv). If your project uses a different name (e.g., .python-env), fork the repo and edit the VENV_DIR_NAMES list in __venv.
Limitations
- Only supports standard Python venvs (
python -m venv,virtualenv) β detection relies onbin/activate.fishexisting - conda environments are not supported β conda has its own activation mechanism
- pyenv-virtualenv is not supported for the same reason
Manual vs auto-venv
| Scenario | Manual | auto-venv |
|---|---|---|
| cd into project | Must source activate.fish | Auto-activates |
| Navigate subdirectories | Venv stays (no deactivate) | Venv stays |
| cd out of project | Must remember to deactivate | Auto-deactivates |
| Jump with z/zoxide | Venv doesn’t activate | Auto-activates |
| Switch between projects | Deactivate then activate | Auto-switches |
Summary
The entire plugin is under 40 lines. Watching $PWD instead of overriding cd makes it compatible with every navigation tool. Using the git root as the lookup base means moving between subdirectories never accidentally kills the venv. Once installed, you stop thinking about virtual environment management entirely.
