zshで直前のコマンドラインの最後の単語を挿入する

  • 24
    Like
  • 0
    Comment
More than 1 year has passed since last update.

zshでは、直前のコマンドラインの最後の単語を挿入する機能がある。1つのファイルに対して違うコマンドを実行するときに便利なので紹介する。

insert-last-wordを使う

標準でinsert-last-wordという機能がある。これを使うと、直前のコマンドラインの最後の単語がカーソル位置に挿入される。キーバインドはESC-_と ESC-.に割り当てられているので、ESCを押したあとに_、またはESCを押したあとに.で使える。

% git diff foo.txt
% git add # <= ここでESC-.
% git add foo.txt # <= 前のコマンドラインの末尾にある単語が挿入される

これを使ってもいいんだけど、次のsmart-insert-last-wordというやつをつかうともっと便利なので紹介する。

smart-insert-last-wordを使う

smart-insert-last-wordというのもある。これを有効にするための設定は次のとおり。

autoload -Uz smart-insert-last-word
zle -N insert-last-word smart-insert-last-word

これを使うと、標準のinsert-last-wordがスマートなやつに置き換わる。具体的には、[a-zA-Z], /, \ のうち少なくとも1文字を含む単語だけが挿入の対象になって、そうじゃない単語は読み飛ばされる。

キーバインドはinsert-last-wordと変わらないので、そのまま同じように使える。

% git diff foo.txt 2>&1
% git add # <= ここでESC-.
% git add foo.txt # <= 2>&1は出てこない

smart-insert-last-wordをカスタマイズする

「match」というスタイルを使うと、smart-insert-last-wordでどういう文字列を単語とみなすのかをカスタマイズできる。

標準は「[a-zA-Z], /, \ のうち少なくとも1文字を含む文字列」という条件になってる。

# [a-zA-Z], /, \ のうち少なくとも1文字を含む単語
zstyle :insert-last-word match '*[[:alpha:]/\\]*'

これを「[a-zA-Z], /, \ のうち少なくとも1文字を含む長さ2以上の文字列」というふうに変更する例は次のとおり。

# [a-zA-Z], /, \ のうち少なくとも1文字を含む長さ2以上の単語
zstyle :insert-last-word match '*([[:alpha:]/\\]?|?[[:alpha:]/\\])*'

これは1文字のグローバルエイリアスを使っているときに便利。末尾にHとかあってもそれは読み飛ばされるようになる。

# alias -g H='| head' というエイリアスを設定しているとする
% git diff foo.txt H
% git add # <= ここでESC-.
% git add foo.txt # <= Hは出てこない

キーバインドを変更する

もちろん、キーバインドは変更できる。次の例では^](Ctrlを押しながら])に変更している。

bindkey '^]' insert-last-word

標準のキーバインドはちょっと押しにくいので、よく使うなら変更しておいたほうが便利。

まとめ

最後に、今回紹介した設定をまとめておく。これを~/.zshrcに書いておけば今回紹介した機能が使用できる。

autoload -Uz smart-insert-last-word
# [a-zA-Z], /, \ のうち少なくとも1文字を含む長さ2以上の単語
zstyle :insert-last-word match '*([[:alpha:]/\\]?|?[[:alpha:]/\\])*'
zle -N insert-last-word smart-insert-last-word
bindkey '^]' insert-last-word