pecoを使って端末操作を爆速にする


[peco/peco](https://github.com/peco/peco)はインタラクティブフィルタリングツールです。

このツールにより、ターミナルでの操作が**何倍にも高速化**できると言っても過言ではありません(過言)。

本記事では私が設定している3種のpecoの使い方と、その設定方法を紹介します。

---
## 環境
以下の環境で使用しています。

- Linux Mint 18.2
- zsh 5.1.1 (x86_64-ubuntu-linux-gnu)

---
## インストール
go getによるインストールは推奨されていないため、githubの[releasesページ](https://github.com/peco/peco/releases)から取得しパスを通します。

---
## history with peco
zshやbashには`Ctrl + R`でのコマンド履歴検索機能があります。
ですが、1行しか表示されないので、類似のコマンドが多く履歴にある場合、なかなかお目当てのコマンドをサーチすることは難しいです。

---
pecoによるコマンド履歴検索は次のようになります。

![history.gif](https://qiita-image-store.s3.amazonaws.com/0/214526/bc60404d-265e-f356-2aad-54071355a32d.gif)


1文字入力するごとにインタラクティブに絞り込んでくれます。

---
設定に関してですが、まずはhistory周りの設定は次のようになっています。
けっこうな数の履歴を保存しています。

```zsh:.zshrc
# history
HISTFILE=$HOME/.zsh-history
HISTSIZE=100000
SAVEHIST=1000000

# share .zshhistory
setopt inc_append_history
setopt share_history
```

---
続いてpecoの設定です。
関数を設定し、`Ctrl + R`にこの関数呼び出しを割り当てる設定になっています。

```zsh:.zshrc
function peco-history-selection() {
    BUFFER=`history -n 1 | tac  | awk '!a[$0]++' | peco`
    CURSOR=$#BUFFER
    zle reset-prompt
}

zle -N peco-history-selection
bindkey '^R' peco-history-selection
```

---
## cdr with peco
過去に実行したコマンドに関しては、上記のhistory + pecoで高速に検索できるようになりました。
しかし、ディレクトリ移動はどうでしょうか？

```sh
$ cd work
$ cd hoge
$ cd ../fuga
```
上記のように相対パスで移動することがほとんどだと思います。
これではコマンド履歴検索でヒットしたとしても、カレントディレクトリが異なる場合では無意味です。

そこで使用するのがcdrです。(`zsh 4.3.11`以降で使用することができます)
cdrはディレクトリ移動の履歴検索機能です。

pecoと組み合わせた場合の挙動は以下のようになります。

![cdr.gif](https://qiita-image-store.s3.amazonaws.com/0/214526/0d59a150-a41a-45aa-80bf-1dd222f71245.gif)


まずはcdr自体の設定です。

```zsh:.zshrc
# cdr
if [[ -n $(echo ${^fpath}/chpwd_recent_dirs(N)) && -n $(echo ${^fpath}/cdr(N)) ]]; then
    autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
    add-zsh-hook chpwd chpwd_recent_dirs
    zstyle ':completion:*' recent-dirs-insert both
    zstyle ':chpwd:*' recent-dirs-default true
    zstyle ':chpwd:*' recent-dirs-max 1000
    zstyle ':chpwd:*' recent-dirs-file "$HOME/.cache/chpwd-recent-dirs"
fi
```

次にpecoの設定です。
こちらもhistoryの場合と同様に関数を用意しています。
ショートカットは`Ctrl + E`に割り当てています。

```zsh:.zshrc
function peco-cdr () {
    local selected_dir="$(cdr -l | sed 's/^[0-9]\+ \+//' | peco --prompt="cdr >" --query "$LBUFFER")"
    if [ -n "$selected_dir" ]; then
        BUFFER="cd ${selected_dir}"
        zle accept-line
    fi
}
zle -N peco-cdr
bindkey '^E' peco-cdr
```

## ghq with peco
様々なgitリポジトリを管理していると、cdrだけではディレクトリ検索が面倒になってきます。
そこでリポジトリ管理コマンドの[ghq](https://github.com/motemen/ghq)と組み合わせます。

ghqは`ghq get reireias/dotfiles`のようなコマンドでリポジトリのcloneが可能です。
cloneされたリポジトリは、.gitconfig等で設定したrootディレクトリ以下にcloneされます。

管理しているリポジトリ一覧を取得する`ghq list`コマンドとpecoを組み合わせると以下のようになります。
gitリポジトリのみが抽出対象となるので、cdrよりも高速にリポジトリへ移動することができます。

![ghq.gif](https://qiita-image-store.s3.amazonaws.com/0/214526/14e146e3-4261-bddc-b4c6-ab237ad3fc17.gif)


pecoの設定は次のようになっています。
ショートカットは`Ctrl + G`を割り当てています。

```zsh:.zshrc
function peco-ghq-look () {
    local ghq_roots="$(git config --path --get-all ghq.root)"
    local selected_dir=$(ghq list --full-path | \
        xargs -I{} ls -dl --time-style=+%s {}/.git | sed 's/.*\([0-9]\{10\}\)/\1/' | sort -nr | \
        sed "s,.*\(${ghq_roots/$'\n'/\|}\)/,," | \
        sed 's/\/.git//' | \
        peco --prompt="cd-ghq >" --query "$LBUFFER")
    if [ -n "$selected_dir" ]; then
        BUFFER="cd $(ghq list --full-path | grep --color=never -E "/$selected_dir$")"
        zle accept-line
    fi
}

zle -N peco-ghq-look
bindkey '^G' peco-ghq-look
```

## おわり
これでターミナルでの作業が爆速になるはず！！！