refactor(format): replace with apheleia

Initial refactor of format module to replace format-all with apheleia
This commit is contained in:
Ellis Kenyő
2022-08-16 08:13:55 +01:00
committed by Ellis Kenyo
parent a44e8d6bfd
commit 4ecd616cd8
9 changed files with 126 additions and 585 deletions

View File

@@ -1,89 +1,54 @@
;;; editor/format/config.el -*- lexical-binding: t; -*-
(defvar +format-on-save-enabled-modes
'(not emacs-lisp-mode ; elisp's mechanisms are good enough
sql-mode ; sqlformat is currently broken
tex-mode ; latexindent is broken
latex-mode
org-msg-edit-mode) ; doesn't need a formatter
"A list of major modes in which to reformat the buffer upon saving.
If this list begins with `not', then it negates the list.
If it is `t', it is enabled in all modes.
If nil, it is disabled in all modes, the same as if the +onsave flag wasn't
used at all.
Irrelevant if you do not have the +onsave flag enabled for this module.")
(defvar +format-preserve-indentation t
"If non-nil, the leading indentation is preserved when formatting the whole
buffer. This is particularly useful for partials.
Indentation is always preserved when formatting regions.")
(defvar-local +format-with nil
"Set this to explicitly use a certain formatter for the current buffer.")
(defvar +format-with-lsp t
"If non-nil, format with LSP formatter if it's available.
This can be set buffer-locally with `setq-hook!' to disable LSP formatting in
select buffers.")
(defvaralias '+format-with 'apheleia-formatter
"Set this to explicitly use a certain formatter for the current buffer.")
;;
;;; Bootstrap
(add-to-list 'doom-debug-variables 'format-all-debug)
(defun +format-enable-on-save-maybe-h ()
"Enable formatting on save in certain major modes.
This is controlled by `+format-on-save-enabled-modes'."
(or (cond ((eq major-mode 'fundamental-mode))
((string-prefix-p " " (buffer-name)))
((and (booleanp +format-on-save-enabled-modes)
(not +format-on-save-enabled-modes)))
((and (listp +format-on-save-enabled-modes)
(if (eq (car +format-on-save-enabled-modes) 'not)
(memq major-mode (cdr +format-on-save-enabled-modes))
(not (memq major-mode +format-on-save-enabled-modes)))))
((not (require 'format-all nil t))))
(format-all-mode +1)))
(when (modulep! +onsave)
(add-hook 'after-change-major-mode-hook #'+format-enable-on-save-maybe-h))
(add-hook 'doom-first-file-hook #'apheleia-global-mode))
;;
;;; Hacks
;; Allow a specific formatter to be used by setting `+format-with', either
;; buffer-locally or let-bound.
(advice-add #'format-all--probe :around #'+format-probe-a)
(defadvice! +format--inhibit-reformat-on-prefix-arg-a (orig-fn &optional arg)
"Make it so \\[save-buffer] with prefix arg inhibits reformatting."
:around #'save-buffer
(let ((apheleia-mode (and apheleia-mode (member arg '(nil 1)))))
(funcall orig-fn)))
;; Doom uses a modded `format-all-buffer', which
;; 1. Enables partial reformatting (while preserving leading indentation),
;; 2. Applies changes via RCS patch, line by line, to protect buffer markers
;; and avoid any jarring cursor+window scrolling.
(advice-add #'format-all-buffer--with :override #'+format-buffer-a)
(add-hook! 'apheleia-post-format-hook
;; HACK `web-mode' doesn't update syntax highlighting after arbitrary buffer
;; modifications, so we must trigger refontification manually.
(defun +format--fix-web-mode-fontification-h ()
(when (eq major-mode 'web-mode)
(setq web-mode-fontification-off nil)
(when (and web-mode-scan-beg web-mode-scan-end global-font-lock-mode)
(save-excursion
(font-lock-fontify-region web-mode-scan-beg web-mode-scan-end)))))
(defun +format--refresh-git-gutter-h ()
(when (bound-and-true-p git-gutter-mode)
(git-gutter))))
;; format-all-mode "helpfully" raises an error when it doesn't know how to
;; format a buffer.
(add-to-list 'debug-ignored-errors "^Don't know how to format ")
;; Don't pop up imposing warnings about missing formatters, but still log it in
;; to *Messages*.
(defadvice! +format--all-buffer-from-hook-a (fn &rest args)
:around #'format-all-buffer--from-hook
(letf! (defun format-all-buffer--with (formatter mode-result)
(when (or (eq formatter 'lsp)
(eq formatter 'eglot)
(condition-case-unless-debug e
(format-all--formatter-executable formatter)
(error
(message "Warning: cannot reformat buffer because %S isn't installed"
(gethash formatter format-all--executable-table))
nil)))
(funcall format-all-buffer--with formatter mode-result)))
(apply fn args)))
;;
;;; Additional formatters
(after! apheleia-mode
;; TODO html-tidy
)