zshのターミナルに今いるパスのリポジトリの情報を表示してみることにします。最終目標はこんな感じ。
- ブランチ名を表示
- 全てコミットされてきれいな状態であれば緑色
- addされていないファイルがあれば
+
マークをつけて赤色 - commitされていないファイルがあれば
!
マークをつけて黄色
ちなみにこの記事に書いてあることは zsh のバージョンが 4.3.10 以上に限って有効です。
さて、これを実現するには vcs_info というものを使います。以下のような記述を ~/.zshrc
に追加します。
# この行は現在のパスを表示する設定です。ブランチを表示して色をつける設定とは関係ありません
RPROMPT="%{${fg[blue]}%}[%~]%{${reset_color}%}"
autoload -Uz vcs_info
setopt prompt_subst
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{yellow}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{red}+"
zstyle ':vcs_info:*' formats "%F{green}%c%u[%b]%f"
zstyle ':vcs_info:*' actionformats '[%b|%a]'
precmd () { vcs_info }
RPROMPT=$RPROMPT'${vcs_info_msg_0_}'
最初はネットから拾ってきてそれをそのまま使ってて動くには動いてたのですが、正直設定内容を全然理解してなくってイミフでしたので、勉強もかねてマニュアルを読んでちょっと改造してみました。以下つらつらと解説していきますが、ほぼマニュアルの日本語訳みたいなものですが自分用まとめということで。
vcs_info って?
vcs は Version Control Systems のこと(だと思う)。
subversion とか CVS とか git とかいわゆるバージョン管理システムと呼ばれるものから情報を自動的に取得してくれる関数です。
vsc_info 関数で取得した情報をもとに、それをプロンプトに表示したりします。
サポートしてるVCS
サポートしてるバージョン管理システムは以下の12個。めっちゃあるよ。
- Bazaar (bzr) http://bazaar-vcs.org/
- Codeville (cdv) http://codeville.org/
- Concurrent Versioning System (cvs) http://www.nongnu.org/cvs/
- Darcs (darcs) http://darcs.net/
- Fossil (fossil) http://fossil-scm.org/
- Git (git) http://git-scm.com/
- GNU arch (tla) http://www.gnu.org/software/gnu-arch/
- Mercurial (hg) http://mercurial.selenic.com/
- Monotone (mtn) http://monotone.ca/
- Perforce (p4) http://www.perforce.com/
- Subversion (svn) http://subversion.tigris.org/
- SVK (svk) http://svk.bestpractical.com/
vcs_info を使う準備
で、これらのバージョン管理システムの情報を自動的に取得してくれる vcs_info 君ですが、こいつを使うための宣言みたいなことをやってるんですね。それが最初の行のこれ。
autoload -Uz vcs_info
これで vcs_info 君を使う準備ができたのですが、さてバージョン管理システムの情報を取得するためにはこいつをどっかで呼び出さないといけない。
vcs_info を呼び出す
で、呼び出してるのが、この行。
precmd () { vcs_info }
precmd
てのが zsh のプロンプトが表示される毎に実行される関数で、ここで呼び出すことによって何かコマンドを叩く毎に vsc_info 君がバージョン管理システムから情報を取得してきてくれます。そして情報を取得できたら次はそれをプロンプトに表示しないといけないわけですが、、、
vcs_info の結果を表示する
取得した情報の表示をやってるのがこの行。
setopt prompt_subst
RPROMPT=$RPROMPT'${vcs_info_msg_0_}'
実は vcs_info 君は、呼び出された時に $vcs_info_msg_0_
という変数に取得してきた情報を格納してくれます。なのでそれをプロンプト変数に設定することでバージョン管理システムの情報を表示することができます。
ただ、プロンプトに vcs_info_msg_0_
をセットするだけではうまく表示してくれないので prompt_subst
というオプションをセットします。これは、プロンプトを表示する際に最初に変数展開をしてくれるというオプションです。
vcs_info の設定をカスタマイズする
$vcs_info_msg_0_
に格納される情報は自分でカスタマイズできます。カスタマイズしてるのは以下の部分です。
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{yellow}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{red}+"
zstyle ':vcs_info:*' formats "%F{green}%c%u[%b]%f"
zstyle ':vcs_info:*' actionformats '[%b|%a]'
:vcs_info:*
とすると特にバージョン管理システムを指定しない設定になります。 :vcs_info:git:*
とするとバージョン管理システムが git の時のみに有効な設定となります。
1つずつ見てみましょう。
- check-for-changes
true または false を指定します(デフォルトは false)。
true が指定されていると formats という設定項目(後で説明します)で %c
と %u
というフォーマットが使えるようになります。これは、リポジトリにコミットされていないファイルがあった場合に %c
または %u
に文字列が格納されます。詳しくは stagedstr と unstagedstr の説明を参照。
この設定を true にするとおそらく実際にバージョン管理システムに問い合わせにいってると思いますが、マニュアルには デカいリポジトリとかだと結構重くなるよ。だからデフォルトではこの機能は off になってるよ とあります。
- stagedstr
ステージされていてコミットされていない(git add だけされている)ファイルがあった時 formats の設定に %c
があれば、ここで指定した文字列が表示されます。今回の例では黄色で +
プラスマークが表示されます。
- unstagedstr
ステージされていない(git add されていない)変更ファイルがあった時 formats の設定に %u
があれば、ここで指定した文字列が表示されます。今回の例では赤色で !
エクスクラメーションマークが表示されます。
- formats
$vcs_info_msg_0_
で表示する内容をここに指定します。 %
でエスケープすることで色々なフォーマットが使えます。詳しくはマニュアル(英語)。ここでは例で使ってるものだけ解説します。
%c
ステージされていてコミットされていない(git add だけされている)ファイルがあった時に stagedstr で指定した文字列に展開されます。ない場合は空です。
%u
ステージされていない(git add されていない)変更ファイルがあった時に unstagedstr で指定した文字列に展開されます。ない場合は空です。
%b
カレントブランチ名に展開されます。
例では %F{green}%c%u[%b]%f
という値を設定しています。これは
- 通常はブランチ名のみカッコ
[]
でくくって緑色で表示 - add されていないファイルがある時は頭に
+
がついて赤くなる - commit されていないファイルがある時は頭に
!
がついて黄色くなる
となります。
- actionformats
rebase 途中だったり merge でコンフリクトが発生したり、何か特別な状況になった時に formats の代わりに actionformats で指定した文字列が $vcs_info_msg_0_
に格納されます。
設定完了
ようやっと設定の全貌が理解できました。わからないまま使ってるより、きちんとわかって使ったほうがスッキリしますね。ただ、ここで説明している以外にも vcs_info 以外の関数やら、フック機能やら、まだまだ便利そうな機能がありそうですのでさらにマニュアルを読み進めて行きたいところです。