Flymake for private config

I am trying out flymake instead of flycheck (mostly because flycheck had some problem with eglot and switching to flymake) fixed it.

The two things I am missing are

  1. The modeline indicator but that is a small thing and I think I should be able to recreate it.

  2. Sensible errors in my private doom config. When I enable flycheck errors I get inundated by errors which are relevant in an elisp package but not my private config. Those coming from checkdoc I can disable by removing elisp-flymake-checkdoc from flymake-diagnostic-functions but how do I disable those warning about function not known to be defined etc? I try looking at the flycheck module but there doesn’t seem to be anything there that would take care of this.

1 Like

To give a partial answer to my own question, I have this in my config now:

(add-hook 'emacs-lisp-mode-hook
            (defun my-elisp-flymake-hook ()
              (when (doom-real-buffer-p (current-buffer))
                (when (seq-find (lambda (dir) (file-in-directory-p (buffer-file-name) dir))
                                '("~/.config" "~/.doom.d" "~/.emacs.d/lisp" "~/.emacs.d/modules"))
                  (setq flymake-diagnostic-functions '(my-elisp-config-flymake-byte-compile)))
                (flymake-mode))))

(cl-callf append elisp-flymake-byte-compile-load-path load-path)

And the function my-elisp-config-flymake-byte-compile is a modified version of elisp-flymake-byte-compile which passes some extra args to the emacs process:

(defun my-elisp-config-flymake-byte-compile (report-fn &rest _args)
  "A Flymake backend for elisp byte compilation.
Spawn an Emacs process that byte-compiles a file representing the
current buffer state and calls REPORT-FN when done."
  (when elisp-flymake--byte-compile-process
    (when (process-live-p elisp-flymake--byte-compile-process)
      (kill-process elisp-flymake--byte-compile-process)))
  (let ((temp-file (make-temp-file "elisp-flymake-byte-compile"))
        (source-buffer (current-buffer))
        (coding-system-for-write 'utf-8-unix)
        (coding-system-for-read 'utf-8))
    (save-restriction
      (widen)
      (write-region (point-min) (point-max) temp-file nil 'nomessage))
    (let* ((output-buffer (generate-new-buffer " *elisp-flymake-byte-compile*")))
      (setq
       elisp-flymake--byte-compile-process
       (make-process
        :name "elisp-flymake-byte-compile"
        :buffer output-buffer
        :command `(,(expand-file-name invocation-name invocation-directory)
                   "--batch"
                   "--eval" "(setq byte-compile-warnings '(not unresolved docstrings))"
                   "-l" "~/.emacs.d/lisp/doom.el"
                   "-l" "~/.emacs.d/lisp/doom-start.el"
                   ;; "--eval" "(setq load-prefer-newer t)" ; for testing
                   ,@(mapcan (lambda (path) (list "-L" path))
                             elisp-flymake-byte-compile-load-path)
                   "-f" "elisp-flymake--batch-compile-for-flymake"
                   ,temp-file)
        :connection-type 'pipe
        :sentinel
        (lambda (proc _event)
          (unless (process-live-p proc)
            (unwind-protect
                (cond
                 ((not (and (buffer-live-p source-buffer)
                            (eq proc (with-current-buffer source-buffer
                                       elisp-flymake--byte-compile-process))))
                  (flymake-log :warning
                               "byte-compile process %s obsolete" proc))
                 ((zerop (process-exit-status proc))
                  (elisp-flymake--byte-compile-done report-fn
                                                    source-buffer
                                                    output-buffer))
                 (t
                  (funcall report-fn
                           :panic
                           :explanation
                           (format "byte-compile process %s died" proc))))
              (ignore-errors (delete-file temp-file))
              (kill-buffer output-buffer))))
        :stderr " *stderr of elisp-flymake-byte-compile*"
        :noquery t)))))

The extra args silence the byte compiler warnings about free variables and functions not known to be defined (since they are mostly false positives for the config) and docstring problems. They are also used to load the doom.el so that the core doom stuff is defined and byte-compiler can warn about wrong calling conventions etc.

It would be better to be able to load enabled modules as well but I haven’t figured out that part yet.

1 Like