概要
これはzsh Advent Calendar 2014の9日目のエントリです。
最近zshのコマンドラインで表題の範囲選択とかを出来ることを知りました。で、それ自体は便利なんですが、かゆいところに手が届かない感じだったので自分でwidget(zshのキーバインドに割り当てられる関数みたいなやつ)を書きました。
その内容を共有します。
範囲選択
control+@
かcontrol+space
でemacsのmarksetライクに範囲選択(set-mark-command
)が出来ます。入力文字が変わる操作をすると範囲選択モードが終わります。
削除
範囲選択した状態でcontrol+h
とか押したら選択したところ全部消えて欲しいんですけど、いつも通りの1文字削除しかしてくれません。しかも、あろうことか範囲選択したところを(切り取りではなく)削除する機能がデフォルトでないようでした(あれば教えて下さい)
というわけで、
-
control+h
で普段は手前の1文字削除なんだけど範囲選択してたらその範囲を削除 -
control+d
で普段は後ろの1文字削除なんだけど範囲選択してたらその範囲を削除
というのを出来るようwidget書きました。
function delete-region() {
zle kill-region
CUTBUFFER=$killring[1]
shift killring
}
zle -N delete-region
function backward-delete-char-or-region() {
if [ $REGION_ACTIVE -eq 0 ]; then
zle backward-delete-char
else
zle delete-region
fi
}
zle -N backward-delete-char-or-region
function delete-char-or-list-or-region() {
if [ $REGION_ACTIVE -eq 0 ]; then
zle delete-char-or-list
else
zle delete-region
fi
}
zle -N delete-char-or-list-or-region
bindkey "^h" backward-delete-char-or-region
bindkey "^d" delete-char-or-list-or-region
コピー
範囲選択した状態でEscape押してからwを押すと選択範囲をコピー(copy-region-as-kill
)が出来ます。
oh-my-zshを使っていると、Escape→wが切り取り(kill-region
)に割り当てられてるので注意。
で、このcopy-region-as-kill
はコピーしても範囲選択状態が続くんですよね。コピーしたら範囲選択は終わってほしいので、これもwidget書きました。
function copy-region() {
zle copy-region-as-kill
REGION_ACTIVE=0
}
zle -N copy-region
bindkey "^[w" copy-region
ちなみに貼り付け(yank
)はcontrol+y
です。
切り取り
kill-region
というwidgetが用意されていて、これを呼ぶと選択範囲の切り取りが出来ます。しかしデフォルトではショートカットキーに割り当てられていません。で、単純にこのkill-region
をてきとうなキーに割り当てても良かったんですが、ちょっと工夫してみました。
Emacsだとcontrol+w
が、このkill-region
と同等の機能に割り当てられてます。ですが、zshのデフォルトだとcontrol+w
は単語切り取りです。
そこで、「普段は単語切り取り。範囲選択状態ならその範囲を切り取り」と言う挙動になるwidgetを書いてみました(と言うか僕のEmacsがそういう風にカスタマイズしてるんで同じにしたかっただけなんですけどね!)
function backward-kill-word-or-region() {
if [ $REGION_ACTIVE -eq 0 ]; then
zle backward-kill-word
else
zle kill-region
fi
}
zle -N backward-kill-word-or-region
bindkey "^w" backward-kill-word-or-region
補足
- コードはzshrcに書いて使ってください。
- キーバインド(コードの
bindkey
のところ)は好みで変えてください。 - 手前味噌ですが、以下と組み合わせて使いこなすとかなり便利なので、お試しあれ。
- 大したことは書いてないんですが、コードの内容を理解にするには
man zshzle
読むと良いです。 - 動作はver5.0.5で確認してます。