kevin
kevin

Reputation: 3168

How do I change the default virtualenv prompt?

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.

Upvotes: 68

Views: 37586

Answers (7)

Uraxii
Uraxii

Reputation: 3

Posting a response, because it seems the solution is much easier now. Custom prompts are set via a prompt variable in the file pyvenv.cfg. You may need to add this variable to the file. It was not there by default for me.

pyvenv.cfg

# Example data. Your values will look different here.
home = ...\Python\Python312
include-system-site-packages = false
version = 3.12.7
executable = ...\Python\Python312\python.exe
command = ...\Python\Python312\python.exe -m venv ...\venv

# Add prompt var to file. Set to whatever value you like.
prompt = MyCustomPrompt

After setting the prompt value, the custom text is prepended to your regular system prompt. If you want to customize it further, I'd recommend modifying the activate script.

(MyCustomPrompt)~$:

Upvotes: 0

Robert
Robert

Reputation: 2198

Now the time comes to 2023. There's an easy way to set/change the default prompt in Python3 by

--prompt PROMPT       Provides an alternative prompt prefix for this
                        environment.

For example,

python3 -m venv --prompt "the prompt you want" "the-path-to-your-env-dir"

Upvotes: 8

TomB
TomB

Reputation: 71

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) ..."

Upvotes: 6

ivanalejandro0
ivanalejandro0

Reputation: 1761

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} ..."

Upvotes: 102

dtk
dtk

Reputation: 2526

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##*/})"
}

Upvotes: 6

Dror
Dror

Reputation: 13051

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

Upvotes: 9

kevin
kevin

Reputation: 3168

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\[\033[$PROMPT_COLOR1\](\t)\[\033[$PROMPT_COLOR2\] \u @ \w \n\[\033[$PROMPT_COLOR1\]$ \[\033[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\[\033[$PROMPT_COLOR1\](`basename \"$VIRTUAL_ENV\"`) ${_OLD_VIRTUAL_PS1:2:${#_OLD_VIRTUAL_PS1}}"
else
    PS1="\[\033[$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).

Upvotes: 10

Related Questions