ターミナルで作業する上でディレクトリを移動するcd
コマンドは最も多く使われるコマンドだと思います。
ただディレクトリを深く掘ったり多くの作業場があるとすんなり移動出来ずに時間がかかってしまいます。
なのでディレクトリ移動を効率化できればターミナル作業を格段と効率の良いものに出来るはず。
ということで sd_clという移動ツールを作りました。
だいぶ前に作ったものですが、今回のアップデートでディレクトリ選択に
peco
やfzf
と言った好きな選択ツールを選べる様になりました。
sd_cl
シェルスクリプトで作られたディレクトリ移動支援ツールです。
sd_cl
という一つのスクリプトからなっていて、これを適当なところに置いて
$ source /path/to/sd_cl
とするとsd
とcl
というコマンドが使える様になります。
$ curl -fsSL https://raw.github.com/rcmdnk/sd_cl/install/install.sh| prefix=~/usr/local/ sh
とすれば自動で~/usr/local/etc/sd_clにインストールされます。
MacならHomebrewで
$ brew install rcmdnk/rcmdnkpac/sd_cl
としてインストールすることも出来ます。
Bash/Zshの両方で使える様になっているので、使ってるシェルの.bashrc/.zshrcに
source /path/to/sd_cl
を加えてやればsd
/cl
が常に使える様になります。
基本的な使い方
元々GNU screenを使っていて、あるウィンドウのカレントディレクトリに 他のウィンドウで簡単に移動したい、というのがきっかけで作ったものです。
それを実現するためにはWindow 1でsd
(Save directory)として
Window 2でcl
(Change to the Last directory)とするだけ。
(ただし今は-w
オプションでもっと簡単に移動できます。)
sd
したらそのディレクトリは残るので、Window 1でも他のディレクトリに行ったあとに
cl
とすれば元のディレクトリに戻れます。
保存したディレクトリ一覧から選ぶ
sd
で保存したディレクトリはデフォルトで最大20個まで保存されます。
この保存されたディレクトリ一覧から行きたいディレクトリを選ぶ事もできます。
$ cl -l
とすると保存されたディレクトリ一覧が表示され、
$ cl -c
とすれば一覧から選ぶモードに入ります。
この際、もともと sentaku というシェルスクリプトベースの選択ツールが必要でしたが、 今回のアップデートで他の同様のツールも使える様になりました。
また、いずれのツールが入ってない場合でもシンプルなシェルスクリプトベースの選択モードに入ります。
デフォルトでは以下のツールを順に探して見つかったものを使います。
- rcmdnk/sentaku: Utility to make sentaku (selection, 選択(sentaku)) window with shell command. (use
sentaku -s line
option) - peco/peco: Simplistic interactive filtering tool
- mooz/percol: adds flavor of interactive filtering to the traditional pipe concept of UNIX shell
- junegunn/fzf: A command-line fuzzy finder
- jhawthorn/fzy: A better fuzzy finder
- garybernhardt/selecta: A fuzzy text selector for files and anything else you need to select. Use it from vim, from the command line, or anywhere you can run a shell command.
- mattn/gof
- mptre/pick: A fuzzy search tool for the command-line
使いたいツールを指定したい場合には
SD_CL_TOOL=peco
と、SD_CL_TOOL
を.bashrcなどで設定してください。
SD_CL_TOOL=NONE
またはSD_CL_TOOL=shell
とすると組み込まれたシンプルな選択モードに入ります。
絞り込み
$ cl hoge
とするとhoge
という文字列の入ったディレクトリのみを抜き出して
選択モードに入ります。
もし該当するディレクトリが一つしか無ければ直接そのディレクトリに移動します。
この絞り込みや次のタブ補完は後で出てくる他のリストにも有効です。
(ランキングリストからの絞り込みならcl -r hoge
。)
タブ補完
$ cl [Tab]
とタブを押すとリストにあるディレクトリをタブ補完します。
$ cl hoge [[Tab]
とすればhoge
という文字列の入ったディレクトリのみを抜き出してタブ補完を開始します。
補完後、一つだけに絞られればそのディレクトリに移動し、 いくつか候補が残っていれば選択モードに入ります。
番号指定
$ cl 3
の様に数字を与えるとリストのなかのその順番にあるディレクトリに移動できます。
保存ディレクトリ以外のリスト
sd_cl
ではsd
で保存するディレクトリ以外にもディレクトリリストを使うことが出来ます。
Pre-defined directory list
このリストに関しては
$ sd -p
でリストに現在のディレクトリを追加し、
$ cl -p
でリストから選択出来るモードに入ります。
基本的に通常のリストと同じですが、
通常のリストはsd
を使うことでどんどん上書きされてくものだとして、
一方、こちらのリストは良く使うリストを選んで入れておく、という使い方を想定しています。
ディレクトリ数の制限はつけていません。
いちいちディレクトリに行ってsd -p
をするのは面倒、という場合には
$ sd -e -p
とするとエディタ(vi
もしくはEDITOR
で指定されたもの)でリストが開かれるので
それを編集すればOK。
このリストファイルは一行に一つのディレクトリが書いてあるだけのリストなので 必要なディレクトリを一行ごとに書いてあげればOKです。
Window directory list
GNU screenやtmuxを使っている際に各WindowやPaneの今いるディレクトリ一覧を出してくれるリスト。
$ cl -w
で選択モードに入ります。
$ cl -w -l
でリスト表示する際にはディレクトリ名の前にWindow番号とPane番号も表示されます。 (GNU screenの場合はPaneはないのでPane番号は常に0。)
選択モードでもこれらの情報を表示させたい場合には
SD_CL_SHOW_MORE_INFO=1
を設定しておきます。
Ranking directory list
よく使うディレクトリをランキングして表示してくれるリスト。
$ cl -r
で選択モードに入ります。
$ cl -r -l
でリスト表示する際にはランキングスコアも表示されます。
これも
SD_CL_SHOW_MORE_INFO=1
を設定することで
選択モードでも表示するようにできます。
ランキングの仕組みや設定については長くなるのでまた別に書こうと思います。
Back to the history
cd
で移動してきた履歴を使うリスト。
$ cl -b
で選択モードに入ります。
これはpushd
をラップして使っています。
実はsd_cl
を読み込むとcd
コマンドをラップして実際にはpushd
を使って移動する様になります。
追記: 2018/08/19
アップデートしてpushd
などへの依存をなくしました。
代わりに
$ cl -f
で戻ったディレクトリを逆に進むことも出来る様になりました。
追記ここまで
一応通常のcd
の使用感と変わらないようにラップしてありますが、
もしcd
をラップするのが嫌な場合には
SD_CL_ISCDWRAP=0
とするとcd
のラップをしないようになります。
この設定はsd_cl
を読み込む前にしてください。
Vim like file explorer
お遊びみたいなものですが、 Vimのファイルエクスプローラー的なものを選択モードを連続して使うことで実現した機能です。
$ cl -v
とするとVimエクスプローラーモードに入ります。
..
(一つ上のディレクトリ)を含めたディレクトリ一覧が
出るので、そのなかから選ぶとそのディレクトリに移動し
再びそのディレクトリでディレクトリ一覧を取得し選択モードに入ります。
何も選択しないで終了すれば今いるディレクトリにいる状態で終了、というもの。
sd/cl以外の関数、エイリアス
sd_cl
を読み込むとsd
/cl
以外の関数などもロードされます。
- bd (Back Directory): 一つ前のディレクトリに戻る。
cl -b 1
と同様。 - fd (Forward Directory): 一つ先のディレクトリに進む。
cl -f 1
と同様。 - up : 一つ上のディレクトリに移動。
- cdpwd:
cd "$(pwd -P)"
をします。つまりシンボリックリンクを解決して物理パスへ移動します。 - cd: cdのラップ関数。ファイルへのパスを指定するとそのファイルのあるディレクトリへ移動。
cd
へのラップは上にも書いたように
SD_CL_ISCDWRAP=0
とするとcd
のラップをしないようになります。
この設定はsd_cl
を読み込む前にしてください。
sd_cl以外の似たようなツール
他にもディレクトリ移動を効率化しようというツールとして以下のものが有名です。
pushd
/popd
/dirs
シェルの組み込みコマンド。pushd
で履歴を保持しながら移動でき、popd
で前に戻ったりdirs
で履歴を表示したり出来ます。
内容だけ見ればcd
なんて使わずにこちらを使ったほうが断然便利だと思うわけですが、
やはり頻繁に使うコマンドということでp
u
s
h
d
なんて押すよりc
d
のが短い上に
配置も左手で一瞬で押せる位置にあって圧倒的に便利なのでpushd
なんて使ってられない、というのが現実です。
cdをラップしてpushd
みたいに履歴を保存し
$ - # 一つ前に戻る
$ + # 一つ先に進む
$ = # リスト表示
を出来るようにしてくれるシェルスクリプト。
Python製のautojump
というコマンドでディレクトリ選択を行うツール。
実際に使う際には
/usr/local/etc/autojump.shを読み込み
この中(で呼ばれてるファイルの中)で定義されているj
という関数でautojump
を使ってディレクトリを選択し移動します。
ディレクトリリストはPROMPT_COMMAND
の中にautojump_add_to_database
という関数が加えられ
この関数でコマンド終了後にアップデートされます。
使い方は
$ j foo
とするとfoo
を含むディレクトリに移動できます。
このリストにはkey weightが付けられていて 該当するディレクトリが複数ある場合にはweightの最も高いディレクトリに移動します。 key weightはそのディレクトリでどれだけ作業を行ったか、の度合いです。
$ jc foo
とすると現在のディレクトリより下のディレクトリのみを検索します。
またjo
コマンドでファイルエクスプローラーを開いたりも出来ます。
シェルスクリプトで作られたautojump
に似たツール。
z.sh
というファイルを読み込むことでz
というコマンドが使えるようになり、
j
の様に
$ z foo
と言った感じで保存されてるディレクトリの中からfoo
を含むディレクトリを検索して移動します。
z
もPROMPT_COMMAND
に_z --add
というコマンドを追加し毎回ディレクトリリストをアップデートします。
この際にfrecency
(おそらくfrequency+recencyからの造語)という値が各ディレクトリに付けられます。
複数の該当ディレクトリがある場合はこのfrecency
が高いものが選ばれます。
これ以外にもz -t foo
とすれば最も最近使われたもの、
z -r foo
とすれば使用頻度が最も高いものから選ぶことも出来ます。
シェルスクリプトで作られたcd
コマンドのラップツール。
レポジトリにあるファイルをsourceするとcdがラップされます。
$ source ./init.sh
これで
$ cd foo
とするとj
やz
の様にディレクトリリストから検索が行われます。
違うのは複数の候補がある場合はfzy
などの選択ツールを起動し選択モードに入るところです。
enhancdではラップしているcd
の中でリストを更新する用になっています。
weightとかランキングとかはなく、
複数あれば選択ツールで選択する、という方針がautojumpやzと違うところです。
また、cd ..
とすると今いるディレクトリの上の階層のディレクトリからの選択、
cd -
とすると過去の履歴からの選択、といった変化が起こります。