Edited at
zshDay 11

よく実行するコマンドにキーバインドを割り当てると捗る話

More than 5 years have passed since last update.

履歴を使えば同じコマンドを高速に実行できますが、キーバインドを使えばさらに高速化することが可能です。

zshのキーバインドの基礎を紹介します。


zshのキーバインドの概要

zshには bindkey という組み込み関数が存在します。詳しくは zshzle(1) の ZLE BUILTINS を読めということなんですが、これを使うとキーバインドを設定できます。

例えばzshをemacsモードで使っているとCtrl-Aでカーソルを先頭に移動させられますが、あれは内部的にはこのキーバインド機能を使って実現されているようです。


.zshrc

bindkey -d  # いったんキーバインドをリセット

bindkey -e # emacsモードで使う
# bindkey -a # vicmdモード
# bindkey -v # viinsモード

おそらく.zshrcに上記のようなコマンドがある書いてある人が多いと思うんですが、この bindkey -e でemacsっぽい挙動をするキーバインドがあれやこれやと定義されるわけです。

オプション無しで bindkey コマンドを実行すると現時点で有効化されているキーバインドが一覧されます。

% bindkey | grep '\^A'

"^A" beginning-of-line

この行は『Ctrl-Aを押すとbeginning-of-lineが実行されます』という意味です。このbeginning-of-lineは先ほどのzshzle(1)のSTANDARD WIDGETSのMovementの中に書かれていています。


biginning-of-line (^A) (unbound) (unbound)

Move to the beginning of the line. If already at the beginning of the line,

move to the beginning of the previous line, if any.


蛇足ですが一行目の (^A) (unbound) (unbound) は左から順に



  1. bindkey -e でCtrl-Aにバインドされる


  2. bindkey -a ではバインドされない


  3. bindkey -v ではバインドされない

という意味です。


新しいキーバインドを作る

好きな処理にキーバインドを当てるにはだいたいこんな感じのことをします


.zshrc

function my_function() {

# やりたい処理
# キー実行時のプロンプトの内容は $BUFFER で取れる
zle reset-prompt # プロンプトを再描画
}
zle -N my_function # my_functionをwidgetとして登録
bindkey '^A' my_function # my_functionをCtrl-Aにバインド

味噌は zle -N で関数をwidgetとして登録できること、そして bindkey は関数ではなくwidgetを割り当てるものである、ということです。


よく使うコマンドにキーバインドをあてる

なんとなくzshのキーバインドが何かわかってきたところで、日常的によく使うあれこれのコマンドにキーバインドを割り当てておくと大変便利です。

例えばgit-statusは息を吸う様に実行したくなります。毎回キーを打っていると腱鞘炎の危険があるのでもっと簡単に実行できるようにキーバインドを割り当てましょう。

function _git_status() {

if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" = 'true' ]; then
echo git status -sb # git statusを実行したっぽくみせかける
git status -sb
fi
zle reset-prompt
}
zle -N git_status _git_status # _git_status関数をgit_status widgetとして登録
bindkey '^G^S' git_status

gitリポジトリ内で間髪入れずにCtrl-G+Ctrl-Sと打つと git status -sb と表示されます。関数の中身をあれこれ変えれば好みのキーバインドを簡単に作ることができます。よく実行するコマンドを登録しておくといろいろと捗るのでおすすめです。

ちなみにemacsモードではCtrl-Gにはsend-breakというwidgetが登録されているのでCtrl-Gを押した後にグズグズしているとそちらが実行されます。