【问题标题】:Seeking better virtualenv/rvm/zsh conditional integration寻求更好的 virtualenv/rvm/zsh 条件集成
【发布时间】:2013-03-10 19:43:39
【问题描述】:

tldr:我希望zsh 忽略 rvm 报告系统 ruby​​,仅在实际使用 rvm 时显示它。

一段时间以来,我一直在使用 zsh 和出色的 oh-my-zsh 扩展。我的提示看起来像这样,oh-my-zsh 中包含 gnzh 主题:

╭─emergent@elysian ~/devel/octopress ‹ruby-1.9.3› ‹source*› 
╰─➤ 

注意‹ruby-1.9.3› ‹source*› - 当然是zsh 主题在做一些事情,以便用rvm 正在使用的版本以及git repo 的当前分支来整理我。

我也一直在尝试使用virtualenvwrapper 插件和a few tweaks within virtualenvwrapper itself in order to avoid it simply prepending (virtualenv) at the start of my $PROMPT 让这个与python 的virtualenv 一起工作。

我喜欢这个,因为它只在我将目录更改为 virtualenv 并激活它时显示一个指示(virtualenvwrapper/zsh 自动为我做)。但是,当我将内容转换为 virtualenv 并且路径名开始变长时,这并不能很好地工作。例如:

╭─emergent@elysian ~PROJECT_HOME/djangotutorial/mysite/polls ‹djangotutorial› ‹system› ‹tu
torial02*›
╰─➤

我的终端只有 88 个字符宽,因此,我的提示主题(包括 virtualenvwrapperrvmgit 信息)分布在 3 行中。

我一直在尝试的解决方案是仅在我实际激活rvm ruby 时才显示rvm 指示符。我发现自己从来没有同时使用这两者,并且在我的每条提示行中附加‹system› 似乎最终是多余的。

这是我尝试修改我的.zsh-theme 以实现此目的:

local rvm_ruby=''
# Tests for existence of RVM
if which rvm-prompt &> /dev/null; then
  # !!! THIS IS THE EDIT TO THE THEME I'M ATTEMPTING: !!!
  # Tests if it's using the system ruby and only displays when RVM is
  # actually being used.
  if [ $(rvm-prompt i v g s) != "system" ]; then
    rvm_ruby='%{$PR_RED%}‹$(rvm-prompt i v g s)›%{$PR_NO_COLOR%}'
  fi
else
  if which rbenv &> /dev/null; then
    rvm_ruby='%{$PR_RED%}‹$(rbenv version | sed -e "s/ (set.*$//")›%{$PR_NO_COLOR%}'
  fi
fi
local git_branch='$(git_prompt_info)%{$PR_NO_COLOR%}'

#PROMPT="${user_host} ${current_dir} ${rvm_ruby} ${git_branch}$PR_PROMPT "
PROMPT="╭─${user_host} ${current_dir} ${rvm_ruby} ${git_branch}
╰─$PR_PROMPT "

但是,它根本没有做任何事情 --- 我在此编辑之前和之后看不到任何区别。我确保我是sourceing ~/.zshrc。我在一个较小的脚本中测试了条件评估,它似乎成功了:

if [ $(rvm-prompt i v g s) != "system" ]; then
  echo $(rvm-prompt i v g s)
fi

╭─emergent@elysian ~/devel/shellscripts ‹system› 
╰─➤  ./test.sh
╭─emergent@elysian ~/devel/shellscripts ‹system› 
╰─➤  rvm use ruby-1.9.3
Using /home/emergent/.rvm/gems/ruby-1.9.3-p392
╭─emergent@elysian ~/devel/shellscripts ‹ruby-1.9.3› 
╰─➤  ./test.sh         
ruby-1.9.3

任何在处理 shell 方面更有经验的人对我在这里可以做得更好有什么想法吗?即使您的建议是告诉我为了提高实用性和生产力而做一些与我现在完全不同的事情,我也很乐意听到它。提前干杯和感谢!

【问题讨论】:

  • 您看到的箭头是 oh-my-zsh 附带的,尽管这正是我的 linux 机器上终端的样子。在 OSX 上,我看起来更像这样,因为 OSX 上的终端似乎更好地实现了 unicode。想象一下 ~ 之后的换行符:@Ds-MacBook.local ~ ⤷
  • 如果您希望得到解答,我建议您使用 TL;DR。
  • 感谢您的建议,我知道这并不是我要说的最简洁的解释。

