Last active
October 13, 2021 12:47
-
-
Save mrchrisadams/9309736 to your computer and use it in GitHub Desktop.
virtual environments with python and fish
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################ | |
# Automatic activation | |
if not set -q VIRTUALFISH_ACTIVATION_FILE | |
set -g VIRTUALFISH_ACTIVATION_FILE .venv | |
end | |
function __vfsupport_auto_activate --on-variable PWD | |
if status --is-command-substitution | |
return | |
end | |
# find an auto-activation file | |
set -l activation_root $PWD | |
set -l new_virtualenv_name "" | |
while test $activation_root != "" | |
if test -f "$activation_root/$VIRTUALFISH_ACTIVATION_FILE" | |
set new_virtualenv_name (cat "$activation_root/$VIRTUALFISH_ACTIVATION_FILE") | |
break | |
end | |
# this strips the last path component from the path. | |
set activation_root (echo $activation_root | sed 's|/[^/]*$||') | |
end | |
if test $new_virtualenv_name != "" | |
# if the virtualenv in the file is different, switch to it | |
if begin; not set -q VIRTUAL_ENV; or test $new_virtualenv_name != (basename $VIRTUAL_ENV); end | |
vf activate $new_virtualenv_name | |
set -g VF_AUTO_ACTIVATED $activation_root | |
end | |
else | |
# if there's an auto-activated virtualenv, deactivate it | |
if set -q VIRTUAL_ENV VF_AUTO_ACTIVATED | |
vf deactivate | |
end | |
end | |
end | |
# remove the auto-activation flag on deactivation | |
function __vfsupport_deactivate_remove_flag --on-event virtualenv_did_deactivate | |
# remove autoactivated flag | |
if set -q VF_AUTO_ACTIVATED | |
set -e VF_AUTO_ACTIVATED | |
end | |
end | |
#automatically activate if started in a directory with a virtualenv in it | |
__vfsupport_auto_activate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# add ~/.config/fish/config.fish | |
# add this to config.fish, to make it work properly | |
#include virtual fish, so I can change virtual envs with python | |
set -g VIRTUALFISH_COMPAT_ALIASES | |
# set up paths for loading in | |
set vfish_path ~/.config/fish/virtual_fish/virtual.fish | |
set vfish_autopath ~/.config/fish/virtual_fish/auto_activation.fish | |
set vfish_global ~/.config/fish/virtual_fish/global_requirements.fish | |
for p in $vfish_path $vfish_autopath $vfish_global | |
source $p | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function __vfext_global_requirements --on-event virtualenv_did_create | |
if test -f $VIRTUALFISH_HOME/global_requirements.txt | |
pip install -r $VIRTUALFISH_HOME/global_requirements.txt | |
end | |
end | |
function __vf_requirements --description "Edit the global requirements file for all virtualenvs" | |
eval $EDITOR $VIRTUALFISH_HOME/global_requirements.txt | |
pushd $VIRTUALFISH_HOME | |
# If the user has set up wheels, make sure we build wheels of all the deps | |
# prior to trying to install them, so as to speed things up | |
if set -q PIP_USE_WHEEL | |
pip wheel -r $VIRTUALFISH_HOME/global_requirements.txt | |
end | |
for i in */bin/pip | |
eval $i install -U -r $VIRTUALFISH_HOME/global_requirements.txt | |
end | |
popd | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# VirtualFish | |
# A Virtualenv wrapper for the Fish Shell based on Doug Hellman's virtualenvwrapper | |
if not set -q VIRTUALFISH_HOME | |
set -g VIRTUALFISH_HOME $HOME/.virtualenvs | |
end | |
if set -q VIRTUALFISH_COMPAT_ALIASES | |
function workon | |
if not set -q argv[1] | |
vf ls | |
else | |
vf activate $argv[1] | |
end | |
end | |
function deactivate | |
vf deactivate | |
end | |
function mktmpenv | |
vf tmp $argv | |
end | |
function mkvirtualenv | |
# Check if the first argument is an option to virtualenv | |
# if it is then the the last argument must be the DEST_DIR. | |
set -l idx 1 | |
switch $argv[1] | |
case '-*' | |
set idx -1 | |
end | |
# Extract the DEST_DIR and remove it from $argv | |
set -l env_name $argv[$idx] | |
set -e argv[$idx] | |
vf new $argv $env_name | |
end | |
function rmvirtualenv | |
vf rm $argv | |
end | |
function add2virtualenv | |
__vf_addpath $argv | |
end | |
function cdvirtualenv | |
vf cd $argv | |
end | |
function cdsitepackages | |
vf cdpackages $argv | |
end | |
end | |
function vf --description "VirtualFish: fish plugin to manage virtualenvs" | |
# copy all but the first argument to $scargs | |
set -l sc $argv[1] | |
set -l funcname "__vf_$sc" | |
set -l scargs | |
if test (count $argv) -gt 1 | |
set scargs $argv[2..-1] | |
end | |
if functions -q $funcname | |
eval $funcname $scargs | |
else | |
echo "The subcommand $sc is not defined" | |
end | |
end | |
function __vf_activate --description "Activate a virtualenv" | |
# check arguments | |
if [ (count $argv) -lt 1 ] | |
echo "You need to specify a virtualenv." | |
return 1 | |
end | |
if not [ -d $VIRTUALFISH_HOME/$argv[1] ] | |
echo "The virtualenv $argv[1] does not exist." | |
echo "You can create it with mkvirtualenv." | |
return 2 | |
end | |
#Check if a different env is being used | |
if set -q VIRTUAL_ENV | |
vf deactivate | |
end | |
emit virtualenv_will_activate | |
emit virtualenv_will_activate:$argv[1] | |
set -gx VIRTUAL_ENV $VIRTUALFISH_HOME/$argv[1] | |
set -g _VF_EXTRA_PATH $VIRTUAL_ENV/bin | |
set -gx PATH $_VF_EXTRA_PATH $PATH | |
# hide PYTHONHOME | |
if set -q PYTHONHOME | |
set -g _VF_OLD_PYTHONHOME $PYTHONHOME | |
set -e PYTHONHOME | |
end | |
emit virtualenv_did_activate | |
emit virtualenv_did_activate:(basename $VIRTUAL_ENV) | |
end | |
function __vf_deactivate --description "Deactivate the currently-activated virtualenv" | |
emit virtualenv_will_deactivate | |
emit virtualenv_will_deactivate:(basename $VIRTUAL_ENV) | |
# find elements to remove from PATH | |
set to_remove | |
for i in (seq (count $PATH)) | |
if contains $PATH[$i] $_VF_EXTRA_PATH | |
set to_remove $to_remove $i | |
end | |
end | |
# remove them | |
for i in $to_remove | |
set -e PATH[$i] | |
end | |
# restore PYTHONHOME | |
if set -q _VF_OLD_PYTHONHOME | |
set -gx PYTHONHOME $_VF_OLD_PYTHONHOME | |
set -e _VF_OLD_PYTHONHOME | |
end | |
emit virtualenv_did_deactivate | |
emit virtualenv_did_deactivate:(basename $VIRTUAL_ENV) | |
set -e VIRTUAL_ENV | |
end | |
function __vf_new --description "Create a new virtualenv" | |
emit virtualenv_will_create | |
set envname $argv[-1] | |
set -e argv[-1] | |
virtualenv $argv $VIRTUALFISH_HOME/$envname | |
set vestatus $status | |
if begin; [ $vestatus -eq 0 ]; and [ -d $VIRTUALFISH_HOME/$envname ]; end | |
vf activate $envname | |
emit virtualenv_did_create | |
emit virtualenv_did_create:(basename $VIRTUAL_ENV) | |
else | |
echo "Error: The virtualenv wasn't created properly." | |
echo "virtualenv returned status $vestatus." | |
return 1 | |
end | |
end | |
function __vf_rm --description "Delete a virtualenv" | |
if not [ (count $argv) -eq 1 ] | |
echo "You need to specify exactly one virtualenv." | |
return 1 | |
end | |
if begin; set -q VIRTUAL_ENV; and [ $argv[1] = (basename $VIRTUAL_ENV) ]; end | |
echo "You can't delete a virtualenv you're currently using." | |
return 1 | |
end | |
echo "Removing $VIRTUALFISH_HOME/$argv[1]" | |
rm -rf $VIRTUALFISH_HOME/$argv[1] | |
end | |
function __vf_ls --description "List all of the available virtualenvs" | |
pushd $VIRTUALFISH_HOME | |
for i in */bin/python | |
echo $i | |
end | sed "s|/bin/python||" | |
popd | |
end | |
function __vf_cd --description "Change directory to currently-activated virtualenv" | |
if set -q VIRTUAL_ENV | |
cd $VIRTUAL_ENV | |
else | |
echo "Cannot locate an active virtualenv." | |
end | |
end | |
function __vf_cdpackages --description "Change to the site-packages directory of the active virtualenv" | |
vf cd | |
cd lib/python*/site-packages | |
end | |
function __vf_connect --description "Connect this virtualenv to the current directory" | |
if set -q VIRTUAL_ENV | |
basename $VIRTUAL_ENV > $VIRTUALFISH_ACTIVATION_FILE | |
else | |
echo "No virtualenv is active." | |
end | |
end | |
function __vf_tmp --description "Create a temporary virtualenv that will be removed when deactivated" | |
set -l env_name (printf "%s%.4x" "tempenv-" (random) (random) (random)) | |
set -g VF_TEMPORARY_ENV | |
# Use will_deactivate here so that $VIRTUAL_ENV is available. | |
function __vf_tmp_remove --on-event virtualenv_will_deactivate:$env_name | |
echo "Removing $VIRTUAL_ENV" | |
rm -rf $VIRTUAL_ENV | |
set -e VF_TEMPORARY_ENV | |
end | |
# Ensure that the virtualenv gets deleted even if we close the shell w/o | |
# explicitly deactivating. | |
function __vfsupport_remove_temp_env_on_exit --on-process %self | |
if set -q VF_TEMPORARY_ENV | |
vf deactivate # the deactivate handler will take care of removing it | |
end | |
end | |
vf new $argv $env_name | |
end | |
function __vf_addpath --description "Adds a path to sys.path in this virtualenv" | |
if set -q VIRTUAL_ENV | |
set -l site_packages (eval "$VIRTUAL_ENV/bin/python -c 'import distutils; print(distutils.sysconfig.get_python_lib())'") | |
set -l path_file $site_packages/_virtualenv_path_extensions.pth | |
set -l remove 0 | |
if test $argv[1] = "-d" | |
set remove 1 | |
set -e argv[1] | |
end | |
if not test -f $path_file | |
echo "import sys; sys.__plen = len(sys.path)" > $path_file | |
echo "import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)" >> $path_file | |
end | |
for pydir in $argv | |
set -l absolute_path (eval "$VIRTUAL_ENV/bin/python -c 'import os,sys; sys.stdout.write(os.path.abspath(\"$pydir\")+\"\n\")'") | |
if not test $pydir = $absolute_path | |
echo "Warning: Converting \"$pydir\" to \"$absolute_path\"" 1>&2 | |
end | |
if test $remove -eq 1 | |
sed -i.tmp "\:^$absolute_path\$: d" "$path_file" | |
else | |
sed -i.tmp '1 a\ | |
'"$absolute_path"' | |
' "$path_file" | |
end | |
rm -f "$path_file.tmp" | |
end | |
return 0 | |
else | |
echo "No virtualenv is active." | |
end | |
end | |
################ | |
# Autocomplete | |
# Based on https://github.com/zmalltalker/fish-nuggets/blob/master/completions/git.fish | |
begin | |
function __vfcompletion_needs_command | |
set cmd (commandline -opc) | |
if test (count $cmd) -eq 1 -a $cmd[1] = 'vf' | |
return 0 | |
end | |
return 1 | |
end | |
function __vfcompletion_using_command | |
set cmd (commandline -opc) | |
if test (count $cmd) -gt 1 | |
if test $argv[1] = $cmd[2] | |
return 0 | |
end | |
end | |
return 1 | |
end | |
# add completion for subcommands | |
for sc in (functions -a | sed -n '/__vf_/{s///g;p;}') | |
set -l helptext (functions "__vf_$sc" | head -n 1 | sed -E "s|.*'(.*)'.*|\1|") | |
complete -x -c vf -n '__vfcompletion_needs_command' -a $sc -d $helptext | |
end | |
complete -x -c vf -n '__vfcompletion_using_command activate' -a "(vf ls)" | |
complete -x -c vf -n '__vfcompletion_using_command rm' -a "(vf ls)" | |
if set -q VIRTUALFISH_COMPAT_ALIASES | |
complete -x -c workon -a "(vf ls)" | |
complete -x -c rmvirtualenv -a "(vf ls)" | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment