はじめに
100%趣味で書かれた記事です。
脱コピペを目標にmanを読みつつzshの理解を深めようのコーナー。
ほぼmanの翻訳みたいになったけど、ディレクトリ操作についてコメント混じりで書いていきます。
書くこと
- オプション、各種コマンドについて
- 筆者の設定(zshrc)について
書いてないこと
- zshの導入について
- プラグインについて
- 名前付きディレクトリについて
OS&version
Version | |
---|---|
OS | macOS Catalina |
zsh | 5.8.0 |
cd関連のオプション一覧
-
AUTO_CD
ディレクトリ名だけを入力した場合に、そこにcdする
cd ぐらい入力したいけど..
で親に戻るときの便利さ故に手放せない -
AUTO_PUSHD
ディレクトリ移動時に、移動元をディレクトリスタックにpushする -
CDABLE_VARS
指定したディレクトリが存在しない場合、名前付きディレクトリ展開を試みる
補完時に 意図してない ディレクトリが表示されるので 設定には注意 -
CD_SILENT
cdした後に、カレントディレクトリを表示しない。
※ デフォルト(OFF)時には cd の引数が-
だったり、ディレクトリスタック指定、cdpath内のパスを指定したとき 移動後に カレントディレクトリを表示する仕様になってるよ -
CHASE_DOTS
パスに..
が含まれる場合、物理パスの親ディレクトリとして変換する -
CHASE_LINKS
パス名に含まれるすべてのシンボリックリンクを物理パスに変換する -
PUSHD_IGNORE_DUPS
ディレクトリスタックに同じ名前のものをpushしない(重複除去) -
PUSHD_MINUS
スタックへのアクセス時に、'+'
と'-'
の意味を反転させる -
PUSHD_SILENT
push,またはpopdの後にディレクトリスタックを出力しない -
PUSHD_TO_HOME
引数無しでpushdすると pushd $HOME となる
cd関連の変数一覧
-
cdpath
cdコマンドの検索パスを指定する。 ディレクトリを列挙する配列 -
DIRSTACKSIZE
ディレクトリスタックの最大サイズ
##cd
zshのbuiltin-command cd
について
特徴的なとこ:第2引数がとれるくらい。
書式
cd [ -qsLP ] [arg1 [arg2] | {+|-}N]
arg1 を省略したら$HOMEに移動する。
arg1 が「-」だったら移動前のディレクトリに移動する。
それ以外はこんな感じ
- arg1が /で始めるときは普通に移動
- カレントディレクトリ以下から argを探す
- cdpathからargを探す
- 名前付きディレクトリとしてargを探す
- 上記のいずれにも当てはまらない場合は失敗
オプション一覧
option | 説明 |
---|---|
-q | chpwd関数に登録されたhookを実行しない |
-s | パス名にシンボリックリンクが含まれる場合は移動しない |
-P | シンボリックリンクを物理パスに直して移動 |
-L | シンボリックリンクを物理パスに直さない。 |
pushd, dirs
移動元のディレクトリをスタック状に保存できる。 この記憶領域をディレクトリスタック
と呼ぶ
ここではあんまり詳細には説明しない。
AUTO_PUSHD
オプションがあるので、pushd
単体で使うことそうそうない気がする。
pushd
で ディレクトリスタックにpush。dirs
でディレクトリスタックの中身が確認できる
pushd
pushd [ -qsLP ] [arg1 [arg2] | {+|-}N]
オプションは cd
と同じ
dirs
dirs [ -lpvc ]
-
-l
:ディレクトリスタックを全てフルパスで表示 -
-p
:一行づつ表示 -
-v
:番号つきで表示。
cd でディレクトリスタック参照
cd -{+|-}N
でディレクトリスタックを参照して 移動できる。
+
の場合は、左(新しいほう)から、 -
の場合は 右(古い方)から数える
cd -<ここで補完が聞いて便利ですね>
# pwd → /tmp/x
% dirs
/tmp/x /tmp/x/d /tmp/x/c /tmp/x/b /tmp/x/a
# 補完
% cd +1
1 -- /tmp/x/d
2 -- /tmp/x/c
3 -- /tmp/x/b
4 -- /tmp/x/a
# 補完2
% cd -0
0 -- /tmp/x/a
1 -- /tmp/x/b
2 -- /tmp/x/c
3 -- /tmp/x/d
前者のほうが直感的だと思います。
かつ cd -
との兼ね合いで -
のほうがわかりみが深いので PUSHD_MINUS
オプションを指定してもいいかもしれません。
Remembering Recent Directories
真打ち登場。cdrコマンド
移動したディレクトリを履歴化、参照して移動。ということが可能になる
ディレクトリスタック(pushd, dirs)
と似てるけど cdrではディレクトリスタックを使用しない
以下 chpwd_recent_dirs
で積まれるディレクトリ履歴一覧を ディレクトリリストと呼ぶことにする
デフォルトで重複除去してくれるからいいですね
導入
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
add-zsh-hook chpwd chpwd_recent_dirs
書式
cdr [-l | -r | -e | -p <pattern> | <dir-num> ]
<dir-num>はディレクトリリストの番号
。 1は直前のディレクトリとなる
引数を省略した場合は cdr 1
と同義
ディレクトリリストおよびリストの順序は別ウィンドウと共通なので注意
後述する recent-dirs-default
を設定しているとき、 数値以外の引数の場合 cd
と同じ動作になる
オプション一覧
オプション | 説明 |
---|---|
-l | ディレクトリリストの表示。(~置換した状態で表示される) |
-r | 変数replyをディレクトリセットに設定する。 |
-e | ディレクトリリストを編集する。 zleエディタぽい。 |
-p | パターンにマッチする項目をディレクトリリストから削除する 実行後、確認を求められる。 省略したい場合は -P
|
設定
zstyle ':chpwd:*' <ここで指定するよ>
recent-dirs-default
trueにすると、 コマンド引数に数値(index)以外、 または引数が複数指定された場合は cd
コマンドとして扱う
recent-dirs-file
ディレクトリリストが保存されるファイル
デフォルトは ${ZDOTDIR:-$HOME}/.chpwd-recent-dirs
深いこと考えなければデフォルト(設定無し)安定
recent-dirs-insert
補完候補に何を表示するかの設定。
recent-dirs-default
がtrue かつ この項目が trueのとき、インデックスではなくディレクトリ名が補完される。
履歴に cdr <dir-num>
の形式で残らないのでいいかも
以下、補完候補として表示されるリストとして
ディレクトリリストをA
カレントディレクトリ配下の移動先一覧を B
とする
-
always
: 常にAのみ補完候補に表示する。 -
fallback
:Aを補完候補に表示する。Aが空の場合はBを補完する -
both
:Aの後続にBを補完候補として表示する
always
でいい気もするが、 cdr=cd として使ってる人は fallback
both
がお勧めです。
recent-dirs-max
ファイルに保存するディレクトリの最大数。 デフォルトは 20
recent-dirs-prune
履歴として積まない ディレクトリを指定する
-
parent
ディレクトリリストから 親(祖先)を追加しない。
ホームディレクトリから~/some
→~/some/dirs
と移動したとする
この時~
と~/some
は リストに追加されない。 -
pattern:<patten>
追加しないパターンを指定できる。
recent-dirs-pushd
trueに設定すると、 cdrで pushdを使用するため ディレクトリスタックが積まれる。
ドキュメントにもあるが、 cdr ではディレクトリリストを使用するので こいつを設定するのはあんまり意味がない。
まとめ
まとめというか、ディレクトリ操作に関する.zshrcの記述
# -------------------
# changing directories
# -------------------
cdpath=(~)
setopt auto_cd
setopt auto_pushd
setopt pushd_minus
setopt pushd_ignore_dups
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
add-zsh-hook chpwd chpwd_recent_dirs
zstyle ':chpwd:*' recent-dirs-default true
zstyle ':chpwd:*' recent-dirs-max 500
zstyle ':chpwd:*' recent-dirs-file \
$HOME/.cache/shell/.chpwd-recent-dirs-${TTY##*/} +
zstyle ':chpwd:*' recent-dirs-prune 'parent'
zstyle ':completion:*' recent-dirs-insert always
補足
chpwd_recent_dirs
に合わせてディレクトリスタック
も使用する設定にしている。
・過去移動したことあるディレクトリへの移動 →cdr
・最近移動したディレクトリへの移動 → cd -
でディレクトリ補完
という感じで用途を切り分けてます。前者に関しては筆者は + fzfで絞り込みしてます。
zstyle ':chpwd:*' recent-dirs-file \
$HOME/.cache/shell/.chpwd-recent-dirs-${TTY##*/} +
この部分はmanにも記載のある設定です。端末毎にディレクトリリストを分けることが可能です。