@alvaro
sign in · lmno.lol

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