Endless Parentheses

Concise ramblings on Emacs productivity.

Support on Gratipay
profile for Malabarba on Stack Exchange

Flycheck a directory and report the results

This weekend I found myself doing some heavy-weight refactoring in CIDER. This is the kind of situation where Flycheck helps a lot, but I still needed it to do a bit more. Every time I made a significant change to a file, I had to visit 3 or 5 other files and trigger Flycheck on each one of them. It wasn’t long before I decide there had to be a way to just Flycheck a whole directory.

Enter endless/flycheck-dir. This command runs Flycheck on all files in the current directory and reports the result to the *Compile-Log* buffer. You can then navigate through all issues for the entire directory by TAB-ing through the buffer or using next-error.

(define-key flycheck-command-map "d"
#'endless/flycheck-dir)
(defun endless/flycheck-dir (dir)
"Run flycheck for each file in current directory.
Results are reported in a compilation buffer."

(interactive "DDirectory: ")
(displaying-byte-compile-warnings
(let ((p nil))
(with-current-buffer (get-buffer-create
byte-compile-log-buffer)
(setq default-directory dir)
(unless (eq major-mode 'compilation-mode)
(compilation-mode))
(goto-char (point-max))
(let ((inhibit-read-only t))
(insert "\n\xc\n\n"))
(setq p (point)))
(dolist (file (directory-files "./" nil
"\\`[^\\.].*\\'"))
(endless/-flycheck-file file))
(with-selected-window (display-buffer
byte-compile-log-buffer)
(goto-char p)
(recenter 1)))))

(defun endless/-report-error (fmt &rest args)
"Print an error on `byte-compile-log-buffer'."
(let ((inhibit-read-only t)
(fill-prefix " "))
(with-current-buffer byte-compile-log-buffer
(let ((l (point)))
(insert "\n" (apply #'format fmt args))
(fill-region (1+ l) (point))))))

(defun endless/-flycheck-file (file)
"Check FILE and report to `byte-compile-log-buffer'."
(let ((was-visited (find-buffer-visiting file)))
(with-current-buffer (or was-visited
(progn (find-file file)
(current-buffer)))
(when (ignore-errors (flycheck-buffer))
(while (flycheck-running-p)
(accept-process-output nil 0.1))
(pcase flycheck-last-status-change
((or `errored `suspicious)
(endless/-report-error
"%s: Something wrong here!"
(file-name-nondirectory (buffer-file-name))))
(`finished
(dolist (e flycheck-current-errors)
(endless/-report-error
"%s:%s:%s:%s: %s"
(file-name-nondirectory (buffer-file-name))
(flycheck-error-line e)
(flycheck-error-column e)
(flycheck-error-level e)
(flycheck-error-message e))))))
(if was-visited
(bury-buffer was-visited)
(kill-buffer (current-buffer))))))

Tags: programming, flycheck, init.el, emacs

Support on Gratipay
comments powered by Disqus