vimのiabのよう略語展開
http://zshwiki.org/home/examples/zleiab
ZshWikiを漁っていたら、おもしろい設定を見付けた。
vimではiabで略語展開ができる(らしい)が、同様のことをzshでもやろうという設定だ。
ソースはこんなの。
setopt extended_glob
typeset -A abbreviations
abbreviations=(
"Im" "| more"
"Ia" "| awk"
"Ig" "| grep"
"Ieg" "| egrep"
"Iag" "| agrep"
"Igr" "| groff -s -p -t -e -Tlatin1 -mandoc"
"Ip" "| $PAGER"
"Ih" "| head"
"Ik" "| keep"
"It" "| tail"
"Is" "| sort"
"Iv" "| ${VISUAL:-${EDITOR}}"
"Iw" "| wc"
"Ix" "| xargs"
)
magic-abbrev-expand() {
local MATCH
LBUFFER=${LBUFFER%%(#m)[_a-zA-Z0-9]#}
LBUFFER+=${abbreviations[$MATCH]:-$MATCH}
zle self-insert
}
no-magic-abbrev-expand() {
LBUFFER+=' '
}
zle -N magic-abbrev-expand
zle -N no-magic-abbrev-expand
bindkey " " magic-abbrev-expand
bindkey "^x " no-magic-abbrev-expand
.zshrcに加えるなりsourceするなりしてこの設定を読み込んだ後、たとえば「Im」と入力した後スペースを押すと、ぱっと「| more 」へと展開される!自動略語展開だ。スペースキーで反応するようになっている。
自動略語展開といえば、global alias機能(alias -g)があるのだが、それだとすべての場所で展開されてしまうから危険である。それに対してこの略語展開だとC-x SPCで展開させなくもできる。
なお、この設定はextended_globをonにしていないと動かないけど、zsh使いなら当然onにしているよね。「LBUFFER=${LBUFFER%%(#m)[_a-zA-Z0-9]#}」の行でextended_globの機能を使っているらしい。構文がcrypticすぎてなにがなんだかわからん。マニュアルもわかりにくいし…。
ただ、この設定には欠点があって、以下のように修正しないと「-Im 」が「-| more 」に展開されてしまう。_a-zA-Z0-9の前にハイフンをつけた。
magic-abbrev-expand() {
local MATCH
LBUFFER=${LBUFFER%%(#m)[-_a-zA-Z0-9]#}
LBUFFER+=${abbreviations[$MATCH]:-$MATCH}
zle self-insert
}
言うまでもないが、連想配列abbreviationsは自由に編集すればいい。最初の文字はべつにIでなくても大文字であればなんでもいい。略語は覚えやすく、かつコマンドラインに出てきなそうな文字列にしておこう。もちろん俺は「"Ir" "| ruby"」と入れている。だってrubyistだもん。