vcs_info の使い方 あるいは prompt_subst のススメ
みなさんバージョンコントロールしてますか? 人生もバージョンコントロールしたいですね.
zsh 上でバージョンコントロールを扱う場合に便利な vcs_info
の使い方です. しかしながら自分で自分の使う VCS を使ってがりがりスクリプト書いたほうがいいような気もしますが気のせいです.
以下のようなものを $ZDOTDIR/.zshrc
に書くだけです PROMPT
のあたりは各自調整のこと.
setopt prompt_subst autoload -Uz add-zsh-hook autoload -Uz vcs_info zstyle ':vcs_info:*' formats '%s' '%b' '%i' '%c' '%u' zstyle ':vcs_info:*' actionformats '%s' '%b' '%i' '%c' '%u' '%a' zstyle ':vcs_info:*' get-revision true zstyle ':vcs_info:*' check-for-changes true zstyle ':vcs_info:*' max-exports 6 function _precmd_vcs_info () { LANG=en_US.UTF-8 vcs_info } add-zsh-hook precmd _precmd_vcs_info PROMPT+="\$( if [[ -n \"\${vcs_info_msg_0_}\" ]]; then echo -n \" [\${vcs_info_msg_0_}:\" if [[ \"\${vcs_info_msg_0_}\" == \"git\" && -z \"\${vcs_info_msg_2_}\" ]]; then rev=\$(git rev-parse --short HEAD) namerev=\$(git name-rev --name-only --no-undefined \$rev) if [[ -n \"\$namerev\" ]]; then echo -n \"\$rev(\$namerev)\" else echo -n \"\${vcs_info_msg_1_}\" fi else echo -n \"\${vcs_info_msg_1_}\" fi if [[ -n \"\${vcs_info_msg_3_}\" || -n \"\${vcs_info_msg_4_}\" ]]; then echo -n \":\${vcs_info_msg_3_}\${vcs_info_msg_4_}\" fi if [[ -n \"\${vcs_info_msg_5_}\" ]]; then echo -n \":\${vcs_info_msg_5_}\" fi echo -n \"]\" fi )%E " fi
setopt prompt_subst
- ちょーべんりなプロンプトを実現します. 具体的には
PROMPT
変数の中の変数参照をプロンプト表示時に展開します. ここで$()
によるシェルスクリプト埋め込みを用いるとなんでもできちゃうという寸法です. autoload -Uz add-zsh-hook
- いろんなフックを便利にかけることができる関数をロードします. これなしだと何の前置きもない変数を用意して代入すると…みたいな感じになって見通しよくない気がします. が中ではそういうことやってるよね.
autoload -Uz vcs_info
- キモです.
vcs_info
関数をロードします. 中ではいろいろやってます. git の場合 pid が 30 程度進むくらいにいろいろやってます. zstyle ...
vcs_info
のカスタマイズなんかをやってます. だいたい使うところはこんなところじゃないでしょうか. 細かいところはman zshcontrib
してください.function _precmd_vcs_info
- 名前はどうでもいいです.
precmd
フックでvcs_info
を呼ぶだけの簡単なお仕事です.vcs_info
を呼ぶ際の locale をうまくしておかないとうまくいかない場合があるようです*1. add-zsh-hook precmd _precmd_vcs_info
- 先の関数を
precmd
フックにひっかけます. うまいことしてくれます. PROMPT+=...
vcs_info
が呼ばれるとvcs_info_msg_{n}_
という変数にいろいろ入ってくるので美味しく調理しましょう. ここではprompt_subst
によってべんりになったプロンプト機能によってシェルコマンドをその場で展開してもらいます. ここではエスケープに注意しましょう. *2psvar
という変数に入れてプロンプト側で%v
で受け取る方法もありますが趣味の問題です.psvar
は配列となっていて私には扱いにくかったのです. こっちの方が直感的に扱えますし.git rev-parse --short HEAD; git name-rev --name-only --no-undefined $rev
- どうも
vcs_info
は git の no branch 状態をうまく扱えていないようなので微妙に調整を施します. どうでもいいですよね.
バージョンチェック
vcs_info
は zsh 4.3.7 以上に同梱です. それ未満の環境でも同じ zshrc を使う場合はバージョンチェックが必要になるでしょう. 以下ではその方法を記しておきます.
autoload -Uz is-at-least if is-at-least 4.3.7; then ... ここに 4.3.7 以上向けのコード ... fi
あとがき
vcs_info とか prompt_subst というか add-zsh-hook とか is-at-least の紹介になってしまった気がいたしますが, もうどうでもいいや. vcs_info はいろんなところで紹介されてるし. でも各所でフックのかけかたとかバージョンチェックとかがなってない印象だったのと, psvar 使って見通し悪そうに見えたのでこういう方法もありますよ, くらいのつもりで. prompt_subst は強力ではあるけれど precmd + psvar + %v で代用できなくはなかったり, エスケープ考えなきゃだったりでアレなところはありますが, psvar の添字考えるのとどっちがどーかみたいなところはありますしね.