サブモジュールの状態を含めてZSHの右側に表示する


仕事柄サブモジュールをよく使用しているので、ZSHの右に出すブランチの情報にサブモジュールの情報を合わせて出すようにしました。

拾いどころは忘れてしまいましたが、拾ってきたものを加工しています。

動作を確認している環境は今のところCygwinのみです。

欠点:異常に重い。。。

### Git
#
# Show branch name in Zsh's right prompt
#
autoload -Uz VCS_INFO_get_data_git; VCS_INFO_get_data_git 2> /dev/null
setopt prompt_subst
setopt re_match_pcre

function rprompt-git-submodule-status {
  local st color subName name treeTop cdir
  treeTop="$1"
  cdir="$PWD"
  cd "$treeTop"
  st=`git submodule foreach git status 2> /dev/null | perl -p -0777 -e 's/^(Entering ([^(Entering)]|.)*?)Entering.++/$1/s' 2> /dev/null`
  cd "$cdir"
  subName=`echo $st|sed -n "1p"|sed -e "s/^Entering '\([^']*\)'/\1/"`
  if [[ -n "$subName" ]]; then
    if [[ "$st" =~ "(?m)^nothing added" ]]; then
      color=%B%F{yellow}
    elif [[ "$st" =~ "(?m)^# Untracked" ]]; then
      color=%B%F{red}
    elif [[ "$st" =~ "(?m)^# .*\"git (pull|push)\"" ]]; then
      color=%B%F{blue}
    elif [[ "$st" =~ "(?m)^nothing to" ]]; then
      color=%F{green}
    fi
    echo " with $color$subName%f%b"
  fi
}

function rprompt-git-current-branch {
  local name st color gitdir action
  if [[ "$PWD" =~ '/\.git(/.*)?$' ]]; then
    return
  fi
  name=`git rev-parse --abbrev-ref=loose HEAD 2> /dev/null`
  if [[ -z $name ]]; then
    return
  fi

  gitdir=`git rev-parse --git-dir 2> /dev/null`
  action=`VCS_INFO_git_getaction "$gitdir"` && action="($action)"
  treeTop=`dirname "$gitdir"`

  st=`git status 2> /dev/null`
  if [[ "$st" =~ "(?m)^nothing to" ]]; then
    color=%F{green}
  elif [[ "$st" =~ "(?m)^nothing added" ]]; then
    color=%F{yellow}
  elif [[ "$st" =~ "(?m)^# Untracked" ]]; then
    color=%B%F{red}
  else
    color=%F{red}
  fi
  echo "$color$name$action%f%b`rprompt-git-submodule-status $treeTop`"
}

RPROMPT='[`rprompt-git-current-branch`]'