【问题标题】:rbenv version display in zsh right-prompt not refreshingrbenv版本在zsh中显示右键提示不刷新
【发布时间】:2013-01-16 02:39:18
【问题描述】:

我的 .zshrc 中有以下代码:

local ruby_version=''
if which rvm-prompt &> /dev/null; then
  ruby_version="$(rvm-prompt i v g)"
else
  if which rbenv &> /dev/null; then
    ruby_version="$(rbenv version | sed -e "s/ (set.*$//")"
  fi
fi

我的 RPS1 提示符中有此代码:

RPS1='${PR_GREEN}$(virtualenv_info)%{$reset_color%} ${PR_RED}${ruby_version}%{$reset_color%}'

(为简洁起见,我没有展示设置 PR_ 颜色或确定虚拟环境的代码 - 两者都有效。)

当一个新的 shell 被创建(新窗口或 iTerm2 中的新标签)时,Ruby 信息是正确的。但是,如果我切换到使用不同 Ruby 的项目(由 .ruby-version 文件确定),则右侧提示中显示的 Ruby 信息不会刷新。如果我重新获取我的 .zshrc 文件,则右侧提示会刷新。

我是否需要将确定 Ruby 版本的代码封装在一个函数中?顺便说一句,我的 .zshrc 中也有 setopt promptsubst

当我更改目录时,我错过了什么会阻止右提示刷新?

【问题讨论】:

  • 如果我用单引号括住$(rbenv version | see -e "s/ (set.$//") 行,那么我会在右侧提示符中看到该字符串。当该行用双引号括起来时,如原始问题所示,那么我只有在采购~/.zshrc 之后才能看到当前的 Ruby。

标签: rvm zsh rbenv zshrc


【解决方案1】:

使用这个:

export ruby_version
if
  which rvm-prompt &> /dev/null
then
  ruby_version='$(rvm-prompt i v g)'
elif
  which rbenv &> /dev/null
then
  ruby_version='$(rbenv version | sed -e "s/ (set.*$//")'
else
  ruby_version=''
fi

RPS1='${PR_GREEN}$(virtualenv_info)%{$reset_color%} ${PR_RED}'"${ruby_version}"'%{$reset_color%}'

这会将ruby_version 变量代码注入RPS1

【讨论】:

  • 使用上面的代码,我的 RPROMPT 显示单引号内的文本。就像这样,$(rbenv version | sed -e "s/ (set.*$//")。将单引号更改为双引号会使我回到原来的不正确行为。
【解决方案2】:

看起来您需要使用每次执行命令时都会执行的precmd 挂钩,例如切换文件夹。与您执行此操作的方式不同,它仅在您启动新实例时执行一次。

precmd () {

  local ruby_version=''
  if which rvm-prompt &> /dev/null; then
    ruby_version="$(rvm-prompt i v g)"
  else
    if which rbenv &> /dev/null; then
      ruby_version="$(rbenv version | sed -e "s/ (set.*$//")"
    fi
  fi

  #you can use RPROMPT
  RPS1='${PR_GREEN}$(virtualenv_info)%{$reset_color%} ${PR_RED}${ruby_version}%{$reset_color%}'
}

确保不要覆盖此函数,仅当它不是在其他地方创建时才创建它。 B 因为它很可能已经在您的 .zshrc 或其他 zsh 相关文件中的某处定义,特别是如果您使用类似 oh-my-zsh 或其他显示 git(或某些其他版本控制)提示或类似的信息。

Some more light on the matter.

【讨论】:

  • 在验证我的 zsh 配置中没有其他地方有 precmd 之后,我用 precmd 包装了 RPROMPT。我正在使用 on-my-zsh,但发现它很慢,因此我现在正在滚动我自己的配置。 RPROMPT 的行为没有变化。我将不得不继续阅读 zsh 手册。
【解决方案3】:

您不应该使用此代码

local ruby_version=''
if which rvm-prompt &> /dev/null; then
  ruby_version="$(rvm-prompt i v g)"
else
  if which rbenv &> /dev/null; then
    ruby_version="$(rbenv version | sed -e "s/ (set.*$//")"
  fi
fi

直接在 zshrc 中:切换到另一个项目时不会更新 ruby​​_version 变量。你可以改成

function ruby_version()
{
    if which rvm-prompt &> /dev/null; then
      rvm-prompt i v g
    else
      if which rbenv &> /dev/null; then
        rbenv version | sed -e "s/ (set.*$//"
      fi
    fi
}

并将提示符中的${ruby_version} 更改为$(ruby_version)。或者,如果您确定不需要在每次提示时都检查此项(它会减慢速度),您可以使用

function _update_ruby_version()
{
    typeset -g ruby_version=''
    if which rvm-prompt &> /dev/null; then
      ruby_version="$(rvm-prompt i v g)"
      rvm-prompt i v g
    else
      if which rbenv &> /dev/null; then
        ruby_version="$(rbenv version | sed -e "s/ (set.*$//")"
      fi
    fi
}
chpwd_functions+=(_update_ruby_version)

,它只会在你改变当前目录时更新 ruby​​_version。另请注意,您的代码具有误导性:直接放入 zshrc 的 local ruby_version='' 等效于 typeset -g ruby_version='' 或只是定义全局变量但未导出变量的普通 ruby_version=''。 zsh 中没有文件局部变量(除了实际表示函数的自动加载文件)。

【讨论】:

  • 这两种变体都能完美运行。谢谢你。我已经实现了两者中的第二个,使用chpwd_functions 行仅在目录更改时测试Ruby 版本。唯一可能出现问题的是设置一个具有本地 Ruby 的新项目。在发出rbenv local 命令来定义该Ruby 之后,我将不得不离开密码并返回以重置提示- 一个小细节。再次感谢。
  • @MarkNichols 您不需要更改目录两次。只需使用cd .:它会触发chpwd 挂钩,但实际上并不会更改目录。
  • 您不需要运行 sed。 rbenv 有一个仅针对版本的命令。只要你 rbenv 版本名称,你就会得到你正在寻找的版本。
  • @Fa11enAngel 我的系统上没有 rbenv,我对 ruby​​ 开发几乎一无所知,只是从问题中复制了代码。不会编辑帖子,因为 OP 可能有使用 sed 的原因:即 rbenv 的旧版本不支持 version-name
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 2013-04-25
相关资源
最近更新 更多