zshでwidgetを定義して、コマンドライン編集で任意のzsh関数を呼び出す
今まで困っていたこと
zshでは、WORDCHARSで単語の区切りにならない文字を指定できます。僕の設定はこんな感じです。
WORDCHARS='*?_-.[]~=&;!#$%^(){}<>'
詳しいことはここのWORDCHARSの解説なんかを読んでもらうとして(もう知ってる人多いよね)、要するに^Wでディレクトリ一つ分削除できるようになります。
これはこれで便利なのですが、やっぱりスペース区切りで削除したいこともあります(viで言うdB)。なのでmanでそれっぽいのないかなー、と探していました。で、結論として、ない。vi-backward-blank-wordっていう惜しいのはあったけど、それは移動するだけで削除は出来ませんでした。残念。
解決方法
じゃあどうするか。結論から言うと、以下を.zshrcに書いておけばOKです。
function _kill-backward-blank-word() { # 現在位置から左のスペースまでをkillする zle set-mark-command zle vi-backward-blank-word zle kill-region } zle -N _kill-backward-blank-word bindkey '^Y' _kill-backward-blank-word
これで、こんな使い方ができるようになります。
ls /home/mollifier/work # ここまで入力して ls /home/mollifier/ # ^W でディレクトリ1つ分削除 ls # ^Y でスペースまで全部削除
OKOK、いい感じだ。
何をやっているか
man zshzleを読んでたら、widget というのを見つけました。どうやら、コマンドラインで行うエディタ操作のことをそう言うみたいです。例えば、zshはbackward-kill-wordというwidgetを初めから持っています。これは(emacsモードでは)^Wに割り当てられていて、カーソル左の単語が削除できます。
この初めから持っているwidgetを、built-in widgetと言います。それ以外にuser-defined widgetと言うのがあって、自分で勝手にwidgetが作れます。なので、built-in widgetを組み合わせてuser-defined widgetとして登録しておけば、元にはない凝った機能が追加出来るようになります。
作り方は以下です。
関数を定義する
まずは自作の関数を作ります。上の例では function _kill-backward-blank-word という所です。その中でbuilt-in widgetを3個呼び出しています。こんな風にzle widget
という形式でwidgetを呼び出せます。