index all rss twitter github linkedin email

Álvaro Ramírez

17 July 2015 Open closest build file in Emacs

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