最近はghq+pecoでリポジトリのあるディレクトリ、cdr+pecoで最近訪れた
ディレクトリに簡単に移動できて、非常に捗っている。

ghq+pecoとcdr+pecoはそれぞれ以下の記事が詳しい。

ただ、ghq+pecoはC-x C-y、cdr+pecoはC-x bと、当然別々のキーになるの
で、どっちを使うか考えたり間違えたりするのでモヤモヤしていた。

Emacsは自作のhelm-ghq.el で同じ操作感にしていたので、同じモヤモヤだっ
たが、最近来たPull Request を取り込んでからは改善。

C-x b (helm-for-files)でghqの出力も出すことでキーバインドを1つに集
約できた。C-x C-yのキーバインドは削除。

C-x bでこのような一覧が表示されて、絞り込む感じ。

  • ghq list –full-pathの出力
  • 現在開いているバッファ
  • 最近開いたファイル
  • カレントディレクトリにあるファイルやディレクトリ

複数のソースを出力していても、混乱しないどころか便利に使えたので、
zshも同じでいいじゃんと思い、変更した関数がこれ。(リファクタリング出来そう…)

function peco_helm () {
local IFS="
"
my-compact-chpwd-recent-dirs
local selected_dir=$((ghq list --full-path | sed -e "s@$HOME@~@";
cdr -l | perl -pne 's@^[0-9]+ +@@') | awk '!x[$0]++{print $0}' | peco)
if [ -n "$selected_dir" ]; then
BUFFER="cd ${selected_dir}"
zle accept-line
fi
zle clear-screen
}
zle -N peco_helm
bindkey '^xb' peco_helm
# http://blog.n-z.jp/blog/2014-07-25-compact-chpwd-recent-dirs.html
function my-compact-chpwd-recent-dirs () {
emulate -L zsh
setopt extendedglob
local -aU reply
integer history_size
autoload -Uz chpwd_recent_filehandler
chpwd_recent_filehandler
history_size=$#reply
reply=(${^reply}(N))
(( $history_size == $#reply )) || chpwd_recent_filehandler $reply
}
view raw gistfile1.sh hosted with ❤ by GitHub

ghqとcdrの両方の出力が候補に出ているのが分かると思う。
peco-helm

C-x bだけでghqとcdrを呼び出せるし、Emacsと操作が同じだし、非常に満
足行く設定になった。

IFSをいじっているのは、スペースを含むディレクトリも適切に処理するた
め。デリミタを改行だけにしている。

awkの処理はソートなしの重複削除。なんでこれで出来るのか全く分からな
いけど。。

追記(2014-10-07):
local selected_dir=...の前で、以下のmy-compact-chpwd-recent-dirs
を呼ぶときれいな一覧になります。
zshの機能のみで既に存在しないディレクトリをcdrのリストから削除する - @znz blog