标签: ruby rvm zsh


【解决方案1】:

你有这个:

if which rvm-prompt &> /dev/null; then
  if [ $(rvm-prompt i v g s) != "system" ]; then
    rvm_ruby='%{$PR_RED%}‹$(rvm-prompt i v g s)›%{$PR_NO_COLOR%}'
  fi
else
  # We don't have `rvm-prompt`, try using `rbenv` instead.
fi

让我们看看这实际上在做什么。当你打开一个新终端时,zsh 会加载一堆文件,包括~/.zshrc。在您的 ~/.zshrc 中,您是 sourceing theme。因此,当zsh 加载时,它会贯穿您所做的编辑。

它首先会检查是否可以使用zsh [内置] which 找到rvm-prompt。它通过检查whichreturn code 来做到这一点(如果0,继续)。 (找不到rvm-prompt 是一个不同的问题,与这个答案没有真正的关系)。

如果我们确实找到rvm-prompt,然后使用您的编辑检查rvm-prompt i v g s 的输出是否为system。不是,所以我们将$rvm_ruby 设置为包含对rvm-prompt 的调用

然后,zsh 继续加载主题,最后完成并将$PROMPT 设置为一堆东西,包括对rvm-prompt 的调用。记住zsh 确实重新检查主题逻辑非常有用! (这就是为什么我们需要在编辑后source ~/path/to/theme)!

那么问题是什么?如果rvm-prompt 没有说system 在shell 启动时,我们会在提示符的剩余会话中使用rvm-prompt 的输出。 (如果rvm-prompt 系统,我们将不会在提示中显示任何rvm 指示符...因为rvm_ruby 留空!)。

现在我们了解了正在发生的事情,我们可以着手修复它。我能想到两种方法。

1。从提示中去掉system这个词:

if which rvm-prompt &> /dev/null; then
  rvm_ruby='%{$PR_RED%}‹$(rvm-prompt i v g s | sed -e "s/system//")›%{$PR_NO_COLOR%}'
else
  # We don't have `rvm-prompt`, try using `rbenv` instead.
fi

这可行,但当rvm-promptsystem 时,会在提示中显示(红色)<>

╭─@charmander.local ~ ‹ruby-1.9.3›
╰─ rvm default
╭─@charmander.local ~ ‹ruby-1.9.3›
╰─ rvm use system
Now using system ruby.
╭─@charmander.local ~ ‹›
╰─

您可能会发现这很有用。我想这会让我很烦。

2。使用更聪明的$PROMPT:写一个函数。

在你的theme:

function current_rvm() {
  if which rvm-prompt &> /dev/null; then
    if [ $(rvm-prompt i v g s) != "system" ]; then
      # The double quotes make it work, single quotes do not work.
      echo "%{$PR_RED%}‹$(rvm-prompt i v g s)›%{$PR_NO_COLOR%}"
    else
      # `rvm-prompt` is `system`
      echo ''
    fi
  else
    # We don't have `rvm-prompt`, try using `rbenv` instead.
  fi
}
local rvm_ruby='$(current_rvm)'

这应该很适合你:

╭─@charmander.local ~ ‹ruby-1.9.3›
╰─ rvm use system
Now using system ruby.
╭─@charmander.local ~
╰─ rvm use default
Using /Users/simont/.rvm/gems/ruby-1.9.3-p362
╭─@charmander.local ~ ‹ruby-1.9.3›
╰─

【讨论】:

  • 正确!我一直在玩弄某种功能,但没有得到任何结果,但我知道这是正确的方法。感谢您提出解决方案:)
  • 我添加了一个小编辑——在 current_rvm() 的回显返回上,如果它没有被封装在双引号中,它会给我一个类似于emergent@elysian ~/devel/ 的提示octopress $PR_RED‹$(rvm-prompt i v g s)›$PR_NO_COLOR‹source›.更改 echo 语句的引号可以使事情正常进行。
猜你喜欢
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 2011-06-12
相关资源
最近更新 更多