From 5ab47d11f0981a24f40dc1e03bb5afacf27e8453 Mon Sep 17 00:00:00 2001 From: Jacob Magnusson Date: Fri, 26 Jun 2015 16:42:24 +0200 Subject: [PATCH] Command to activate virtualenvs on changing directory Enables automatic activation of a virtualenv when jumping into a directory This is done by looking in the current directory for a file or directory named `.venv`. If it's not found in the current directory its parents will also be examined. `.venv` can be either: 1. A file containing the name of a virtualenv found in $WORKON_HOME 2. A directory containing bin/activate (meaning that the directory is assumed to be a virtualenv.) If $WORKON_HOME is set it is assumed that virtualenvwrapper is installed and the `workon` command will be issued. --- modules/python/functions/workon-cwd | 60 +++++++++++++++++++++++++++++ modules/python/init.zsh | 4 ++ 2 files changed, 64 insertions(+) create mode 100644 modules/python/functions/workon-cwd diff --git a/modules/python/functions/workon-cwd b/modules/python/functions/workon-cwd new file mode 100644 index 00000000..90768a51 --- /dev/null +++ b/modules/python/functions/workon-cwd @@ -0,0 +1,60 @@ +# +# Enables automatic activation of a virtualenv when jumping into a directory +# This is done by looking in the current directory for a file or directory +# named `.venv`. If it's not found in the current directory its parents will +# also be examined. `.venv` can be either: +# +# 1. A file containing the name of a virtualenv found in $WORKON_HOME +# 2. A directory containing bin/activate (meaning that the directory is +# assumed to be a virtualenv.) +# +# If $WORKON_HOME is set it is assumed that virtualenvwrapper is installed and +# the `workon` command will be issued. +# + +function workon_cwd { + if [ ! $WORKON_CWD ]; then + WORKON_CWD=1 + # Look for a proper PROJECT_ROOT path + PROJECT_ROOT=$(pwd) + while [[ "$PROJECT_ROOT" != "/" && ! -e "$PROJECT_ROOT/.venv" ]]; do + PROJECT_ROOT=${PROJECT_ROOT:A:h} + done + + if [[ "$PROJECT_ROOT" == "/" ]]; then + PROJECT_ROOT="." + fi + # Check for virtualenv name override + if [[ -f "$PROJECT_ROOT/.venv" ]]; then + ENV_NAME=$(cat "$PROJECT_ROOT/.venv") + elif [[ -f "$PROJECT_ROOT/.venv/bin/activate" ]];then + ENV_NAME="$PROJECT_ROOT/.venv" + else + ENV_NAME="" + fi + if [[ "$ENV_NAME" != "" ]]; then + # Activate the environment only if it is not already active + if [[ "$VIRTUAL_ENV" != "$WORKON_HOME/$ENV_NAME" ]]; then + if [[ -e "$WORKON_HOME/$ENV_NAME/bin/activate" ]]; then + workon "$ENV_NAME" && export CD_VIRTUAL_ENV="$ENV_NAME" + elif [[ -e "$ENV_NAME/bin/activate" ]]; then + source $ENV_NAME/bin/activate && export CD_VIRTUAL_ENV="$ENV_NAME" + fi + fi + elif [[ -n $CD_VIRTUAL_ENV && -n $VIRTUAL_ENV ]]; then + # We've just left the repo, deactivate the environment + # Note: this only happens if the virtualenv was activated automatically + deactivate && unset CD_VIRTUAL_ENV + fi + unset PROJECT_ROOT + unset WORKON_CWD + fi +} + +if [[ ! $DISABLE_VENV_CD -eq 1 ]]; then + # Append workon_cwd to the chpwd_functions array, so it will be called on cd + # http://zsh.sourceforge.net/Doc/Release/Functions.html + if ! (( $chpwd_functions[(I)workon_cwd] )); then + chpwd_functions+=(workon_cwd) + fi +fi \ No newline at end of file diff --git a/modules/python/init.zsh b/modules/python/init.zsh index da78ea79..ad1fce53 100644 --- a/modules/python/init.zsh +++ b/modules/python/init.zsh @@ -43,6 +43,10 @@ if (( $+commands[virtualenvwrapper.sh] )); then VIRTUAL_ENV_DISABLE_PROMPT=1 source "$commands[virtualenvwrapper.sh]" + + if (( $+functions[workon-cwd] )); then + workon-cwd + fi fi #