Whether it's Makefile, SConstruct, BUILD, or your favorite build file, chances are you have to tweak it from time to time. ar/open-build-file
searches your current and parent directories to find a build file.
(defvar ar/project-file-names '("Makefile" "SConstruct" "BUILD"))
(defun ar/parent-directory (path)
"Get parent directory for PATH."
(unless (equal "/" path)
(file-name-directory (directory-file-name path))))
(defun ar/find-upwards (path filename)
"Search upwards from PATH for a file named FILENAME."
(let ((file (concat path filename))
(parent (ar/parent-directory (expand-file-name path))))
(if (file-exists-p file)
file
(when parent
(ar/find-upwards parent filename)))))
(defun ar/open-closest (filename)
"Open the closest FILENAME in current or parent dirs (handy for finding Makefiles)."
(let ((closest-file-path (ar/find-upwards (buffer-file-name)
filename)))
(when closest-file-path
(message closest-file-path)
(switch-to-buffer (find-file-noselect closest-file-path)))
closest-file-path))
(defun ar/open-build-file ()
"Open the closest project file in current or parent directory.
For example: Makefile, SConstruct, BUILD, etc.
Append `ar/project-file-names' to search for other file names."
(interactive)
(catch 'found
(mapc (lambda (filename)
(when (ar/open-closest filename)
(throw 'found t)))
ar/project-file-names)
(error "No project file found")))