Finding project files in Emacs

When I find myself repeating the same operations over and over, it's time to timebox some automation to preserev my meaty appendages.

I found myself once again wanting to open the .gitignore file at the root of a project, and decided I should setup a convenient binding to save my feeble fingers from having to punch in another SPC .giti RET.

Fortunately, I already had an autoloaded interactive function for finding a project’s README, so only a little refactoring was required.

We start by parameterising the existing function, which leans on Projectile and Doom to do the heavy-lifting.

;;;###autoload
(defun +jcf-find-project-file (pattern)
  (let* ((project-root (projectile-ensure-project (projectile-project-root)))
         (paths (doom-files-in (list project-root)
                               :type 'files
                               :depth 1
                               :match pattern))
         (path (car paths)))
    (if path
        (progn
          (find-file path)
          (run-hooks 'projectile-find-file-hook))
      (message "No file matching %s found in %s." pattern project-root))))

When a matching file is found in the project root, we visit that file and run Projectile’s projectile-find-file-hook. If memory serves, that was to ensure the list of cached project files would update.

And with that, the existing README finder and a new .gitignore finder are trivial to add.

;;;###autoload
(defun +jcf/find-project-README ()
  (interactive)
  (+jcf-find-project-file (rx "readme")))

;;;###autoload
(defun +jcf/find-project-gitignore ()
  (interactive)
  (+jcf-find-project-file (rx ".gitignore")))

Binding these functions in my case is very Doom specific, relying on the built-in map! macro.

(map! :leader
      (:prefix ("g" . "git")
       :desc "Find ignore file" "i" #'+jcf/find-project-gitignore))

Now I just need to work out why all the indetation rules have changed inside that map! macro.