1

I'm modifying the intika2 theme in oh-my-zsh to add the current pyenv setting to my prompt. OMZ includes a pyenv_prompt_info command & I added it to the LEFTINFOS variable in the intika2 theme to do this. This provides the correct pyenv version whenever the .zshrc file is sourced, but not on subsequent prompts after changing the pyenv version.

Minimal version of the proposed theme modification:

function prompt_char {  
    if [ $UID -eq 0 ]; then echo "#"; else echo $; fi
}

LEFTINFOS="$FG[gray][pyenv=$(pyenv_prompt_info)] [%~] %{$reset_color%}"
PROMPT='
╭─$LEFTINFOS
╰─$(prompt_char)%{$reset_color%} '

Note that LEFTINFOS was defined in the intika2 theme, not something I added.

This gets me: Incorrect prompt updates

If I change PROMPT to

PROMPT='
╭─$FG[gray][pyenv=$(pyenv_prompt_info)] [%~] %{$reset_color%}
╰─$(prompt_char)%{$reset_color%} '

then I get the behavior I expect. desired behavior

I've confirmed that prompt_subst is set. I've tried various tweaks to LEFTINFOS definition, such as %{$(pyenve_prompt_info%), without success. I've looked at this

The fix, i.e. replacing LEFTINFOS, is easy enough; I want to understand why the command substitution is not working.

2
  • See %(#.#.$) in prompt expansion that expands to # if you're superuser (EUID=0) and $ if not. uid can change at runtime in zsh if you assign to EUID/UID/USERNAME special variables. Jan 10, 2023 at 16:09
  • Prompt expansion can do colouring : %F{#808080}gray test%f including on terminals that don't support direct colours if you load the zsh/nearcolor module. Jan 10, 2023 at 16:14

1 Answer 1

1

You have the wrong quotes. The definition of LEFTINFOS uses double quotes, so what's inside the quotes is evaluated when the definition is evaluated, instead of when the prompt is calculated. You need to arrange for the value of PROMPT to contain the string $(pyenv_prompt_info). So define LEFTINFOS to contain $(pyenv_prompt_info), using single quotes so that $… inside isn't expanded. Conversely, the value of PROMPT needs to contain the value of LEFTINFOS, not the string $LEFTINFOS (otherwise your prompt would contain $(pyenv_prompt_info) instead of the result of expanding it). So use double quotes when defining it.

For the other variables, it probably doesn't matter much, but if you want to be able to tweak colors during a session, they also need to be expanded during prompt calculation and not before.

LEFTINFOS='$FG[gray][pyenv=$(pyenv_prompt_info)] [%~] %{$reset_color%}'
PROMPT="
╭─$LEFTINFOS
╰─$(prompt_char)%{$reset_color%} "

Also, as presented here, $(prompt_char) is a fancy and slow way of writing %(!:#:\$), except that %(!…) uses the effective UID, which makes a difference only if you temporary drop privileges from a root shell.

Using psvar and %1v, %2v, … can make prompt definitions easier to read and write, but I don't know if oh-my-zsh interferes with that.

1
  • Super! Thanks for the clarification. I had also tried single quoting LEFTINFOS, but not double quoting PROMPT. I knew this was substitution pilot error.
    – Todd Vanyo
    Jan 9, 2023 at 1:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .