zshを使い始めて最初に気になる点のうち,すぐに設定してすぐに効果を実感できる即効薬的なものを今回は紹介しよう。
プロンプト
これまでとは違うシェルを起動してまず目にするのがプロンプトで,これが変わるとちょっとした違和感がある。この違和感は結構大切でスーパーユーザに切り替えたり,あまり設定していないマシンを触っていたりということが実感できるので慎重に作業を進めるきっかけに利用できる。
zshに乗り換えたときもそうした違和感を感じ,それまでのシェルと似たものにしたくなるかもしれないが,ちょっとした違和感を保ってこれまでとは違う機能をたくさん利用するのだ,という心構えにしたらどうだろうか。心構えはともかくとして,プロンプト出力にもzshの細やかな配慮があるので,それを活かさないのは損である。
その機能をフルに活かしている,とまでは行かないが,筆者の ~/.zshrc のプロンプト設定部分は概ね以下のようになっている。
nprom () {
setopt prompt_subst
local rbase=$'%{\e[33m%}[%%{\e[m%}' lf=$'\n'
local pct=$'%0(?||%18(?||%{\e[31m%}))%#%{\e[m%}'
RPROMPT="%9(~||$rbase)"
case "$USER" in
yatex) PROMPT=$'%{\e[33m%}%U%m{%n}%%%{\e[m%}%u ' ;;
java) PROMPT=$'%{\e[36m%}%U%m{%n}%%%{\e[m%}%u ' ;;
*)
local pbase=$'%{\e[$[32+RANDOM%5]m%}%U%B%m{%n}%b'"$pct%u "
PROMPT="%9(~|$rbase$lf|)$pbase"
;;
esac
[[ "$TERM" = "screen" ]] && RPROMPT="[%U%~%u]"
}
nprom
複雑に見えるが,見た目は第2回で示したサンプルzshrcにあるPROMPT='%m{%n}%% 'およびRPROMPT='[%'と基本的に同じである。これにちょっとした味付けを行なっている。この設定にしたときの端末で操作した様子を模したものをまず示そう。
firestorm{yuuji}% ] firestorm{yuuji}% ] firestorm{yuuji}% ls /usr ] X11R6/ include/ local/ share/ tools.i386/ X11R7/ lib/ lost+found/ spool/ x11r6.tar.gz bin/ libdata/ mdec/ src/ xsrc/ emul/ libexec/ pkg/ tests/ games/ lkm/ sbin/ tmp/ firestorm{yuuji}% ls /usr/hoge ] ls: /usr/hoge: No such file or directory firestorm{yuuji}% ] firestorm{yuuji}% cd /usr/src/external/bsd/openldap/dist/servers/slapd ] firestorm{yuuji}% [/usr/src/external/bsd/openldap/dist/servers/slapd] firestorm{yuuji}% cd back-bdb [/usr/src/external/bsd/openldap/dist/servers/slapd/back-bdb] firestorm{yuuji}%
要点を示すと以下のようになる。
- プロンプトに色付け
コマンドの出力が多くてさかのぼって見るときなど,その出力がどこから始まっているのか判別しやすいよう太字にして色を付けている。
プロンプト文字列に文字属性を変えるエスケープシーケンスを
%{と%}で括って入れておけばよい。エスケープシーケンス先頭のESC文字は,zshでは$'…'でクォートした\eで表現できる。- 数式展開
-
以前遊びで入れた設定で「zshっぽく見える」効果しかないが,zshでは数値演算や乱数生成ができるので色をランダムで変えている。数式展開ほか,さまざまな展開をプロンプト文字列に対して施したい場合には
setoptでシェルオプションprompt_substを有効化しておく。 - 右プロンプト
右側のプロンプト(
RPROMPT)に現在ディレクトリを出しておく。あまりに階層が深くなった場合は右に出すのをやめて2行にする。これを切り替えているのが%n(~|string1|string2)という記法で,スラッシュ区切りがn個以上の場合に string1 を,そうでないときに string2 を設定する。上記設定例では,PROMPT,RPROMPTともにn=9での場合分けを行ない,スラッシュが9個未満のときは右プロンプト,9個以上のときは左プロンプトに改行つきでパス名を出すようにしている。- エラーの明示
直前に実行したコマンドが正常終了せず,終了値(
$?)が0以外になったときはプロンプト末尾の%を赤にしている。ただし,あるプロセス起動中C-zを押しsuspendしてコマンドラインに戻った直後は$?=18となるが,suspend直後は赤でないほうがいいので$?=18の場合も赤くしないよう除外している。この切り替えは
%n(?|string1|string2)の記法で行なう。終了値がnのときはstring1を,そうでないときはstring2 を出力する。なお,起動したコマンドがエラー終了したかを知るにはシェルオプション
print_exit_valueをセットしておくのも効果的で,この場合はエラー終了したときのみ,その終了値を出力してくれる。
筆者個人の設定ではカラフルにしているが,スーパーユーザのプロンプトはシンプルにしている。
RPROMPT='(%~)'
PROMPT=$'%B%m%b:%?:%# '
スーパーユーザでは色を付けず一般ユーザ時と違うことを意識させつつ,太字にして過去のプロンプト位置を探しやすくしている。%?は直前のコマンドの終了コードの値をそのまま出す表記である。
ここまでの例にあるように,プロンプト文字列では%で始まる記法を様々な文字列に展開する。代表的なものを下記に示しておく。
| 記法 | 意味 |
|---|---|
%% | %文字自身 |
%# | 一般ユーザなら %,スーパユーザなら # |
%l | tty名 |
%M | ホスト名(全部) |
%m | ホスト名(最初のドットまで) |
%n | ユーザ名 |
%? | 直前のコマンドの終了値($?) |
%/ | カレントディレクトリ |
%~ | 同上。ただし~記号などで可能な限り短縮する |
%! | ヒストリ中のイベント番号 |
%D{FMT} | strftime(3)関数にFMTの書式を渡したときの現在時刻の文字列 |
%B | 太字開始 |
%b | 太字解除 |
%U | 下線開始 |
%u | 下線解除 |
%S | 強調開始 |
%s | 強調解除 |
%{…%} | 生のエスケープシーケンスを挟む |
%n>string> |
以降のプロンプト文字列の最大長をn文字以下に後略表記する。省略を示す文字列としてstringを使う。 |
%n<string< |
以降のプロンプト文字列の最大長をn文字以下に前略表記する。省略を示す文字列としてstringを使う。 |
最後の%n<string<は,プロンプトに%~などを設定してパス名を出しているときに,階層が深くてプロンプトが長くなるのを回避するもうひとつの方法として利用できる。
たとえば,以下のようにしてみる。
RPROMPT='[%39<...<%'
すると,最初の [ の次の文字,つまり % によって出される文字列が39文字を超える場合は先頭部分を切り詰めて `...' に変わる。
duke{yuuji}% pwd ] duke{yuuji}%] duke{yuuji}% cd /usr/src/sys/arch/amd64/compile/DUKE ] duke{yuuji}% [/usr/src/sys/arch/amd64/compile/DUKE] duke{yuuji}% cd lib [...src/sys/arch/amd64/compile/DUKE/lib]
プロンプト中の%記法には,%の直後に整数を付加して,個数や回数・長さを指定できるものもある。

