#!/bin/zsh #dep:fd fzf source ${$(realpath "$0"):h:h}/lib/common.zsh zparseopts -D -E \ c=cdvenv -cdvenv=cdvenv \ h=help -help=help \ n=newvenv -new=newvenv \ t=tmsu -tmsu=tmsu \ p=pyenv -pyenv=pyenv \ f=find -find=find \ i=ignore -ignore-local=ignore \ s=save -save=save if [[ $help ]]; then <<-HELP Usage: ${0:t} [-c] [DIR] ${0:t} -t If DIR contains bin/activate, start a shell with that virtualenv. Otherwise recursively look up virtualenvs in DIR (by looking for dirs ending in "venv") and select one with fzf. OPTIONS: -c, --cdvenv Change to the venv directory instead of going back to the current working directory (not for pyenv virtualenvs) -t, --tmsu list only venvs named "venv" in a directory with tmsu tag lang=python -p, --pyenv Use pyenv virtualenvs -f, --find Search for virtualenvs by looking for directories ending with 'venv' If neither -p or -f are given, the default behaviour is to use both -s, --save Store selected venv in .venv in current directory. Will be used automatically, when called in this dir again. -i, --ignore-local Ignore .venv files. HELP exit fi ORIGDIR=$PWD venvsh() { cd $1 . bin/activate if [[ -z $cdvenv ]]; then cd $ORIGDIR fi exec $SHELL } pyenvsh() { export PYENV_VIRTUALENV_DISABLE_PROMPT=1 eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" pyenv activate "$1" exec $SHELL } envsh() { local venv=$1 if [[ $venv =~ pyenv\!* ]]; then pyenvsh ${venv##pyenv!} else venvsh $venv fi } if [[ -z $ignore && -e .venv ]]; then venv=$(<.venv) echo "Local .venv found (-i to ignore)." echo "Using: $venv" envsh $venv fi if [[ -n $tmsu ]]; then venv=$( for i in $(tmsu files --directory lang=python); do [[ -d $i/venv ]] && echo $i/venv done | fzf -q "$*") if [[ -n $venv ]]; then exec venvsh $venv else exit 1 fi fi if [[ $newvenv ]]; then python -mvenv ${1:-venv} exec venvsh ${1:-venv} fi if [[ -n $1 && -e $1/bin/activate ]]; then exec venvsh $1 fi pyenvs() { if exists pyenv && pyenv commands | grep -q 'virtualenvs'; then pyenv virtualenvs --bare --skip-aliases | sed -e 's/^/pyenv!/' fi } if [[ $pyenv && ! $find ]]; then venv=$(pyenvs | fzf -q "$*") elif [[ ! $pyenv && $find ]]; then venv=$(fd -I -t d 'venv$' $1 | fzf -q "$*") else venv=$(cat <(fd -I -t d 'venv$' $1) <(pyenvs) | fzf -q "$*") fi if [[ -n $venv ]]; then if [[ -n $save ]]; then echo $venv > .venv fi envsh $venv fi