Question

I have the following code in my .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

And I have this code in my RPS1 prompt:

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

(For brevity sake I have not shown the code that sets the PR_ colors or determines the virtual environment - both of those work.)

When a new shell is created (new window or new tab in iTerm2) the Ruby information is correct. However if I switch to a project that uses a different Ruby, as determined by the .ruby-version file, the Ruby information displayed in the right prompt does not refresh. If I re-source my .zshrc file the right-prompt does refresh.

Do I need to encase the code that determines the Ruby version in a function? By the way, I do have setopt promptsubst in my .zshrc as well.

What am I missing that is preventing the right-prompt from refreshing when I change directories?

Was it helpful?

Solution

You should not be using this code

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

directly in zshrc: it won’t update ruby_version variable when switching to another project. You can change it to

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
}

and change ${ruby_version} in your prompt to $(ruby_version). Or, if you are sure you don’t need checking this on each prompt (it will slow things down) you can use

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)

, it will update ruby_version only when you change current directory. Also note that your code is misleading: local ruby_version='' that is put directly into zshrc is equivalent to typeset -g ruby_version='' or just plain ruby_version='' which defines global, but not exported variable. There are no file-local variables in zsh (except for autoload files that actually represent functions).

OTHER TIPS

use this one:

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%}'

this will inject the ruby_version variable code into the RPS1

Looks like you need to use the precmd hook which is executed every time you execute commands, like switching folders. Unlike the way you did it, that is only executed once when you start a new instance.

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%}'
}

Make sure to not override this function, create it only if it wasn't created somewhere else. B Because it's very likely that it is already defined somewhere in your .zshrc or other zsh related files, especially if you are using something like oh-my-zsh or something else that shows git (or some other version control) information on the prompt or things like that.

Some more light on the matter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top