doomemacs/modules/editor/format/config.el

90 lines
3.3 KiB
EmacsLisp
Raw Normal View History

;;; 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.")
2018-09-13 11:15:01 -04:00
(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.")
;;
;;; Bootstrap
(defun +format-enable-for-lsp-on-save-maybe-h ()
"Enable LSP formatter when LSP client is available."
(remove-hook 'lsp-mode-hook #'+format-enable-for-lsp-on-save-maybe-h 'local)
(cond ((not +format-with-lsp) nil)
((bound-and-true-p lsp-mode)
(when (lsp-feature? "textDocument/formatting")
(+format-enable-on-save-h))
t)
((bound-and-true-p eglot--managed-mode)
(when (eglot--server-capable :documentRangeFormattingProvider)
(+format-enable-on-save-h))
t)
((bound-and-true-p lsp--buffer-deferred)
(add-hook 'lsp-mode-hook #'+format-enable-for-lsp-on-save-maybe-h
nil 'local)
t)))
(defun +format-enable-on-save-maybe-h ()
"Enable formatting on save in certain major modes.
This is controlled by `+format-on-save-enabled-modes'."
(and (not (eq major-mode 'fundamental-mode))
(cond ((booleanp +format-on-save-enabled-modes)
+format-on-save-enabled-modes)
((eq (car-safe +format-on-save-enabled-modes) 'not)
(not (memq major-mode (cdr +format-on-save-enabled-modes))))
((memq major-mode +format-on-save-enabled-modes))
((not (require 'format-all nil t))))
(not (+format-lsp-enable-on-save-maybe-h))
(let (current-prefix-arg) ; never prompt
(not (car (format-all--probe))))
(+format-enable-on-save-h)))
(when (featurep! +onsave)
(add-hook 'after-change-major-mode-hook #'+format-enable-on-save-maybe-h))
;;
;;; 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)
;; 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.
2020-03-10 01:48:20 -04:00
(advice-add #'format-all-buffer--with :around #'+format-buffer-a)
;; 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 ")