virtualenv 名称未显示在 zsh 提示符中

virtualenv name not show in zsh prompt

最近,我尝试了 oh my zsh,在尝试 virtualevn 和 virtualenvwrapper 之前一切看起来都不错。当我激活 virtualenv(例如测试)时,在正常情况下 bash,我会看到 virtualenv 名称如下:

(test)abc@abc:

但是当我切换到 zsh 时,我看不到 virtualenv 名称。尽管如此,我还是在 oh my zsh 的插件中添加了 virtualenv 和 virtualenvwrapper。我还检查了我的 virtualenv 的激活文件,它包含:

f [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then        
    _OLD_VIRTUAL_PS1="$PS1"
    if [ "x" != x ] ; then
        PS1="$PS1"
    else
        PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1"
    fi
        export PS1
fi

是不是因为比较 ["x" != x] return 是真的?

更新: 我试图在激活文件中回显 $PS1,得到了这个:

(test) %{$fg[magenta]%}%n%{$reset_color%}%{$fg[cyan]%}@%{$reset_color%}%{$fg[yellow]%}%m%{$reset_color%}%{$fg[red]%}:%{$reset_color%}%{$fg[cyan]%}%0~%{$reset_color%}%{$fg[red]%}|%{$reset_color%}%{$fg[cyan]%}⇒%{$reset_color%}

$PS1 似乎是正确的,但是当我在终端中回显 $PS1 时,(test) 消失了。似乎 $PS1 被其他东西覆盖了!

找到问题了,是主题问题。我在上面的案例中使用的主题是 pygmalion,它不允许你更改 $PS1。

换成robbyrussell主题后,在terminal里可以换$PS1,但是还是看不到virtualenv的名字。调试了一会儿,发现oh my zsh的virtualenv插件默认是关闭提示的:

# disables prompt mangling in virtual_env/bin/activate
export VIRTUAL_ENV_DISABLE_PROMPT=1

所以只要注释掉virtualenv插件中的那一行,问题就解决了。

最佳解决方案是将以下内容添加到 ~/.zshrc 文件的末尾:

export VIRTUAL_ENV_DISABLE_PROMPT=

这将覆盖 virtualenv.plugin.zsh 中的值 - 无需更改该文件。

~/.zshrc 中执行此操作:

plugins=(virtualenv)

POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status virtualenv)

注意事项:

1 -- 添加该插件以及您拥有的其他插件。

2 -- 我正在使用 POWERLEVEL9K 主题。也许你的主题

按照本指南here

  • 先在.zshrc文件plugin下添加virtualenv依赖 如果这对您不起作用,则意味着您选择的主题(oh-my-zsh 主题之一)在 bash 提示符中不包含 virtualenv 名称,因此请尝试第二步。

  • 转到文件 ~/.oh-my-zsh/themes/YOUR_THEME_NAME.zsh-theme 并将其添加到基本提示中 %{$fg[green]%}$(virtualenv_prompt_info)%{$reset_color%}%

注意virtualenv_prompt_info是在~/.oh-my-zsh/plugins/virtualenv/virtualenv.plugin.zsh中声明的函数名。如果你的插件文件有不同的函数名,那么相应地改变它。

或者您可以在 ~/.zshrc 文件中声明您自己的函数,如此 guide

所示

如果您使用 conda 启动虚拟环境,则环境变量会有所不同。要找出保存您的 virtaulenv 名称的环境的名称,请键入 printenv 并查看输出。对我来说是 CONDA_PROMPT_MODIFIER

知道变量的名称后打开 .zshrc 并添加此函数

function virtualenv_info { [ $CONDA_PROMPT_MODIFIER ] && echo `basename $CONDA_PROMPT_MODIFIER` }

并在其下方添加此行

PROMPT="%{$fg[green]%}$(virtualenv_info)%{$reset_color%}%${PROMPT}"

关闭编辑器并输入source .zshrc

我按照这个 link 让它工作:https://askubuntu.com/a/387098

我在下面复制答案。

如何更改提示在虚拟环境目录中的脚本bin/activate中定义。此文件由 virtualenv 根据模板创建。不幸的是,模板提供的提示修改的唯一方法是在 (env name) 之前或使用 --prompt.

设置的任何内容

要按照你想要的方式修改提示,我建议绕过bin/activate中的提示设置,修改你的主题文件中PROMPT的定义。

