rcmdnk's blog

【Amazon.co.jp限定】Transcend microSDHCカード 32GB Class10 (無期限保証) TS32GUSDHC10E (FFP)

だいぶ前に書いた ターミナルでのディレクトリ移動 にも書いていたターミナル移動用の関数のアップデート。

multi_clipboard をアップデートしている時に導入した画面上で選択する方法が便利だったので こちらにも入れてみたのと、タブ補完など色々付け足し。

前までの設定

ターミナルでのディレクトリ移動

ここにあるようにsd(save directory)というコマンドで現在のディレクトリを保存しておいて、 cl(change to the last directory)でその保存したディレクトリに進む、という設定です。

一番の目的はGnu screen等を使っていて、一方のウィンドウで居るディレクトリに もう一方のウィンドウでも直ぐに移動したい時に使います。

Bash等だと、同じような事ができるpushdpopdというbuiltinコマンドがありますが、 これだと各プロセス毎なのでscreen上の他のウィンドウと共有するためには sdclが必要です。

この時点で、複数個のディレクトリを保存しておいて、過去の保存した物の中から選べる、 みたいなことまではしてましたが、 一覧を全部だして、そこで番号で選ぶ、と言った形で、 リストが長くなるとスクロールして上に行かないと確認出来なかったりしていました。

新しい設定: sd_cl

という訳で、色々アップデートしたのがこちらのレポジトリにあるsd_cl

基本的にsdclコマンドを使うのは上と一緒です。

今回アップデートする上で、BashとZsh両方で使えるようにしました。

関数を直接定義するのでZshをきちんと書かざるを得なくて、 色々その時にひっかかったのを書いたのがこの話。

BashとZshの違いでのハマりどころ

また、今回は

  • GNU screenで各ウィンドウのディレクトリも自動で別に保存しておいて 直ぐに呼び出せるようにする

という機能も入れたので、 この時についでにtmuxにも対応する様にしてあります。

インストール

インストールは上のレポジトリにあるファイルをREADMEにあるようにcurlやHomebrewでインストール後、 .bashrcまたは.zshrcから読み込む様にします。

基本的には読みこむだけで使えますが、 色々設定したい場合はREADMEにしたがってパラメーターを調節して下さい。

特に、.zshrcの中ですでに

autoload -Uz compinit
compinit

的なことをしてる場合には、必ずこれより後でsourceして、また、 中で2重に呼ばない様に(デフォルトだとsd_clの中でこの設定を呼ぶので)、

export NOCOMPINIT=0

の設定をsd_clsourceする前にしておいて下さい。

基本的な使い方

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というコマンド:

cdd を tmux, bash, multi session +α に対応した - @m4i’s blog

と見つけてこの中でできている様なものは取り入れようと思ってやってみた感じです。

Vim file explorerライクな移動

ちょっとしたお遊び感覚ですが、上の機構を使って、 Vimの中のfile explorer的な動きでディレクトリ移動できる様にもしました。

$ cl -v

とすると、現在のディレクトリにあるディレクトリ一覧と../が 選択できるようになるので通常のcl -cと同様に選択し、移動します。 cl -vの場合は一回Enterを押しても終了せずに、 新しいディレクトリで再びリストを作ります(一番上にカレントディレクトリが出ます。

こんな感じ。

clv

最後にqを押すとその場で終了します。

その他設定される関数、エイリアス

sd_clをそのまま読み込んだ場合、cdを上書きして popdを毎回行う様にします。

また、aliasとして

alias bd='popd >/dev/null'

を設定してあり(bd, back directory)、cdで進んだ後、 bdできた道を戻れる様にしてあります。 pushdpopdだと少し感覚とずれる部分があったので その辺りを補正してあります1

また、もう一つ、良く使うcd関連の関数として

1
2
3
function cdpwd () {
  cd -P .
}

という関数を入れてあります。 シンボリックリンクをたどった先のディレクトリなどにいる場合、 cdpwdとすることで、シンボリックリンクを解いた 実際のディレクトリへ移動する事が出来ます。

cd/chpwdを自分で設定する

もし、cdchpwdといった関数を既に他で設定している場合には

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 "$@"に変更)。

Sponsored Links
  1. 自分の感覚でなので余計だと思ったら下に書くようにexport ISCDWRAP=0 でこの設定だけ無効にもできます。

Sponsored Links

« BashとZshの違いでのハマりどころ Font Awesomeをアップデート »

}