Search code examples
shellzshprompt

How to change color of prompt from last exit code in ZSH?


I have this piece of code in my .zshrc:

autoload -U colors && colors

function change_color() {
    if [[ "$?" = 0 ]]; then
    return "green"
  else
    return "red"
  fi
}

PS1="%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[magenta]%}%~%{$fg[red]%}]% %{$fg[$changecolor]%}➜%b "

However, the character stays white, no matter what I do.


Solution

  • As a function, you need to call it, not expand it as a variable. Do that with a command substitution:

    PS1="...%{$fg[\$(changecolor)]%}➜%b "
    

    However, there's a lot of bash-like stuff in this prompt that you can replace with simpler, more robust zsh features. First, %F can be used to change the color directly, without using escape codes stored in an array. (Unlike raw escape codes, and like other zsh-defined escape sequences, %F{...} doesn't need to be wrapped in %{...%}.) Second, there is prompt escape specifically for producing one value or another depending on whether the last exit status was 0 or not.

    PS1='%B%F{red}[%F{yellow}%n%F{green}@%F{blue}%M '
    PS1+='%F{magenta}%~%F{red}] %(?.%F{green}.%F{red})➜%b%f '
    

    %(?.FOO.BAR) expands to FOO if the last command succeeded, BAR otherwise. %f restores the color to the default, regardless of any preceding %F codes.


    %(...) is, in fact, more general than just testing the exit code. ? is just one of 20 or so testable conditions. As a silly example, suppose your birthday is coming up on January 18. Here's an escape to put a cake in your prompt on your birthday.

    %(0D.%(18d.🎂.).)
    

    More information on prompt escape codes can be found in man zshmisc.