module!: add :editor whitespace

BREAKING CHANGE: Moves ws-butler, dtrt-indent, and whitespace defaults
out of Doom's core and into a new module. ws-butler is gated behind
+trim and dtrt-indent behind +guess. Users who depend on/like these
packages will need to enable the new module and their respective
flags (which is the default going forward).

This change is motivated by an ongoing effort to slim down Doom's
core (by (re)moving non-essentials from it).

This also addresses an issue where dtrt-indent would vastly increase
load times for some major-modes (e.g. elixir-mode & elm-mode, see #7537)
by restricting it to non-project files and non-read-only buffers AND
excludign those two major modes from indent guessing.

Fix: #8516
Fix: #7537
This commit is contained in:
Henrik Lissner
2025-09-24 01:29:09 -04:00
parent 22f86d25e9
commit fbdde6b5f4
16 changed files with 215 additions and 143 deletions

View File

@@ -2,19 +2,6 @@
;;; Commentary:
;;; Code:
(defvar doom-detect-indentation-excluded-modes
'(pascal-mode
so-long-mode
;; Automatic indent detection in org files is meaningless. Not to mention, a
;; non-standard `tab-width' causes an error in org-mode.
org-mode)
"A list of major modes where indentation shouldn't be auto-detected.")
(defvar-local doom-inhibit-indent-detection nil
"A buffer-local flag that indicates whether `dtrt-indent' should try to detect
indentation settings or not. This should be set by editorconfig if it
successfully sets indent_style/indent_size.")
(defvar doom-inhibit-large-file-detection nil
"If non-nil, inhibit large/long file detection when opening files.")
@@ -468,50 +455,6 @@ files, so this replace calls to `pp' with the much faster `prin1'."
(advice-add #'imenu :around #'doom-set-jump-a))
(use-package! dtrt-indent
;; Automatic detection of indent settings
:unless noninteractive
;; I'm not using `global-dtrt-indent-mode' because it has hard-coded and rigid
;; major mode checks, so I implement it in `doom-detect-indentation-h'.
:hook ((change-major-mode-after-body read-only-mode) . doom-detect-indentation-h)
:config
(defun doom-detect-indentation-h ()
(unless (or (not after-init-time)
doom-inhibit-indent-detection
doom-large-file-p
(eq major-mode 'fundamental-mode)
(member (substring (buffer-name) 0 1) '(" " "*"))
(apply #'derived-mode-p doom-detect-indentation-excluded-modes))
;; Don't display messages in the echo area, but still log them
(let ((inhibit-message (not init-file-debug)))
(dtrt-indent-mode +1))))
;; Enable dtrt-indent even in smie modes so that it can update `tab-width',
;; `standard-indent' and `evil-shift-width' there as well.
(setq dtrt-indent-run-after-smie t)
;; Reduced from the default of 5000 for slightly faster analysis
(setq dtrt-indent-max-lines 2000)
;; always keep tab-width up-to-date
(push '(t tab-width) dtrt-indent-hook-generic-mapping-list)
(defvar dtrt-indent-run-after-smie)
(defadvice! doom--fix-broken-smie-modes-a (fn &optional arg)
"Some smie modes throw errors when trying to guess their indentation, like
`nim-mode'. This prevents them from leaving Emacs in a broken state."
:around #'dtrt-indent-mode
(let ((dtrt-indent-run-after-smie dtrt-indent-run-after-smie))
(letf! ((defun symbol-config--guess (beg end)
(funcall symbol-config--guess beg (min end 10000)))
(defun smie-config-guess ()
(condition-case e (funcall smie-config-guess)
(error (setq dtrt-indent-run-after-smie t)
(message "[WARNING] Indent detection: %s"
(error-message-string e))
(message ""))))) ; warn silently
(funcall fn arg)))))
(use-package! smartparens
;; Auto-close delimiters and blocks as you type. It's more powerful than that,
;; but that is all Doom uses it for.
@@ -636,17 +579,5 @@ on."
smartparens-mode
smartparens-strict-mode)))
(use-package! ws-butler
;; a less intrusive `delete-trailing-whitespaces' on save
:hook (doom-first-buffer . ws-butler-global-mode)
:config
(pushnew! ws-butler-global-exempt-modes
'special-mode
'comint-mode
'term-mode
'eshell-mode
'diff-mode))
(provide 'doom-editor)
;;; doom-editor.el ends here

View File

@@ -502,17 +502,6 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
show-paren-when-point-in-periphery t))
;;;###package whitespace
(setq whitespace-line-column nil
whitespace-style
'(face indentation tabs tab-mark spaces space-mark newline newline-mark
trailing lines-tail)
whitespace-display-mappings
'((tab-mark ?\t [? ?\t])
(newline-mark ?\n [ ?\n])
(space-mark ?\ [] [?.])))
;;
;;; Third party packages
@@ -768,12 +757,5 @@ triggering hooks during startup."
(put sym 'disabled "Doom doesn't support `customize', configure Emacs from $DOOMDIR/config.el instead"))
(put 'customize-themes 'disabled "Set `doom-theme' or use `load-theme' in $DOOMDIR/config.el instead")
(after! whitespace
(defun doom--in-parent-frame-p ()
"`whitespace-mode' inundates child frames with whitespace markers, so
disable it to fix all that visual noise."
(null (frame-parameter nil 'parent-frame)))
(add-function :before-while whitespace-enable-predicate #'doom--in-parent-frame-p))
(provide 'doom-ui)
;;; doom-ui.el ends here

View File

@@ -359,7 +359,7 @@ Respects `require-final-newline'."
"Change the indentation size to WIDTH of the current buffer.
The effectiveness of this command is significantly improved if you have
editorconfig or dtrt-indent installed."
editorconfig installed."
(interactive
(list (if (integerp current-prefix-arg)
current-prefix-arg
@@ -391,20 +391,6 @@ editorconfig or dtrt-indent installed."
;;
;;; Hooks
;;;###autoload
(defun doom-enable-delete-trailing-whitespace-h ()
"Enables the automatic deletion of trailing whitespaces upon file save.
i.e. enables `ws-butler-mode' in the current buffer."
(ws-butler-mode +1))
;;;###autoload
(defun doom-disable-delete-trailing-whitespace-h ()
"Disables the automatic deletion of trailing whitespaces upon file save.
i.e. disables `ws-butler-mode' in the current buffer."
(ws-butler-mode -1))
;;;###autoload
(defun doom-enable-show-trailing-whitespace-h ()
"Enable `show-trailing-whitespace' in the current buffer."

View File

@@ -27,17 +27,7 @@
;; doom-editor.el
(package! better-jumper :pin "b1bf7a3c8cb820d942a0305e0e6412ef369f819c")
(package! dtrt-indent :pin "9108979357e8c9a1015baa5d37c0b596e2dda11b")
(package! smartparens :pin "b629b4e893ba21ba5a381f6c0054bb72f8e96df2")
(package! ws-butler
;; REVIEW: emacsmirror/nongnu_elpa serves this package from a branch. To stop
;; Straight from clobbering a single repo for multiple packages, we must be
;; explicit to force it to clone it multiple times.
:recipe (:host github
:repo "emacsmirror/nongnu_elpa"
:branch "elpa/ws-butler"
:local-repo "ws-butler")
:pin "67c49cfdf5a5a9f28792c500c8eb0017cfe74a3a")
;; doom-projects.el
(package! projectile :pin "9325c45e0fd96d5421e75ad901a91ee5353e10ad")