xyzzyでビルドするときには、C-x &でmakeするのですが、makefileとソースが別のディレクトリにあると、makefileのディレクトリにいってからビルドする必要があって面倒です。というわけで、親ディレクトリをたどっていって、makefileが見つかったところでビルドするコマンドを作ってみました。
(defun parent-directory (directory) (if (string-match "\\(.:/.+/\\)[^/]+/" directory) (string-replace-match directory "\\1") nil)) (defun search-ancestors (directory pred skip) (cond ((not directory) nil) ((funcall pred directory) (if (= skip 0) directory (search-ancestors (parent-directory directory) pred (- skip 1)))) (t (search-ancestors (parent-directory directory) pred skip)))) (defun search-ancestors-file (directory file skip) (search-ancestors directory #'(lambda (directory) (file-exist-p (concat directory file))) skip)) (defun build-ancestor (cmd &optional (file "makefile") (skip 0)) (execute-subprocess cmd nil nil nil (search-ancestors-file (default-directory) file skip))) (defun make (target) (interactive "sTarget: " :history0 'make) (build-ancestor (concat "bash -i -c \"make " target "\"") "makefile")) (defun make1 (target) (interactive "sTarget: " :history0 'make) (build-ancestor (concat "bash -i -c \"make " target "\"") "makefile" 1)) (defun ant (target) (interactive "sTarget: " :history0 'ant) (build-ancestor (concat "ant " target) "build.xml"))
make1は、makeからmakeを呼び出している場合に、親側のmake(一回層親ディレクトリのmakefile)を呼び出します。makeのついでにantも同じことができるようにしました。ついでに、antのエラーメッセージからジャンプできるように以下を追加。
(push (list (compile-regexp " +\\[.+\\] \\(.*\\):\\([0-9]+\\): .*") 1 2) ed::*error-regexp-list*)