ハイパーマッスルエンジニア

Vim、ShellScriptについてよく書く

zshが遅いのはvcs_infoが原因だったので高速化した

zshの起動が遅い。tmuxでパネル分割したときやls打ったあとがもっさりしてきた。
自分のzsh環境はoh-my-zshやpreztoなどは使っていないプレーンなzsh環境だったが、PROMPT表示に用いるvcs_infoが遅かったので改善した。

vcs_info

gitやsubversionなどのバージョン管理システムから情報を取得してくれる関数。プロンプトにブランチ名や状態を表示するのに利用する。

リポジトリ情報の表示。ブランチ名の表示と差分があると✗がつく。

vcs_infoを使ったリポジトリ情報の表示は.zshrcに下記のような記載をするだけだ。

# PROMPTテーマ
setopt prompt_subst #プロンプト表示する度に変数を展開
local CYAN=$'%{\e[36m%}'
local GRAY=$'%{\e[37m%}'

autoload -Uz vcs_info
zstyle ':vcs_info:git:*' check-for-changes true    # formats 設定項目で %c,%u が使用可
zstyle ':vcs_info:git:*' stagedstr "%F{red}"     # commit されていないファイルがある
zstyle ':vcs_info:git:*' unstagedstr "%F{red}"     # add されていないファイルがある
zstyle ':vcs_info:*' formats "%F{green}%b %c%u%m %f" # 通常
zstyle ':vcs_info:*' actionformats '[%b|%a]'     # rebase 途中,merge コンフリクト等 formats 外の表示
precmd () { 
  vcs_info
}
PROMPT="
${CYAN}%~%f"
PROMPT=$PROMPT'  ${vcs_info_msg_0_}
${GRAY}$ %f'

zstyle ':vcs_info:git+set-message:*' hooks git-is_clean git-untracked
# 状態がクリーンか判定
function +vi-git-is_clean(){
  if [ -z "$(git status --short 2>/dev/null)" ];then
    hook_com[misc]+=""
  fi
}
# unstaged, untrackedの検知
function +vi-git-untracked() {
  if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
    hook_com[unstaged]+='%F{red}✗%f'
  fi
}

precmd()内にvcs_infoを書くことでPROMPT表示のたびに呼び出される。

vcs_infoが遅いのでやめる

vcs_infoは様々な情報を取得するため、自分にとっては余分な処理も走っている。自分の環境において必要なのはブランチ名、diffの有無だけだったのでgitコマンドのみにした。

# PROMPTテーマ
setopt prompt_subst #プロンプト表示する度に変数を展開

precmd () { 
  if [ -n "$(git status --short 2>/dev/null)" ];then
    export GIT_HAS_DIFF=""
    export GIT_NON_DIFF=""
  else 
    export GIT_HAS_DIFF=""
    export GIT_NON_DIFF=""
  fi
  # git管理されているか確認
  git status --porcelain >/dev/null 2>&1
  if [ $? -ne 0 ];then
    export GIT_HAS_DIFF=""
    export GIT_NON_DIFF=""
  fi
  export BRANCH_NAME=$(git branch --show-current 2>/dev/null)
}
# 末尾に空白をつけることで改行される
PROMPT=" 
%F{cyan}%~%f"
PROMPT=${PROMPT}'%F{green}  ${BRANCH_NAME} ${GIT_NON_DIFF}%F{red}${GIT_HAS_DIFF} 
%f$ '

precmd()内でvcs_infoの代わりにgitコマンドを実行し、変数をEXPORTする。EXPORTされた変数をPROMPT内で利用する形。 ちゃんとした計測はしていないが、体感300msぐらいは早くなった気がする。特にM1 MacではないIntel MacBookProでは顕著に効果を実感できた。

終わり

たまに素のzshにするとその速さにびびる。