MSYS2でzshのGitプロンプトを快適に使う方法

MSYS2 で zsh 使いたくない?使いたいよね?そう、使いたい! しかしその上で一つ大きな障害があります MSYS2 の zsh でプロンプトに Git のブランチを表示させようとすると微妙に上手くいきません

問題

.zshrc を使って PROMPT に現在の Git ブランチの状態を表示させようとするとフリーズするケースがあります 具体的には以下のような設定を書くとターミナルのサイズ変更時にシェルがフリーズします 原因は不明ですが PROMPT='$(git)' だけでフリーズするので Git for Windows との相性がなにか良くないのだと思っています

## git functions

current_git_branch() {
  (git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
}

parse_git_dirty() {
  local DIRTY=$(git status -s | tail -1)
  if [[ -n $DIRTY ]]; then
    echo "%{$fg_bold[magenta]%})%{$fg_bold[red]%}✗"
  else
    echo "%{$fg_bold[magenta]%})%{$fg_bold[blue]%}✓"
  fi
}

print_git_prompt() {
  local FIND_BRANCH=$(git branch 2> /dev/null | tail -1)
  if [[ -n $FIND_BRANCH ]]; then
    echo "%{$fg_bold[magenta]%}(%{$reset_color%}%{$fg_bold[yellow]%}"$(current_git_branch)$(parse_git_dirty)" %{$reset_color%} "
  else
    echo ""
  fi
}

## setting propmt

PROMPT="
%{$fg_bold[cyan]%}%n%{$reset_color%}%{$fg_bold[blue]%}@%m%{$reset_color%}:%{${fg_bold[green]}%}%~%{$reset_color%}
%(?:%{$fg_bold[green]%}➜:%{$fg_bold[red]%}➜)  %{${reset_color}%}"'$(print_git_prompt)'

RPS1="%(?..%{$fg_bold[red]%} [ %? ]%{$reset_color%}) %D - %*"

解決策 1

プロンプト表示に使う git バイナリだけ msys2 の物に差し替えると上手くいくようになります 具体的には以下のようにして Git for Windows と競合しないように MSYS2 の Git を構成し PROMPT='$(msys2_git)' のように呼び出してやると上手くいきます

pacman -S git
mv /usr/bin/git /usr/bin/msys2_git

課題

  • msys2/git をアップデートするときに毎回リネームをする必要がある
  • ここが面倒で脆弱性に繋がる可能性がゼロではない

解決策 2

Git for Windows だけでやる場合の方法です add-zsh-hook precmd でプロンプトに出したいコマンドを呼び出し、変数の値を書き換えてそれを表示するスタイルでやると上手くいきます

課題

  • プロンプトの速度が遅い
  • プロンプトする時に一瞬フォーカスが飛ぶ(別プロセルがコールされ一瞬窓ができている気がする