How do I change the default virtualenv prompt?
Question:
How do you change the default Virtualenvwrapper prompt? By default, working on a particular virtual environment with a command like workon <_name_of_env_>
prepends the name of the virtualenv to your prompt. This may work poorly if you’re not using a default command prompt.
Answers:
By default, when you switch into a virtualenv with the command “workon < name_of_env >”, virtualenvwrapper prepends a string along the lines of “(< name_of_env >) ” to your command prompt. The problem is that I set my Bash prompt with the lines:
PROMPT_COLOR1='0;36m'
PROMPT_COLOR2='1;34m'
PS1='n[ 33[$PROMPT_COLOR1](t)[ 33[$PROMPT_COLOR2] u @ w n[ 33[$PROMPT_COLOR1]$ [ 33[0;39m]'
Which yields a command prompt along the lines of:
< old_line >
(19:11:05) kevin @ ~/research
$
Switching into a new virtual environment with “workon < name_of_env >” turned the command prompt to something like:
< old_line >
(< name_of_env >)
(19:11:05) kevin @ ~/research
$
Which was more cluttered than I wanted and the wrong color to boot. I was hoping for something like:
< old_line >
(< name_of_env >) (19:11:05) kevin @ ~/research
$
Ian Bicking has previously pointed out that virtualenvwrapper’s hooks were the solution but I figured I’d post my actual code to maybe save someone else a minute down the line.
I simply edited the file $WORKON_HOME/postactivate to include these lines:
# color virtualenv name properly and put it after the n if there is one at the start of the prompt
if [ ${_OLD_VIRTUAL_PS1:0:2} == 'n' ]; then
PS1="n[ 33[$PROMPT_COLOR1](`basename "$VIRTUAL_ENV"`) ${_OLD_VIRTUAL_PS1:2:${#_OLD_VIRTUAL_PS1}}"
else
PS1="[ 33[$PROMPT_COLOR1](`basename "$VIRTUAL_ENV"`) $_OLD_VIRTUAL_PS1 "
fi
and voila! The color and location are correct and it even works when you switch directly from one virtual environment to another (which I hadn’t expected).
If you are working on a custom PS1 (as I when found out this issue), I recommend you to disable prompt change, use export VIRTUAL_ENV_DISABLE_PROMPT=1
(see virtualenv docs), and make your own virtualenv prompt in order to add to your PS1.
See this snippet that I’ve used:
function virtualenv_info(){
# Get Virtual Env
if [[ -n "$VIRTUAL_ENV" ]]; then
# Strip out the path and just leave the env name
venv="${VIRTUAL_ENV##*/}"
else
# In case you don't have one activated
venv=''
fi
[[ -n "$venv" ]] && echo "(venv:$venv) "
}
# disable the default virtualenv prompt change
export VIRTUAL_ENV_DISABLE_PROMPT=1
VENV="$(virtualenv_info)";
# the '...' are for irrelevant info here.
export PS1="... ${VENV} ..."
I think the following is the simplest solution:
Add to ~/.virtualenvs/postactivate
the following:
PS1="[e[1;33;45m] (`basename "$VIRTUAL_ENV"`) [e[0m]$_OLD_VIRTUAL_PS1"
Taken from: http://wiki.hackzine.org/development/python/virtualenv.html
I adopted @ivanalejandro0’s solution by slimming down the function a bit:
function virtualenv_info {
# Get Virtual Env
if [[ -n "$VIRTUAL_ENV" ]]; then
# Strip out the path and just leave the env name
echo "(venv:${VIRTUAL_ENV##*/})"
fi
Or if you’re feeling really hacky:
function virtualenv_info {
[[ -n "$VIRTUAL_ENV" ]] && echo "(venv:${VIRTUAL_ENV##*/})"
}
One could reduce the function in @ivanalejandro0’s solution by using an “alternate value” parameter expansion. Also, as @crimson-egret commented, the call can be right in PS1 without the VENV intermediate:
function __virtualenv_ps1 {
echo "${VIRTUAL_ENV:+(venv:${VIRTUAL_ENV##*/})}"
}
# disable the default virtualenv prompt change
export VIRTUAL_ENV_DISABLE_PROMPT=1
# the '...' are for irrelevant info here.
export PS1="... $(__virtualenv_ps1) ..."
How do you change the default Virtualenvwrapper prompt? By default, working on a particular virtual environment with a command like workon <_name_of_env_>
prepends the name of the virtualenv to your prompt. This may work poorly if you’re not using a default command prompt.
By default, when you switch into a virtualenv with the command “workon < name_of_env >”, virtualenvwrapper prepends a string along the lines of “(< name_of_env >) ” to your command prompt. The problem is that I set my Bash prompt with the lines:
PROMPT_COLOR1='0;36m'
PROMPT_COLOR2='1;34m'
PS1='n[ 33[$PROMPT_COLOR1](t)[ 33[$PROMPT_COLOR2] u @ w n[ 33[$PROMPT_COLOR1]$ [ 33[0;39m]'
Which yields a command prompt along the lines of:
< old_line >
(19:11:05) kevin @ ~/research
$
Switching into a new virtual environment with “workon < name_of_env >” turned the command prompt to something like:
< old_line >
(< name_of_env >)
(19:11:05) kevin @ ~/research
$
Which was more cluttered than I wanted and the wrong color to boot. I was hoping for something like:
< old_line >
(< name_of_env >) (19:11:05) kevin @ ~/research
$
Ian Bicking has previously pointed out that virtualenvwrapper’s hooks were the solution but I figured I’d post my actual code to maybe save someone else a minute down the line.
I simply edited the file $WORKON_HOME/postactivate to include these lines:
# color virtualenv name properly and put it after the n if there is one at the start of the prompt
if [ ${_OLD_VIRTUAL_PS1:0:2} == 'n' ]; then
PS1="n[ 33[$PROMPT_COLOR1](`basename "$VIRTUAL_ENV"`) ${_OLD_VIRTUAL_PS1:2:${#_OLD_VIRTUAL_PS1}}"
else
PS1="[ 33[$PROMPT_COLOR1](`basename "$VIRTUAL_ENV"`) $_OLD_VIRTUAL_PS1 "
fi
and voila! The color and location are correct and it even works when you switch directly from one virtual environment to another (which I hadn’t expected).
If you are working on a custom PS1 (as I when found out this issue), I recommend you to disable prompt change, use export VIRTUAL_ENV_DISABLE_PROMPT=1
(see virtualenv docs), and make your own virtualenv prompt in order to add to your PS1.
See this snippet that I’ve used:
function virtualenv_info(){
# Get Virtual Env
if [[ -n "$VIRTUAL_ENV" ]]; then
# Strip out the path and just leave the env name
venv="${VIRTUAL_ENV##*/}"
else
# In case you don't have one activated
venv=''
fi
[[ -n "$venv" ]] && echo "(venv:$venv) "
}
# disable the default virtualenv prompt change
export VIRTUAL_ENV_DISABLE_PROMPT=1
VENV="$(virtualenv_info)";
# the '...' are for irrelevant info here.
export PS1="... ${VENV} ..."
I think the following is the simplest solution:
Add to ~/.virtualenvs/postactivate
the following:
PS1="[e[1;33;45m] (`basename "$VIRTUAL_ENV"`) [e[0m]$_OLD_VIRTUAL_PS1"
Taken from: http://wiki.hackzine.org/development/python/virtualenv.html
I adopted @ivanalejandro0’s solution by slimming down the function a bit:
function virtualenv_info {
# Get Virtual Env
if [[ -n "$VIRTUAL_ENV" ]]; then
# Strip out the path and just leave the env name
echo "(venv:${VIRTUAL_ENV##*/})"
fi
Or if you’re feeling really hacky:
function virtualenv_info {
[[ -n "$VIRTUAL_ENV" ]] && echo "(venv:${VIRTUAL_ENV##*/})"
}
One could reduce the function in @ivanalejandro0’s solution by using an “alternate value” parameter expansion. Also, as @crimson-egret commented, the call can be right in PS1 without the VENV intermediate:
function __virtualenv_ps1 {
echo "${VIRTUAL_ENV:+(venv:${VIRTUAL_ENV##*/})}"
}
# disable the default virtualenv prompt change
export VIRTUAL_ENV_DISABLE_PROMPT=1
# the '...' are for irrelevant info here.
export PS1="... $(__virtualenv_ps1) ..."