Search code examples
anacondaenvironment-variableszshcommand-promptzshrc

Environment Variable is read incorrectly in .zshrc file


Recently I updated my MacOS to Catalina. Now the default shell is zsh, i could like revert it to bash but I thought to play along. Now I came across a problem while wanting to customize my Command Prompt.

In $HOME/.zshenv I declared;

export ZDOTDIR="$XDG_CONFIG_HOME/zsh"

in that folder I have the .zshrc file. It contains the part of the conda initialization.

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/finn/anaconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/Users/finn/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/Users/finn/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/Users/finn/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

But more importantly I source this prompt.sh file:

function promptcmd () {
    local blue="{33}";
    local cyan="{87}";
    local orange="{160}";
    local pink="{200}";
    local white="{15}";
    local yellow="{226}";

    # Set the terminal title and prompt.
    PROMPT=""; # working directory base name
    PROMPT+="%B"; # all bold

    PROMPT+="%F${pink}%n%f"; # username
    PROMPT+="%F${yellow}@%f"; # at
    PROMPT+="%F${orange}%M%f"; # hostname
    PROMPT+="%F${white} in %f"; # in
    PROMPT+="%F${blue}%~%f"; # directory
    PROMPT+="%F${white} \$ %f%b";

    if [[ $CONDA_DEFAULT_ENV != "base" ]]; then
        RPROMPT="%F${cyan}($CONDA_DEFAULT_ENV)%f";
    fi;
}

promptcmd

The PROMPT part works perfectly fine. But the part where I'd like to display my Anaconda Environment on the right hand side, it doesn't. The problem is that the Environment Variable $CONDA_DEFAULT_ENV is read incorrectly. If I were to just display the Variable in the prompt (without the if statement) I see how it always stays (base), even though I typed conda activate my_env, then entered echo $CONDA_DEFAULT_ENV and it returned my_env.

Is .zshrc not rereading the Environment Variables?

EDIT:

You are only calling promptcmd once; you want to define precmd instead (or all promptcmd from inside promptcmd) so that your prompt is redefined just before it is displayed every time.

chedner's commment helped; Just by renaming the promptcmd function, it at first somehow worked. The RPROMPT is empty until I conda activate my_env, then it says (my_env). But then some weird behavior followed, which I can only show you:

Example Terminal Output


Solution

  • There were two parts missing before the EDIT.

    I found out the first of these thanks to chepner's comment, which quotes:

    You are only calling promptcmd once; you want to define precmd instead [...] so that your prompt is redefined just before it is displayed every time.

    Apparently there is this naming convention, which causes my function promptcmd to only be executed once, when opening a new Terminal window. If you rename it to precmd it is executed for every prompt.

    Then I had the issue displayed in the EDIT of the question. It worked every time a new conda env was activated, because $CONDA_DEFAULT_ENV, was different from base which caused the if clause to execute and set RPROMPT to "%F${cyan}($CONDA_DEFAULT_ENV)%f". Now it never vanished from the right side of my prompt when I entered conda deactivate and $CONDA_DEFAULT_ENV was back to base. After I learned a way to debug more easily thanks to user1934428's comment:

    If you have the necessary permissions, I would put a set -x at the first command in /etc/zshenv, because this is where execution starts. Of course this will affect all users. If you don't want to do this, put it at the top of your ~/.zshenv.

    Then, I quickly realized, that $RPROMPT was simply not reset before my custom prompt function precmd, which I naively asssumed. So what solved the last part, was a simple RPROMPT="" before the if, that sets RPROMPT when $CONDA_DEFAULT_ENV is not base.