fix(ligatures): proper resetting of font-ligatures

resetting font-ligatures means passing `nil` as the second argument
of `(set-font-ligatures!)`

Using `ligatures-ignored-major-modes` to cancel ligatures is too
brittle, because "resetting ligatures for `prog-mode`" would have bad
semantics with all its derived modes. The user probably just wants to
remove the default ligatures and then configure `foo-mode`, but pushing
`prog-mode` to `ignored-major-modes` might just disable ligatures across
all modes _derived from_ `prog-mode`.

This commit changes things in 2 ways:
- resetting ligatures now directly manipulates ligature.el internal
  state (the `ligature-composition-table` alist)
- in order to work, Doom must maintain an extra invariant on that alist,
  multi-modes keys (`'(foo-mode bar-mode)`), cannot be used, only single
  modes.

That mostly means that users should _not_ use
`ligature-set-ligatures` themselves in private config, but instead
always rely on `set-font-ligatures!` which does splicing behind
curtains. Failing to do so would be mostly harmless though (it would
just make "resetting ligatures" only partially remove set ligatures).

Fix: #7433
This commit is contained in:
Gerry Agbobada 2023-09-17 09:59:09 +02:00 committed by Henrik Lissner
parent 2b08b2da33
commit a60d8b3da4

View file

@ -67,10 +67,15 @@ Font ligatures can be unset for emacs-lisp-mode with:
Note that this will keep all ligatures in `+ligatures-prog-mode-list' active, as Note that this will keep all ligatures in `+ligatures-prog-mode-list' active, as
`emacs-lisp-mode' is derived from `prog-mode'." `emacs-lisp-mode' is derived from `prog-mode'."
(declare (indent defun)) (declare (indent defun))
;; NOTE: Doom enforces `ligature-composition-table' to have a single mode per key in the alist.
;; This is less efficient than what ligature.el can do (i.e. use a list of modes, or `t' as a key),
;; but holding this invariant allows resetting with `(set-font-ligatures! 'mode nil)` to work reliably.
(if (null ligatures) (if (null ligatures)
(dolist (mode (ensure-list modes)) (dolist (mode (ensure-list modes))
(add-to-list 'ligature-ignored-major-modes mode)) (delq! mode ligature-composition-table 'assq))
(after! ligature (after! ligature
(dolist (mode (ensure-list modes)) (dolist (mode (ensure-list modes))
(setq ligature-ignored-major-modes (delq mode ligature-ignored-major-modes))) (setq ligature-ignored-major-modes (delq mode ligature-ignored-major-modes))
(ligature-set-ligatures (ensure-list modes) ligatures)))) (ligature-set-ligatures mode ligatures)))))