zsh は cd -[TAB] で補完できる directory stack が setopt autopushd と組み合わせていると非常に便利なので、 directory stack を自前で保存する仕組みを作ったり、 GNU screen の他の WINDOW のディレクトリに移動するための cdsというコマンド を作ったりして、 現状でもあまり困っていませんでした。

しかし、 zshcontrib(1) に入っているものも試してみるのが 良さそうと思って試してみました。

ドキュメント

ドキュメントは man zshcontrib か、 pager $^fpath/cdr(N) で読めます。

cdr コマンドの使い方

cdr [TAB] で補完して使ったり、 cdr -l で一覧を出したり、 cdr -e で一覧を編集したりできます。

cdr -e の編集は zle なので、 bindkey -e なら、 普通のカーソル移動などの他に ただの Enter だと編集終了になってしまうので、 ^[^M (ESC に続けて Enter) で改行を入力して行を増やしたり分割したり 出来ることを知っておけば充分だと思います。

設定全体

全体としては以下のように設定してみました。

以降は設定内容を個別に解説していきます。

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:*:*:cdr:*:*' menu selection
  zstyle ':completion:*' recent-dirs-insert both
  zstyle ':chpwd:*' recent-dirs-max 500
  zstyle ':chpwd:*' recent-dirs-default true
  zstyle ':chpwd:*' recent-dirs-file "${XDG_CACHE_HOME:-$HOME/.cache}/shell/chpwd-recent-dirs"
  zstyle ':chpwd:*' recent-dirs-pushd true
fi

使えるかどうかのガード条件

昔、 zsh の設定を環境ごとに分岐させようとした時、 is-at-least は古い zsh で使えなかったのと、 バックポートで使える可能性があったり、 自前の fpath にファイルを追加した場合などを考慮して、 機能自体の存在をチェックするようにしています。

ruby で推奨されているやり方として、 RUBY_VERSION をチェックするのではなく、 機能の存在をチェックするべき、 という話があったことも影響しています。

  if [[ -n $(echo ${^fpath}/chpwd_recent_dirs(N)) && -n $(echo ${^fpath}/cdr(N)) ]]; then

Glob Qualifiers の (N) (NULL_GLOB) を使っている関係で、 一度 echo してから -n でチェックしています。 もっと簡潔に書ける方法があれば教えてください。

autoload

autoload -U と書いてある設定例もありますが、 ドキュメントにあったように autoload -Uz を使っています。

-z を付けないと KSH_AUTOLOAD の設定の影響を受けるそうなので、 基本的には -z を明示的に付けるのがおすすめのようです。

add-zsh-hook

chpwd_functions への追加は

typeset -ga chpwd_functions
chpwd_functions+=chpwd_recent_dirs

としても良かったのですが、 念のため typeset するのが最近の zsh しか使わないのなら無駄に感じたのと、 cdr のドキュメントに書いてあったこともあり、 add-zsh-hook を使ってみました。

Web で設定例を見ると zstyle ':completion:*' menu select になっていることが多いのですが、 基本的に menu select は使っていなかったので、 zshcontrib(1)${^fpath}/cdr(N) に書いてあった通りに ':completion:*' ではなく ':completion:*:*:cdr:*:*' で、 値も select ではなく selection で設定しています。

  zstyle ':completion:*:*:cdr:*:*' menu selection

recent-dirs-insert

これは cdr [TAB] の挙動の設定で、 好みが分かれると思うので、 always, fallback, both を一通り試してみるのをおすすめします。

both だと通常の cd の補完にメニューから選ぶ補完候補に履歴が入っているという感じに見えました。 あまりうまく使えていないので、そのうち他の設定に変えて試してみようと思っています。

recent-dirs-max

設定を保存する最大数です。 デフォルト値は 20 です。

recent-dirs-file

XDG Base Directory Specification に合わせて ~/.cache を使うようにしています。

他の部分で既に mkdir -p しているので、ここでは省略しています。

  #mkdir -p "${XDG_CACHE_HOME:-$HOME/.cache}/shell"
  zstyle ':chpwd:*' recent-dirs-file "${XDG_CACHE_HOME:-$HOME/.cache}/shell/chpwd-recent-dirs"

ドキュメントにあるように、 以下のような設定にして TTY ごとのファイルと グローバルのファイルにわけるのも良いかもしれません。

  zstyle recent-dirs-file ':chpwd:*' ~/.chpwd-recent-dirs-${TTY##*/} +

recent-dirs-pushd

他の設定が影響していたのか、 何が原因だったのかは追求していないのですが、 recent-dirs-pushdtrue にしないと 最初はうまく動かなかったのですが、 履歴がたまったからなのか、 なぜか今はこの設定に関係なくちゃんと動いているようです。

recent-dirs-prune

recent の一覧に追加しないディレクトリのパターンなどを設定できるようですが、 必要性を感じていないので、 まだ何も設定していません。

Disqus Comments

Kazuhiro NISHIYAMA

Ruby のコミッターとかやってます。 フルスタックエンジニア(って何?)かもしれません。 About znzに主なアカウントをまとめました。

znz znz


Published

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy