パーソナル locate プログラムを作りました
以前「巨大なディレクトリ構造でもフラットに find-file する」(*) というエントリを書きましたが、そのプログラムを実用にたえる程度に書きなおしたので再び紹介します。前回のプログラムでは slocate に依存した Perl スクリプトでしたが、今回は C 言語で根本的なロジックから書き直しています。なので、 slocate 特有のクセのつよい仕様も回避することができました。
(*) http://dev.ariel-networks.com/Members/matsuyama/flat-find-file
インストール
以下から tar ボールをダウンロードして下さい。
http://dev.ariel-networks.com/Members/matsuyama/stuff/path-1.0.tar.gz/download
最新のソースコードは以下から取得することができます。
https://kserver.panicode.com/panicode/path/trunk/
% tar xvzf path-1.0.tar.gz % cd path-1.0 % make % sudo cp path /usr/bin/path
とすればインストール完了です。 Emacs モジュールを使う場合は path.el を load-path の通ったディレクトリにインストールして、 .emacs に以下のコードを追加してください。
.emacs:
(autoload 'path-goto-path "path" nil t) (autoload 'path-find-file "path" nil t) (global-set-key "\C-x\C-g" 'path-goto-path) (global-set-key "\C-x\M-f" 'path-find-file)
使用方法
データベースの構築/更新
このプログラムを使用するには、まずデータベースを構築する必要があります。検索対象にしたいディレクトリに cd するか、 -d オプションで検索対象を指定してデータベースの更新を行えば、そのディレクトリに PATH という独自データベースファイルが作成されます。そのファイルがすでに存在する場合はデータベースの更新が実行されます。
% cd ~/music % path -u # 音楽ファイルを検索対象にする % path -u # データベース更新 % path -d ~/music -u # 上と同じ
原理は locate と同じで、データベースには最後に更新された時のディレクトリの全エントリ名が格納され、検索時にデータベースからファイルパスを復元してマッチを行います。
除外ルール
通常は特に気にする必要はないのですが、 .svn などデータベースに格納したくないエントリ名を含んだディレクトリでデータベースの構築を行いたい時のために、特定の文字列にマッチした場合にその名前を除外する -e オプションと -E オプションを提供しています。 slocate にも -e オプションはありますが、こちらはフルパスの完全一致しかできないので実質 .svn を除外することができません。その点、このプログラムは -e オプションで部分一致、 -E オプションで POSIX 拡張正規表現になり、自由度の高い除外機能を実現しています。
また、前述したように slocate ではフルパスに対してのマッチしかできませんが、このプログラムでは -p オプションを指定することでデフォルトのマッチ対象をエントリ名からフルパスに切り換えることができます。
具体的に例を示しますと、
% path -e .svn -u # エントリ名に .svn が含まれる場合に除外(子供も除外) % path -E '\.(cpp|h)$' -u # 拡張子が cpp か h の場合に除外 % path -p -e src/tmp -u # フルパスに src/tmp が含まれる場合に除外
となります。
なお、一度 -e オプションや -E オプションで除外ルールを指定すれば、次回のデータベースの更新時にもその設定がうけつがれます。なので、邪魔なエントリがデータベースに混ざっていて、新しく除外ルールを追加したいときにも、以前の除外ルールをタイプしなおす必要がありません。
除外ルールをクリアしてデータベースを更新したい場合は、 -u オプションのかわりに -U オプションを使います。
エントリの検索
データベースの構築が完了したら、実際にエントリの検索を行うことができます。
% cd ~/music % path .mp3 /home/tomo/music/hoge1.mp3 /home/tomo/music/hoge2.mp3 ...
POSIX 拡張正規表現を使うには -r オプションを指定します。
% path -r '\.(mp3|ogg|ape)$'
-Q オプションを指定すれば、ダブルクォーテーションによってクォートされたパスが出力されます。このオプションは xargs にパイプする時に面倒な問題が起こらないようにするために付けました。
% path -Qr '\.(mp3|ogg)$' | xargs mplayer
予備知識ですが、データベースファイルを持つディレクトリ以下ならどこからでもこのプログラムを利用することができます。
% cd ~/music % path -u % cd Favorites % pwd /home/tomo/music/Favorites % path -P # -P はデータベースファイルの場所を表示するオプション /home/tomo/music/PATH % path .mp3 ...
Emacs での使用方法
Emacs での使用方法といっても、基本的にただのフロントエンドなので動作にほとんど変わりはありません。違うといえばカレントディレクトリの変わりに default-directory が使用されることぐらいでしょう。
path.el は主に以下の二つの関数を提供しています。
path-goto-path
補完なしにミニバッファに入力された文字列で検索を実行します。候補が一個しかない場合はそのまま find-file します。候補が複数個ある場合は find-file するパスを選択するバッファに切り替わります。
path-goto-path の欠点は補完がきかないことでしょう。しかし開こうとしているファイル名はすでに知っていることが前提なので、特に問題はないと思っています。
(例)``M-x path-goto-path RET o RET``
以下のディレクトリ構造に対して実行。
% ls ** PATH abc foo foobar hoge dir_x: Hello world dix_y:
この例では、 path-goto-path の結果( o をエントリ名に含むパス)が複数個あるので、パスを選択するバッファに切り替わっています。前述したように、結果が一つしかない場合はそのまま find-file します。
path-find-file
path-goto-path とは違いエントリ名に対して補完を実行することができます。補完方式は completing-read に依存しています。簡単に言えばミニバッファで一般的に使われる補完機能をそのまま使うことができます( Emacs の設定に依存)。ただ問題としては、エントリが大量にある場合にメモリを無尽蔵に使うこと、 path-find-file の動作が遅くなる点です。データベースの大きさを適切に認識して使う必要があります。
(例)M-x path-find-file [TAB]
何も入力せずに TAB を押すと全エントリが *Completions* に一覧されます。
# 画像のミニバッファの入力で ‘‘File file: `` となっているのは愛嬌。最新ではなおっています。
(例)M-x path-find-file foo[TAB]
foo に一致するのは foo と foobar があるので正しく補完がきいていることがわかります。
使用用途
Java を使用しているソフトウェアのソースコードディレクトリに対してデータベースを構築して、 Emacs から簡単に find-file したいというのが、このプログラムを開発した動機です。例にも示しましたが、それ以外にも音楽ディレクトリに対してデータベースを構築するなど、いろいろな使用方法があると思います。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/personal-locate-program/tbping