locate-executable
標準添付の executable-find が全く同じ機能でした。 *1
d:id:elim:20080126:1201802151 のコードは e21 と e22 の時で結果が変わってしまう可能性がありました。
以下のような状況を想定します。
- exec-path が ("~/bin" "/bin")
- ~/bin/foo.bat と /usr/bin/foo.exe がある
e21 の場合、(concat name exec-suffixes) ではじめに見付かったものになるので /usr/bin/foo.exe が返ってきます。
e22 の場合、exec-path の中ではじめに見付かったものになるので ~/bin/foo.bat が返ります。
結果を同じにするべく、以下のように書き換えてみました。
(defun locate-executable (name) (if (and (boundp 'exec-suffixes) (fboundp 'locate-file)) ;; emacs22 feature (locate-file name exec-path exec-suffixes 'file-executable-p) (let ((exec-suffixes (list nil ".exe" ".com" ".cmd" ".bat"))) (caar (remove nil (mapcar #'(lambda (path) (remove nil (mapcar #'(lambda (suffix) (locate-library (concat name suffix) nil (list path))) exec-suffixes))) exec-path))))))
- exec-path を順に取り出す
- 取り出した exec-path の各要素に対して
- exec-suffixes を順に取り出し、 name と結合させファイル名を作る
- 作り出したファイル名が存在するか確認させる
- caar で一番若い要素を抜く
これで e21 の場合も e22 の場合も同じ値が求まります。
あ、e21 の時は file-executable-p を通していない……。
また今度。