首先将以下内容添加到您的.zsh-theme(或.zshrc

export VIRTUAL_ENV_DISABLE_PROMPT=yes

function virtenv_indicator {
    if [[ -z $VIRTUAL_ENV ]] then
        psvar[1]=''
    else
        psvar[1]=${VIRTUAL_ENV##*/}
    fi
}

add-zsh-hook precmd virtenv_indicator

并在PROMPT定义的第二行前加上%(1V.(%1v).)。它应该看起来像这样:

PROMPT='
%(1V.(%1v).)%{$fg_bold[grey]%}[%{$reset_color%}%{$fg_bold[${host_color}]%}%n@%m%{$reset_color%}%{$fg_bold[grey]%}]%{$reset_color%} %{$fg_bold[blue]%}%10c%{$reset_color%} $(git_prompt_info) $(git_remote_status)
%{$fg_bold[cyan]%}❯%{$reset_color%} '

如果你想要一些颜色,你可以添加 %(1V.%{$fs_bold[yellow]%}(%1v)%{$reset_color%}.) 例如。

解释:

每次创建提示之前都会调用

virtenv_indicator。它检查 $VIRTUAL_ENV 是否已设置且不为空。如果是这样,它会将 $psvar 数组的第一个元素设置为 $VIRTUAL_ENV,并删除之前的所有内容,包括最后一个 /(类似于 basename $VIRTUAL_ENV,但更便宜)

PROMPT 的定义中 %(1V.(%1v).) 检查 $psvar 的第一个元素是否设置且不为空 (%(1V.true-text.false-text)) 并添加此元素的内容加上一些括号 ((%1v))

export VIRTUAL_ENV_DISABLE_PROMPT=yes 禁用 bin/activate 脚本的任何提示设置。

我的设置显示 Python 默认 (a.k.a. robbyrussell) 主题的 virtualenv 名称如下。

.zshrc文件中

  1. virtualenv 添加到 plugins

  2. 添加自定义函数:

    function virtualenv_info { 
        [ $VIRTUAL_ENV ] && echo '('`basename $VIRTUAL_ENV`') '
    }
    

导航到您的主题

  1. 我的主题是 zsh 的默认主题:
    $ vim ~/.oh-my-zsh/themes/robbyrussell.zsh-theme
    
  2. 在现有 PROMPT 命令之后立即添加此命令:
    PROMPT+='%{$fg[green]%}$(virtualenv_info)%{$reset_color%}%'
    

终于

$ source ~/.zshrc

PS: 你可以在PROMPT+之前或之后添加你的名字或几个space。

希望对您有所帮助!

如果您使用 Homebrew 安装 Anaconda:

brew tap homebrew/cask-versions 
brew cask install anaconda 

并且您正在使用 POWERLEVEL9K 主题

git clone https://github.com/bhilburn/powerlevel9k.git ~/.oh-my-zsh/custom/themes/powerlevel9k

您需要做的就是将这一行添加到 .zshrc 的末尾:

POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status root_indicator background_jobs history time anaconda)

不需要 virtualenv 插件。

已编辑:

如果您已经为 bash 安装了 conda 并且您得到:

zsh: command not found: conda

运行 这个:

~/anaconda3/bin/conda init zsh

我正在使用 oh-my-zsh pygmalion,这对我有用:

  • 在~/.zshrc

    添加virtualenv插件
  • 打开~/.oh-my-zsh/themes/pygmalion.zsh-theme,修改prompt_pygmalion_precmd函数为:

     prompt_pygmalion_precmd(){
       setopt localoptions extendedglob
    
       local gitinfo=$(git_prompt_info)
       local gitinfo_nocolor=${gitinfo//\%\{[^\}]##\}}
       local exp_nocolor="$(print -P \"$base_prompt_nocolor$gitinfo_nocolor$post_prompt_nocolor\")"
       local prompt_length=${#exp_nocolor}
       local python_venv=$(virtualenv_prompt_info)
    
       PROMPT="${python_venv}${base_prompt}${gitinfo}${post_prompt}"
     }
    

基本上只需将 $(virtualenv_prompt_info) 添加到您的 PROMPT 到您喜欢的任何位置,这里我将其添加到我的 PROMPT 的开头。

如果你使用 zsh 和 pyenv,把这个放到 ~/.zshrc

eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
#export PS1='($(pyenv version-name)) '$PS1

export PYENV_VIRTUALENV_DISABLE_PROMPT=1
export BASE_PROMPT=$PS1
function updatePrompt {
    if [[ "$(pyenv version-name)" != "system" ]]; then
        # the next line should be double quote; single quote would not work for me
        export PS1="($(pyenv version-name)) "$BASE_PROMPT
    else
        export PS1=$BASE_PROMPT
    fi
}
export PROMPT_COMMAND='updatePrompt'
precmd() { eval '$PROMPT_COMMAND' } # this line is necessary for zsh

我也在使用带有 pygmalion 主题的 Oh My Zsh。我必须编辑 pygmalion 脚本以在提示名称之前添加虚拟环境名称。

  • 打开~/.oh-my-zsh/themes/pygmalion.zsh-theme,修改prompt_pygmalion_precmd函数如下:
prompt_pygmalion_precmd(){
  setopt localoptions extendedglob

  local gitinfo=$(git_prompt_info)
  local gitinfo_nocolor=${gitinfo//\%\{[^\}]##\}}
  local exp_nocolor="$(print -P \"$base_prompt_nocolor$gitinfo_nocolor$post_prompt_nocolor\")"
  local prompt_length=${#exp_nocolor}
  local python_venv="($(echo $CONDA_DEFAULT_ENV)) "

  PROMPT="${python_venv}${base_prompt}${gitinfo}${post_prompt}"
}

根据文档,您不需要创建新函数 - 此函数是为您创建的。 https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/virtualenv

但是您仍然需要编辑主题文件,如上所述,只需输入正确的函数名称 - virtualenv_prompt_info:

PROMPT+='%{$fg[绿色]%}$(virtualenv_prompt_info)%{$reset_color%}%'

在尝试了环绕声答案之后,我发现以下最适合我的用例。这会在您每次更改目录并使用正确的 venv 信息设置提示时检查 $VIRTUAL_ENV_PROMPT 和 $VIRTUAL_ENV 变量。

DEFAULT_PROMPT=$PROMPT

function cd() {
  builtin cd "$@"

  if [[ -n "$VIRTUAL_ENV_PROMPT" ]] ; then
      PROMPT="$VIRTUAL_ENV_PROMPT$DEFAULT_PROMPT"
  elif [[ -n "$VIRTUAL_ENV" ]] ; then
      PROMPT="(`basename $VIRTUAL_ENV`) $DEFAULT_PROMPT"
  else
      PROMPT=$DEFAULT_PROMPT
  fi
}