weblog of key_amb

主にIT関連の技術メモ

peco をセットアップしてみた(Zsh編)

これもだいぶ今更感ありますが、Maczshpeco を入れて設定してみました。

peco について知らない人のために一応かんたんに説明すると、@lestrrat さんが元は Python の percol というツールだったものを Go 言語に移植したもの*1で、テキストをフィルタして、history などの検索を楽にしてくれるものです。

ネット上で話題になって、一部の技術者界隈で流行ったのはたぶん半年以上前で、そのときにも一瞬だけ触ったのだけど、そのときは使い込まずに終わりました。

…で、なくてもなんとかなるかなと思っていたのですが、最近「pecoないと死ぬ」と言っている人が周囲に3人ぐらいいたので、「そんなに便利なのか」と、そろそろもう1回トライしておくことにしました。

今では Qiita などに先人たちの .zshrc.bashrc の設定がアップされているので、ありがたいですね。 参考にさせてもらっています。

本家リポジトリの Wiki にも色んな応用例があるようなので、暇を見つけて試してみたいと思います。
特に、エディタ連携は捗りそうなので、設定しておきたい。

以下は、現在 Mac.zshrc に設定しているものです。ちょっと検索して Qiita 等から拝借しているものが主(後述の参考記事参照)なので、既に使い込んでいる人には目新しい要素はないかと。

後ほどサーバ作業用にbashの設定も作ろうと思っています。

history 検索

Ctrl-r のヒストリ検索を peco に置き換えてしまう。

# search history
function peco-select-history() {
  local tac
  if which tac > /dev/null; then
    tac="tac"
  else
    tac="tail -r"
  fi
  BUFFER=$(\history -n 1 | eval $tac | peco)
  CURSOR=$#BUFFER
  zle clear-screen
}
zle -N peco-select-history
bindkey '^r' peco-select-history

ローカルリポジトリのファイル、ディレクトリ検索

Goのソースとその他をまとめて探す。

キーバインドのプレフィックスはとりあえず Ctrl-u にしてみた。
Ctrl-uzsh でコマンド入力を全削除するキーバインドだけど、peco と組み合わせる場合は問題になるケースなさそう。
あと打ちやすい。

※追記: その後問題になったので、デフォルトの Ctrl-uキーバインドを削除するように .zshrc に追記しました。

bindkey -r '^u'

ディレクトリ移動するやつ以外はカーソルを末尾に持っていかないようにしたpeco の結果をコマンドラインに挿入することにした。
ファイルだったらエディタで開くようにしている設定も見かけて、それはそれで実用的だと思うけど、この設定にしておけば vi なり入力した後にキーバインドを実行すればいいので、より汎用的だと思う。
最初、このやり方がわからなくて、キーバインドを実行した後に vi なり打つようにしていたが、後に書く予定の bash のやり方を参考にしたらできた。

# search repository
function peco-cd-repository() {
  DIR=$(\find ~/gitrepos ~/my/go/src/github.com -type d -a \! -regex '.*/\.git.*' | peco | head -n 1)
  pushd $DIR > /dev/null
  zle clear-screen
}
function peco-find-repository() {
  local l=$(\find ~/gitrepos ~/my/go/src/github.com -a \! -regex '.*/\.git.*' | peco)
  BUFFER="${LBUFFER}${l}"
  CURSOR=$#BUFFER
  zle clear-screen
}
zle -N peco-cd-repository
zle -N peco-find-repository
bindkey '^ud' peco-cd-repository
bindkey '^uf' peco-find-repository

カレントディレクトリ以下の検索

以下では一応 -maxdepth N という安全弁はつけているものの、サーバでやると死にかねないので、サーバ用の設定には入れないつもり。
面倒でも都度 find . | peco とかやった方が安全そう。

# search current directory
function peco-find() {
  local l=$(\find . -maxdepth 8 -a \! -regex '.*/\..*' | peco)
  BUFFER="${LBUFFER}${l}"
  CURSOR=$#BUFFER
  zle clear-screen
}
function peco-find-all() {
  local l=$(\find . -maxdepth 8 | peco)
  BUFFER="${LBUFFER}${l}"
  CURSOR=$#BUFFER
  zle clear-screen
}
zle -N peco-find
zle -N peco-find-all
bindkey '^uc' peco-find
bindkey '^ua' peco-find-all

感想

階層が深いときのディレクトリ移動やファイル検索して開くまでがめちゃ楽になりそう。

今後は grep よりも peco って打つ機会の方が増えそうです。
パッと思いつく例だと、ps | peco とか。

参考