Search code examples
gitcolorszshprompt

How to colour git branch name in zsh prompt


I have the following set in my .zshrc

autoload -Uz add-zsh-hook vcs_info
setopt prompt_subst
add-zsh-hook precmd vcs_info

zstyle ':vcs_info:git:*' formats '%b'

and this in my custom zsh theme :

vcs_info_wrapper() {
  vcs_info
  if [[ "${vcs_info_msg_0_}" == "master" ]]; then
    echo "%{$FG[196]%}"
  else
    echo "%{$fg[cyan]%}"
  fi
}

PROMPT=$'%B%{$FG[039]%}%n%b%{$fg_bold[white]%}@%m%{$FG[220]%} %{\x1b[3m%}%5~ %{$reset_color%}$(git_prompt_info)%{$reset_color%}%{\x1b[0m%} %(?.%{$fg[white]%}.%{$fg_bold[red]%}[%?])» %{$FG[010]%} ||$(vcs_info_wrapper)${vcs_info_msg_0_}|| '

I have both $(vcs_info_wrapper)${vcs_info_msg_0_} and $(git_prompt_info) to test the colour output. For some reason the former always works and has the correct colour, but the latter doesn't and once the colour changes it never resets. I've basically tried everything at this point. Any ideas are welcome

EDIT:

Thanks @Gairfowl to I have most of it working now with:

function my_precmd {
  vcs_info
  local user='%B%F{#00ACE6}%n%f%b'

  local host='%B%F{white}@%m%f%b'
  local path='%F{#FFD700}%4~%f'
  local rcAndArrow='%(?.%F{white}.%B%F{red}[%?])»%f%b'

  local git2color='cyan'
  local git2=""

  [[ "${vcs_info_msg_0_}" == "master" || "${vcs_info_msg_0_}" == "main" ]] && git2color='196'

  if [[  "${vcs_info_msg_0_}" != "" ]]
    then
      local git2="%B%F{${git2color}}($(git_prompt_info))%f%b "
  fi

  psvar[1]="${user}${host} ${path} ${git2}${rcAndArrow} "

However I don't get any git information from $(git_prompt_info) If I combine it with path (like this local path="%F{#FFD700}%4~%f $(git_prompt_info)") that seems to work.


Solution

  • It's often much easier to read and debug a precmd function than to put everything in the PROMPT variable. Try building your prompt like the function below; you can comment out pieces and isolate the parts you're working on:

    autoload -Uz add-zsh-hook vcs_info
    setopt prompt_subst
    add-zsh-hook precmd my_precmd
    
    zstyle ':vcs_info:git:*' formats '%b'
    
    function my_precmd {
      local theUser='%B%F{39}%n%f%b'
      local theHost='%B%F{white}@%m%f%b'
      local git1="%F{220}~%f$(git_prompt_info)"
      local rcAndArrow='%(?.%F{white}.%B%F{red}[%?])»%f%b'
    
      vcs_info
      local git2color='cyan'
      [[ "${vcs_info_msg_0_}" == "master" ]] && git2color='196'
      local git2="||%F{${git2color}}${vcs_info_msg_0_}%f||"
    
      psvar[1]="${theUser}${theHost} ${git1} ${rcAndArrow} "
      psvar[2]="${git2}"
    }
    
    PROMPT='${psvar[1]}'
    RPROMPT='${psvar[2]}'