virtualenvzshoh-my-zshvirtualenvwrapperdirenv

How to automatically activate virtualenvs when cd'ing into a directory


I have a bunch of projects in my ~/Documents. I work almost exclusively in python, so these are basically all python projects. Each one, e.g. ~/Documents/foo has its own virtualenv, ~/Documents/foo/venv (they're always called venv). Whenever I switch between projects, which is ~10 times a day, I do

deactivate
cd ..
cd foo
source venv/bin/activate

I've reached the point where I'm sick of typing deactivate and source venv/bin/activate. I'm looking for a way to just cd ../foo and have the virtualenv operations handled for me.


Solution

  • Put something like this in your .zshrc

    function cd() {
      if [[ -d ./venv ]] ; then
        deactivate
      fi
    
      builtin cd $1
    
      if [[ -d ./venv ]] ; then
        . ./venv/bin/activate
      fi
    }
    

    Edit: As noted in comments cd-ing into a subfolder of the current virtual env would deactivate it. One idea could be to deactivate the current env only if cd-ing into a new one, like

    function cd() {
      builtin cd $1
    
      if [[ -n "$VIRTUAL_ENV" && -d ./venv ]] ; then
        deactivate
        . ./venv/bin/activate
      fi
    }
    

    that could still be improved, maybe turning it into a "prompt command" or attempting some prefix matching on the folder names to check there's a virtual env somewhere up the path, but my shell-fu is not good enough.