以下では zsh Version 4.0.2 を前提としてます。
TOC
- intro
- complete
- abbreviation
- prompt
- keybind
- TODO
intro
zsh とは、bash や tcsh や ksh の良いとこ取りをしたシェルです。よくシェルの紹介文
では bash や tcsh を普通に紹介してから、ハッカー向けとして zsh を紹介し
てる場面を見かけます。自尊心をくすぐられるでしょ?
最強のシェルだから z て付いてるのに、web での情報量は泣きたくなるほど少ないです。
実際に使ってみようとすると、その理由がわかりました。zsh 自身が既に充分複雑である
ことともうひとつ、マニュアルのせいです。目下のところ、肝となる部分の日本語訳は存
在しません( 2001.02.28 現在、と思ったらなにやら翻訳中らしい )。
ええとこういうことをやるには何処をどうすればいいのかなとマニュアルを眺めるわけで
すが、このマニュアルが最高に意味不明♪なのです。量が少ないわけではあり
ません。というか膨大です。デタラメなこと書いてあるわけでもありません。むしろ完全
に正確ですが専用の特殊用語の連発です。ネイティブスピーカでさえ「高圧的だ」「例示
が皆無」と読みづらさを口にしているのに、日本人にどうしろってんだい。
てなわけで、マニュアルとは別に、User-friendly user guide なるものがあります。マ
ニュアルを読んだあとにこれを読むとわかりますが、感動的に読みやすいです。
User-friendly という言葉はダテではありません。でも途中から専門用語が増えてきます
けど。そして、そう、これはマニュアル
を読めるようになるためのマニュアルなのかもしれません。ちなみに、
User-friendly user guide も正規のマニュアルに負けないくらい膨大です。挫折する人
がいてもおかしくはありませんというか自分も挫折しそう。
complete
zsh といえばプログラマブルな補完が最大の目玉です。最新の機構は zstyle なんですが、
コイツがまた最高に複雑です。webmaster の知る限り、zsh のマニュアルやガイド以外で
zstyle を解説してるウェブサイトにはまだ出逢っていません。ちょっとずつわかってき
たけどまだまだ深くは理解してないのでわかってから書きます。
abbreviation
emacs に abbreviation という機能があります。それをシェルでもやりたいと思ったので
す。グローバルエイリアスではだめなんです。展開されてほしかったのです。オプション
で zle を設定しておいて、.zshrc とかでたとえば以下のようにします。
typeset -A myabbrev
myabbrev=(
"ll" "| less"
"lg" "| grep"
"tx" "tar -xvzf"
)
my-expand-abbrev() {
local left prefix
left=$(echo -nE "$LBUFFER" | sed -e "s/[_a-zA-Z0-9]*$//")
prefix=$(echo -nE "$LBUFFER" | sed -e "s/.*[^_a-zA-Z0-9]\([_a-zA-Z0-9]*\)$/\1/")
LBUFFER=$left${myabbrev[$prefix]:-$prefix}" "
}
zle -N my-expand-abbrev
bindkey " " my-expand-abbrev
するってーと、コマンドラインで
lg[スペース]
と打つと、
| grep
ってかんじに展開されるのです。
ps -aux | grep mozilla
とかってよくやりますよね。大抵は暴走したときだけど...
あとはお好みで myabbrev をいじれば自由に略語を設定できますね。
prompt
シェルとはユーザがカーネルと会話する為にその間に介在するインターフェースであり、
プロンプトはユーザとまさに喫緊に接する部分であると云えます。
つまり、毎日お肌に密着するからシルクの下着のようにきめ細かでありつつも耐性があり
柔軟でいて滑かであってほしい、と思うのは人情でしょう(笑)。
さて、プロンプトに何を含めるかは好みの問題です。
ただ、カレントディレクトリは必須ではないかと。テスト環境のつもりでコマンド打った
ら実は本番環境で後の祭だったみたいなことは「んなことこの俺様がしでかすわけねーよ」
と自身たっぷりの人ほどやっちまうもんです。世の中そういうもんです。
ところがカレントディレクトリてのは階層が深くなると絶対パスが長くなりますよね。必
然的にコマンドを打てる残りのカラムが減ってしまいます。そういうのを嫌ってプロンプ
トを2段にしちまえと考えた方がいたようです。
以下の記述により screenshot のようなプロンプトにするこ
とができます。
これは bash のプロンプトをカスタマイズしてた頃のを改造したのですが、bash のほうの
カスタマイズを解説されていた元ネタの link は
こちらです。
いろんなもの詰め込んでるのでちょっと重いすけど、とても使いやすいですよ。
→ [2002.05.21] rook さんからのご指摘によりかなり速くなりました!! Thanks!!
マニュアル調べたついでに調子にのって少々最適化をやってみました。
ループも無くなってすっきり。
いやあしかし便利な機能があるもんですね。zsh スゲーわ。
precmd() {
hostnam=${HOST##.*} # wildcard, not regex!
usernam=$(whoami)
newPWD=${PWD}
# アクセサリをつけていく
promptstr="--(${usernam}@${hostnam})-<mm/dd-hh:mm>---(${PWD})--"
fillsize=$(( ${COLUMNS} - ${#promptstr} )) # プロンプト幅を計算
if [ $fillsize -ge 0 ]
then
fill=${(l.${fillsize}..-.)}
else
fill=""
offset=$(( (${fillsize}*(-1)) + 4 ))
newPWD="..."${newPWD[${offset},-1]}
fi
}
termwide() {
local GRAY=$'%{\e[1;30m%}'
local LIGHT_GRAY=$'%{\e[0;37m%}'
local WHITE=$'%{\e[1;37m%}'
local LIGHT_BLUE=$'%{\e[1;36m%}'
local YELLOW=$'%{\e[1;33m%}'
local PURPLE=$'%{\e[1;35m%}'
local GREEN=$'%{\e[1;32m%}'
local BLUE=$'%{\e[1;34m%}'
PROMPT=$YELLOW"-"$BLUE"-("$YELLOW"\${usernam}"$LIGHT_BLUE"@"$YELLOW"\${hostnam}"\
$BLUE")-<"$YELLOW"%D{%m}"$LIGHT_BLUE"/$YELLOW%D{%d}"$BLUE"-"\
$PURPLE"%D{%H}"$LIGHT_BLUE":"$PURPLE"%D{%M}"$BLUE">-"\
$YELLOW"-\${fill}"$BLUE"-("$YELLOW"\${newPWD}"$BLUE")-"$YELLOW"-"\
$'\n'\
$YELLOW"-"$BLUE"-["\
$YELLOW"%h"\
$BLUE"]"$WHITE"%#"\
$'%{\e[0m%} '
PROMPT2=$LIGHT_BLUE"-"$YELLOW"-"$YELLOW"-"$LIGHT_GRAY$'%{\e[0m%} '
}
このように定義してから termwide と実行するだけです。
端末(エミュレータ)によっては改行の前に行が変わってしまうかもしれません。その場合
は、プロンプト幅の計算のところで -1 を入れて
fillsize=$(( ${COLUMNS} - ${#promptstr} -1 )) # プロンプト幅を計算
としてみてください。
ちなみにこのように書いた場合は、オプションとして
setopt prompt_subst
が有効になっている必要があります。こうしないならば、precmd に PROMPT の設定まで
含める必要があるのです。
keybind
そのうち整理します。
TODO
- 沢山ありすぎてよくわかりません
役に立たないので戻る