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*)