AUTO_PUSHD によって自動的に積まれたディレクトリスタックの移動はカレントのシェルにおいて有用ですが、ログアウト後、あるいは別のセッションでは利用できません。
そのためよく移動するディレクトリについては $cdpath やディレクトリのエイリアスに設定、あるいは移動するための関数を定義することも多いと思います。
ここでは zsh バージョン 4.3.11 から標準モジュールとして使えるようになった chpwd_recent_dirs について紹介します。
以下の設定を例に説明します。カレントディレクトリを変更したときに呼ばれる特殊関数 chpwd_functions に chpwd_recent_dirs を呼ぶようにしています。詳しい使い方は zshcontrib(1) の REMEMBERING RECENT DIRECTORIES を参照してください。
autoload -Uz compinit && compinit
zstyle ':completion:*' menu select
zstyle ':completion:*:cd:*' ignore-parents parent pwd
zstyle ':completion:*:descriptions' format '%BCompleting%b %U%d%u'
typeset -ga chpwd_functions
if is-at-least 4.3.11; then
autoload -U chpwd_recent_dirs cdr
chpwd_functions+=chpwd_recent_dirs
zstyle ":chpwd:*" recent-dirs-max 500
zstyle ":chpwd:*" recent-dirs-default true
zstyle ":completion:*" recent-dirs-insert always
fi
このように設定した状態でいくつかのディレクトリを渡り歩いたあとに cdr <TAB> すると、
% cdr <TAB>
% cdr /usr/ports ←ここまで補完されるので続けて<TAB>
% cdr /usr/ports<TAB>
Completing recent directory
/usr/ports/sysutils/byobu /usr/ports/sysutils/screen /usr/ports/editors/vim
/usr/ports/sysutils/tmux /usr/ports/editors/emacs /usr/ports
% cdr /usr/ports/sysutils/<TAB>
Completing recent directory
/usr/ports/sysutils/byobu /usr/ports/sysutils/tmux /usr/ports/sysutils/screen
こんな感じにディレクトリの移動履歴が補完候補として出てきます。続けて <TAB> を押せばメニュー補完として動作します。
ディレクトリの移動履歴は ${ZDOTDIR:-$HOME}/.chpwd-recent-dirs に保存されます。これは recent-dirs-file で変更できます。
この例では .chpwd-recent-dirs に /usr/ports 以下のディレクトリしか履歴として記録されていないため、最初の <TAB> で /usr/ports まで仮入力されましたが、使っていくうちに補完候補が一画面では表示しきれなくなります。実際には移動したい先の文字列をいくつか入力して cdr ~/work/201212<TAB> などとして使っています。
ファイルに移動履歴が保存されますので、GNU Screen などで開いている別の zsh セッションからも参照できます。
日々の作業に欠かせません。
参考までに、手元にあるいくつかの OS で chpwd_recent_dirs がすぐに使えるかどうか調べてみました。
| OS | version | |
|---|---|---|
| ○ | Ubuntu 12.10 | 5.0.0-2ubuntu1 |
| ○ | Fedora 17 | 5.0.0-1.fc17 |
| ○ | FreeBSD | 5.0.0_1 |
| ○ | Oracle Solaris 11 11/11 | 4.3.12 |
| ○ | OS X Mountain Lion | 4.3.11 |
| × | Debian squeeze | 4.3.10-14 |
| × | Oracle Linux 6.3 | 4.3.10-5.el6 |
| × | CentOS 5.8 | 4.2.6-6.el5 |
比較的新しめのパッケージを採用する OS だと使えるようですね。
単なる関数なのでソースだけ取得してローカルに展開して読み込むのもアリかも知れません。