In Python, it’s common to create a separate virtual environment for each project. This is A cooperatively isolated runtime environment that allows Python users and applications to install and upgrade Python distribution packages without interfering with the behaviour of other Python applications running on the same system. Once a virtual environment is active, your shell’s prompt should display its name. Here’s an example of how that looks in Zsh on macOS. Note the (.venv) at the beginning of the prompt; this means the active virtual environment lives inside the .venv directory, relative to the current directory.

A screenshot of the Terminal app on macOS. The shell prompt begins with the name of the virtual environment in parentheses.

In January, one of my Multiverse apprentices reported that this wasn’t working for them with Oh My Zsh. We tried the suggestions offered in various posts on Stack Overflow, but nothing worked. I still haven’t figured out why it doesn’t work for my apprentice by default (it’s probably something unique to their system), but I have figured out how to make it work.

The virtualenv plugin

Oh My Zsh comes with a virtualenv plugin. This should be in the ~/.oh-my-zsh/plugins/virtualenv directory. There are two files: virtualenv.plugin.zsh, which is the plugin, and README.md, which contains the following instructions.

# virtualenv

The plugin displays information of the created virtual container and allows background theming.

To use it, add `virtualenv` to the plugins array of your zshrc file:

```
plugins=(... virtualenv)
```


The plugin creates a `virtualenv_prompt_info` function that you can use in your theme, which displays
the basename of the current `$VIRTUAL_ENV`. It uses two variables to control how that is shown:

- `ZSH_THEME_VIRTUALENV_PREFIX`: sets the prefix of the VIRTUAL_ENV. Defaults to `[`.

- `ZSH_THEME_VIRTUALENV_SUFFIX`: sets the suffix of the VIRTUAL_ENV. Defaults to `]`.

These instructions tell you that you need to:

  1. Add virtualenv to the plugins array in your ~/.zshrc file.
  2. Use the virtualenv_prompt_info function in your theme file.
  3. Optionally set the ZSH_THEME_VIRTUALENV_PREFIX and ZSH_THEME_VIRTUALENV_SUFFIX variables in your theme file.

The robbyrussell theme

My apprentice was using the default robbyrussell theme, so their theme file was located at ~/.oh-my-zsh/themes/robbyrussell.zsh-theme. The default contents of that file are as follows. Notice that this theme already uses the git_prompt_info function provided by the git-prompt plugin and sets some variables to control its appearance.

PROMPT="%(?:%{$fg_bold[green]%}%1{➜%} :%{$fg_bold[red]%}%1{➜%} ) %{$fg[cyan]%}%c%{$reset_color%}"
PROMPT+=' $(git_prompt_info)'

ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}%1{✗%}"
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"

You will need to do something similar to add the virtual environment name to the prompt. You can add it wherever you like, but for consistency with the default behaviour, I suggest that you start the prompt with it. You can also set the ZSH_THEME_VIRTUALENV_PREFIX and ZSH_THEME_VIRTUALENV_SUFFIX variables to wrap the virtual environment name in parentheses instead of square brackets.

PROMPT='$(virtualenv_prompt_info) '
PROMPT+="%(?:%{$fg_bold[green]%}%1{➜%} :%{$fg_bold[red]%}%1{➜%} ) %{$fg[cyan]%}%c%{$reset_color%}"
PROMPT+=' $(git_prompt_info)'

ZSH_THEME_VIRTUALENV_PREFIX="("
ZSH_THEME_VIRTUALENV_SUFFIX=")"

ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}%1{✗%}"
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"

Note that the first line uses the = operator to initialize the PROMPT variable while the second and third lines use the += operator for concatenation.

It’s important that the first and third lines use single quotes to prevent immediate evaluation of the plugin functions. This is because you want the command substitution to happen dynamically when the prompt is displayed, not statically at the time of assignment.

After restarting your shell, the virtual environment name should be displayed in parentheses at the beginning of the prompt:

A screenshot of the Terminal app on macOS with Oh My Zsh installed. The shell prompt begins with the name of the virtual environment in parentheses.

Summary

Once a virtual environment for Python is active, your shell’s prompt should display its name by default. For whatever reason, this might not work for you. To make it work with Oh My Zsh, you need to:

  1. Add virtualenv to the plugins array in your ~/.zshrc file.
  2. Use the virtualenv_prompt_info function in your theme file.
  3. Optionally set the ZSH_THEME_VIRTUALENV_PREFIX and ZSH_THEME_VIRTUALENV_SUFFIX variables in your theme file.