zsh で cd する時の TAB 補完で、カレントディレクトリに存在しないディレクトリの名前が候補一覧に出てきて、``キーっ′′となった事はないだろうか。
私はあります。
多い時では週4回くらい、少なくても3週間に1回は``キーっ′′となります。
例えば、cd a<TAB補完> とすると下記のように、adm や apache が候補に現れます。
もちろんカレントディレクトリに adm や apache というディレクトリは存在しません。
% cd a<TAB補完> adm apache
その他、d , g , n , s 等でも補完されます。
% cd d<TAB補完> daemon dbus distcache
% cd g<TAB補完> games gopher
% cd n<TAB補完> news nobody nscd ntp
% cd s<TAB補完> shutdown smmsp sshd sync
候補に出現する名前は環境によって異なりますので、必ずしも上記のようになるとは限りません。
どうやら候補に出現する名前は /etc/passwd のユーザー名に由来しているようです。
これの何が問題かといえば、例えば、alonglongdirname という名前のディレクトリが1つしか存在しない状態で、
cd a<TAB補完> として、一発で alonglongdirname に入りたいが、候補に adm や apache が出てくるので、
数回<TAB補完>するか、あるいは cd al<TAB補完> としなくてはなりません。
% ls alonglongdirname/ % cd a<TAB補完> adm alonglongdirname/ apache
adm や apache が候補にあるので、一発の補完で alonglongdirname に移動できない。``キーっ′′
Google で 「zsh cd 補完 adm apache」などと検索しても有用な解決方法は見つけられず、``キーっ′′となる度にいつも苦い思いをしていました。
もちろん「zsh cd 補完 “キーっ”」のキーワードでも見つけられませんでした。
で、、本日、もう``キーっ′′となるのは嫌だ。金輪際ごめんだ。という事で、時間もあったので、
.zshrc の setopt をしらみつぶしに探しました。
具体的には、setopt のそれらしい設定に的を絞って、1つずつ設定を消して、その度に sshログインし直します。
そして、cd a<TAB補完> として、憎き adm や apache が補完されないかを試しました。
source コマンドで .zshrc をリロードした方が早いですが、なぜか source コマンドが効かない時があるので、sshログインをやり直す方式にしました。
そして見つけました!
setopt cdable_vars
犯人は、cdable_vars でした。
これを無効にした状態で、cd a<TAB補完> としても何の反応もありません。やったー!
さっそく cdable_vars について調べると下記の説明が見つかりました。
CDABLE_VARS (-T) If the argument to a cd command (or an implied cd with the AUTO_CD option set) is not a directory, and does not begin with a slash, try to expand the expression as if it were preceded by a ~ (see section Filename Expansion)
訳) cd コマンドの引数がディレクトリでなく、かつ / から始まらない時、~ を付与して展開を試みます。
つまり、cdable_vars を設定することで、
cd a<TAB補完>
は
cd ~a<TAB補完>
として補完されていた為、adm や apache が候補にあがっていたようです。
cdable_vars の設定を .zshrc から外して、無事に解決しました。
おまけ |
---|
今回調べている最中に副産物として、下記を発見しました。
1つ前のパスに戻るために、cd - はよく利用していましたが、
cd -<TAB補完> で、過去に cd したパスの履歴表示が出来ます。
これ知らなかったです。
% cd -<TAB補完> 0 -- / 1 -- /var 2 -- /usr/lib 3 -- /tmp 4 -- /etc/httpd/conf
番号を入力してエンターキーを押すと、対応するパスに移動できます。これは便利