ここでzshの発表の続きをやる
Webteko(ウェブテコ)っていう勉強会に参加してzshについて発表した(発表資料)。発表したんだけど、時間の都合とかで(zshにとっては)基本的なところしか紹介できなかった。
「うおー! 俺のzsh好きっぷりはこんなもんじゃないぜ!」というわけで、ここでその続きを書くことにした。主にコマンドライン編集の機能について説明するよ。
smart-insert-last-word
について
まず、zshには insert-last-word
と言う機能がある。これを使うと、一つ前のコマンドの最後の単語を挿入できる。
これをもっとスマートにしたのが smart-insert-last-word
。設定の仕方はこんな感じ。
autoload smart-insert-last-word zle -N insert-last-word smart-insert-last-word bindkey '^]' insert-last-word
こうやっておくと、 [a-zA-Z]
, /
, \
のうち少なくとも1文字を含む単語だけが対象となるよ。
例
% make > buildLog.txt 2>&1 # とりあえずコマンド実行 % less # 次のコマンド入力中に ^] を押す % less buildLog.txt # 最後の単語を挿入。2>&1 は出てこない
さらに、この「単語としてマッチさせる条件」の設定もできるみたい。まあ、それはやりすぎだろう。
^Xg
をもっと使いやすくする
list-expand
って機能があって、デフォルトで ^Xg
に割り当てられている。これは *.bak
とかのワイルドカード指定を展開して、「ビヨッ」っと下に表示する機能だ。便利なんだけど、なんだか押しにくいね。2ストロークキーなんて疲れるね。
なので他のキーに割り当てるんだけど、キーがあんまり余ってない。そこで ^D
に「カーソルが行末だったら1文字削除。そうじゃなかったらlist-expand
」という動作を割り当てることにした。こんな感じ。
function _delete-char-or-list-expand() { if [[ -z "${RBUFFER}" ]]; then # the cursor is at the end of the line zle list-expand else zle delete-char fi } zle -N _delete-char-or-list-expand bindkey '^D' _delete-char-or-list-expand
例
% rm *.bak # ^カーソルがここのときに ^D を押す % rm *.bak test1.bak test2.bak # こんな風に、下に候補が展開される % rm *.bak # ^カーソルがここのときに ^D を押す % rm *.ak # b が削除される
OKOK。押しやすくなった。
undo, redo のキーバインド
zshのコマンドラインでは、もちろんundo, redoができる。できるんだけど、undoのキーバインドは ^_
または ^Xu
だ。押しにくいよ。それに、redoはデフォルトで割り当てられていない。
なので、もうちょっとましな設定にすることにした。
bindkey "^[u" undo bindkey "^[r" redo
undoを ESC-u
、redoを ESC-r
にしたよ。こんな時に便利。
% rm *.bak # ここでタブを押すと、 % rm test1.bak test2.bak testX.bak # * が展開される # その後 ESC-u を押すと、 % rm *.bak # 元に戻る
コマンドライン中に改行を入れる
zshを使ってると、ちょっとしたシェルスクリプトぐらいはコマンドラインで済ませてしまいたいと思う。当然コマンドライン中で改行したくなるよね。
改行する(でも実行はしない)っていうのは、以下のどれかでできる。
^V^J
ESC-^J
ESC-^M
ESC-RETURN
4つもあるけど全部押しにくいので、これもキーバインドを変えた。
bindkey '^J' self-insert-unmeta
こんな感じで使うよ。
% for i in $(ls *);do # ここで ^J % for i in $(ls *);do echo $i # 改行できる
実はfor文の途中とかは普通にRETURNで改行できる。
% for i in $(ls *);do # ここで 普通に RETURN % for i in $(ls *);do for> # こんな感じに改行できる
でもこのやりかただと、^P とか上矢印とか押しても1行目に移動できない。
% for i in $(ls *);do for> ls # ^P を押しても前の履歴が出てきてがっかり
self-insert-unmeta
を使うとちゃんと1行目に移動できて便利だよ。
最後に
とりあえずここまで。まあ、全部細かいネタで、別に知らなくてもいいことばっかりだと思う。でも、設定ファイル書いてたらもう楽しくて、何か止まらなくなってくる(よね)。みんなも man zshzle
とか読みまくって色々試してみるといいよ。