zshを使い始めて最初に気になる点のうち,
プロンプト
これまでとは違うシェルを起動してまず目にするのがプロンプトで,
zshに乗り換えたときもそうした違和感を感じ,
その機能をフルに活かしている,
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
複雑に見えるが,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<...<%'
すると,
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]
プロンプト中の%
記法には,%
の直後に整数を付加して,