だいぶ前に書いた ターミナルでのディレクトリ移動 にも書いていたターミナル移動用の関数のアップデート。
multi_clipboard をアップデートしている時に導入した画面上で選択する方法が便利だったので こちらにも入れてみたのと、タブ補完など色々付け足し。
前までの設定
ここにあるようにsd
(save directory)というコマンドで現在のディレクトリを保存しておいて、
cl
(change to the last directory)でその保存したディレクトリに進む、という設定です。
一番の目的はGnu screen等を使っていて、一方のウィンドウで居るディレクトリに もう一方のウィンドウでも直ぐに移動したい時に使います。
Bash等だと、同じような事ができるpushd
、popd
というbuiltinコマンドがありますが、
これだと各プロセス毎なのでscreen上の他のウィンドウと共有するためには
sd
、cl
が必要です。
この時点で、複数個のディレクトリを保存しておいて、過去の保存した物の中から選べる、 みたいなことまではしてましたが、 一覧を全部だして、そこで番号で選ぶ、と言った形で、 リストが長くなるとスクロールして上に行かないと確認出来なかったりしていました。
新しい設定: sd_cl
という訳で、色々アップデートしたのがこちらのレポジトリにあるsd_cl
。
基本的にsd
とcl
コマンドを使うのは上と一緒です。
今回アップデートする上で、BashとZsh両方で使えるようにしました。
関数を直接定義するのでZshをきちんと書かざるを得なくて、 色々その時にひっかかったのを書いたのがこの話。
また、今回は
- GNU screenで各ウィンドウのディレクトリも自動で別に保存しておいて 直ぐに呼び出せるようにする
という機能も入れたので、 この時についでにtmuxにも対応する様にしてあります。
インストール
インストールは上のレポジトリにあるファイルをREADMEにあるようにcurlやHomebrewでインストール後、
.bashrc
または.zshrc
から読み込む様にします。
基本的には読みこむだけで使えますが、 色々設定したい場合はREADMEにしたがってパラメーターを調節して下さい。
特に、.zshrc
の中ですでに
autoload -Uz compinit
compinit
的なことをしてる場合には、必ずこれより後でsource
して、また、
中で2重に呼ばない様に(デフォルトだとsd_cl
の中でこの設定を呼ぶので)、
export NOCOMPINIT=0
の設定をsd_cl
をsource
する前にしておいて下さい。
基本的な使い方
sd
の方は以前同様現在居るディレクトリを保存するだけです。
cl
の方も、何も引数なしなら最後に保存したディレクトリに行きます。
-l
で一覧表示(${PAGER:-less}
を使います)、
-n
でn番目のディレクトリに移動、などはほとんど以前と同じです。
(その他のオプションはcl -h
またはレポジトリのREADMEで)。
新たに-c
とした時に、multi_clipboard
のとこで取り入れたselection mode
の様に、
一覧を表示してj/k
等で選択項目を変更してEnterで選んで移動、
的なことを出来るようにしました。
こんな感じです。
この中でd
で保存してあるディレクトリを削除したりも出来る様になりました。
Pre-defined directory list
さらに、通常のsd
保存ディレクトリリストに加え、
-p
を使うことで予め設定しておいたディレクトリ群の中から選べる様にもしました。
こちらのリストはsd
で変更されないので、常によく使うディレクトリを入れておくと便利です。
設定ファイルは${PREDEFDIRFILE:-$HOME/.predefDir}
。
一行に1ディレクトリで書き込みます。
直接ファイルを編集するか、sd
コマンドでsd -e
とすると
このファイルを${EDITOR:-"vim"}
で立ち上げて編集することが出来ます。
また、上の保存ディレクトリリストで選択中(cl -c
)、
p
を押すとPREDEFDIRFILE
へ追加できます。
Window directory list
-w
を使うとGNU screen/tmuxの中だと各WindowのWindow番号、Pane番号(screen時は常に0)
そしてディレクトリ、が表示されます。
これらのディレクトリは各ウィンドウでディレクトリ移動した際に
自動的に保存、更新されるようにcd
(Bash)やchpwd
(Zsh)がsd_cl
の中で設定されています。
タブ補完
タブを押した時にリストからディレクトリを補完し、直接各ディレクトリへ 移動できるようにもしました。
cl
、cl -p
、cl -w
をタイプした後にタブを押すと
それぞれsdで保存したリスト
、Pre-definedリスト
、各Windowのディレクトリリスト
で補完されます。
補完を使いながらリストにあるディレクトリを書き込んで実行すればそのディレクトリへ 直接移動します。
cl -w
の場合には、補完が
"Window Number" "Pane Number" "Directory"
の形でそれぞれ表示されるので、書き込む時もWindow Numberからで。 Window Numberだけでも移動できて、
$ cl -c 3
とすればWindow 3と同じディレクトリへ移動します。 (tmuxで複数Paneがある場合は各Windowの最初のPaneを使う)。
$ cl -c 3 4
とすればWindow 3のPane 4と同じディレクトリへ移動できます。
この辺りの補完とか各Windowでのディレクトリを使う部分は
アップデート途中で似たようなことをしているcdd
というコマンド:
と見つけてこの中でできている様なものは取り入れようと思ってやってみた感じです。
Vim file explorerライクな移動
ちょっとしたお遊び感覚ですが、上の機構を使って、 Vimの中のfile explorer的な動きでディレクトリ移動できる様にもしました。
$ cl -v
とすると、現在のディレクトリにあるディレクトリ一覧と../
が
選択できるようになるので通常のcl -c
と同様に選択し、移動します。
cl -v
の場合は一回Enterを押しても終了せずに、
新しいディレクトリで再びリストを作ります(一番上にカレントディレクトリが出ます。
こんな感じ。
最後にq
を押すとその場で終了します。
その他設定される関数、エイリアス
sd_cl
をそのまま読み込んだ場合、cd
を上書きして
popd
を毎回行う様にします。
また、aliasとして
alias bd='popd >/dev/null'
を設定してあり(bd, back directory)、cd
で進んだ後、
bd
できた道を戻れる様にしてあります。
pushd
、popd
だと少し感覚とずれる部分があったので
その辺りを補正してあります1。
また、もう一つ、良く使うcd関連の関数として
1 2 3 |
|
という関数を入れてあります。
シンボリックリンクをたどった先のディレクトリなどにいる場合、
cdpwd
とすることで、シンボリックリンクを解いた
実際のディレクトリへ移動する事が出来ます。
cd/chpwdを自分で設定する
もし、cd
やchpwd
といった関数を既に他で設定している場合には
export ISPOSTCD=0 # Don't do automatic save
export ISCDWRAP=0 # Don't wrap for pushd
として上書きを無効化し、必要であれば、補助関数post_cd
及びwrap_cd
を加えて下さい。
Bashの場合、screen/tmuxでのWindow事のディレクトリの上記自動保存を有効にしたい場合は
builtin cd "$@"
local ret=$?
if [ $ret -eq 0 ];then
post_cd
fi
return $ret
的な感じでcd
の関数の中でpost_cd
を呼んで下さい。
Zshの場合はchpwd
の中でpost_cd
を呼んで下さい。
pushd
のwrapをしたい場合は、Bash/Zsh共に
cd
の関数の中で、実際にcd
する場所を
wrap_cd "$@"
に置き換えます(Bashでpost_cd
と共に使いたい場合は上のbuiltin cd "$@"
の部分を
wrap_cd "$@"
に変更)。
-
自分の感覚
でなので余計だと思ったら下に書くようにexport ISCDWRAP=0
でこの設定だけ無効にもできます。 ↩