fix: doom-init-fonts-h: don't run more than needed
The face and theme-face manipulation only needs to happen once per frame, and the `set-fontset-font` calls only need to happen once per session (or whenever the user calls `M-x doom/reload-fonts`). This change ensures this and saves Emacs some work when initializing new frames, as well as resolves `set-fontset-font` related segfaults in some edge cases (#7803). Fix: #7803
This commit is contained in:
parent
42de6282f4
commit
da3d0687c5
1 changed files with 62 additions and 58 deletions
120
lisp/doom-ui.el
120
lisp/doom-ui.el
|
@ -497,65 +497,69 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
(cons 'custom-theme-directory
|
||||
(delq 'custom-theme-directory custom-theme-load-path)))
|
||||
|
||||
(defun doom-init-fonts-h (&optional _reload)
|
||||
(defun doom-init-fonts-h (&optional reload)
|
||||
"Loads `doom-font', `doom-serif-font', and `doom-variable-pitch-font'."
|
||||
(let ((this-frame (selected-frame)))
|
||||
(dolist (map `((default . ,doom-font)
|
||||
(fixed-pitch . ,doom-font)
|
||||
(fixed-pitch-serif . ,doom-serif-font)
|
||||
(variable-pitch . ,doom-variable-pitch-font)))
|
||||
(condition-case e
|
||||
(when-let* ((face (car map))
|
||||
(font (cdr map)))
|
||||
(dolist (frame (frame-list))
|
||||
(when (display-multi-font-p frame)
|
||||
(set-face-attribute face frame
|
||||
:width 'normal :weight 'normal
|
||||
:slant 'normal :font font)))
|
||||
(custom-push-theme
|
||||
'theme-face face 'user 'set
|
||||
(let* ((base-specs (cadr (assq 'user (get face 'theme-face))))
|
||||
(base-specs (or base-specs '((t nil))))
|
||||
(attrs '(:family :foundry :slant :weight :height :width))
|
||||
(new-specs nil))
|
||||
(dolist (spec base-specs)
|
||||
;; Each SPEC has the form (DISPLAY ATTRIBUTE-PLIST)
|
||||
(let ((display (car spec))
|
||||
(plist (copy-tree (nth 1 spec))))
|
||||
;; Alter only DISPLAY conditions matching this frame.
|
||||
(when (or (memq display '(t default))
|
||||
(face-spec-set-match-display display this-frame))
|
||||
(dolist (attr attrs)
|
||||
(setq plist (plist-put plist attr (face-attribute face attr)))))
|
||||
(push (list display plist) new-specs)))
|
||||
(nreverse new-specs)))
|
||||
(put face 'face-modified nil))
|
||||
('error
|
||||
(ignore-errors (doom--reset-inhibited-vars-h))
|
||||
(if (string-prefix-p "Font not available" (error-message-string e))
|
||||
(signal 'doom-font-error (list (font-get (cdr map) :family)))
|
||||
(signal (car e) (cdr e)))))))
|
||||
(when (fboundp 'set-fontset-font)
|
||||
(let* ((fn (doom-rpartial #'member (font-family-list)))
|
||||
(symbol-font (or doom-symbol-font
|
||||
(cl-find-if fn doom-symbol-fallback-font-families)))
|
||||
(emoji-font (or doom-emoji-font
|
||||
(cl-find-if fn doom-emoji-fallback-font-families))))
|
||||
(when symbol-font
|
||||
(dolist (script '(symbol mathematical))
|
||||
(set-fontset-font t script symbol-font)))
|
||||
(when emoji-font
|
||||
;; DEPRECATED: make unconditional when we drop 27 support
|
||||
(when (version<= "28.1" emacs-version)
|
||||
(set-fontset-font t 'emoji emoji-font))
|
||||
;; some characters in the Emacs symbol script are often covered by emoji
|
||||
;; fonts
|
||||
(set-fontset-font t 'symbol emoji-font nil 'append)))
|
||||
;; Nerd Fonts use these Private Use Areas
|
||||
(dolist (range '((#xe000 . #xf8ff) (#xf0000 . #xfffff)))
|
||||
(set-fontset-font t range "Symbols Nerd Font Mono")))
|
||||
;; Users should inject their own font logic in `after-setting-font-hook'
|
||||
(run-hooks 'after-setting-font-hook))
|
||||
(let ((initialized-frames (unless reload (get 'doom-font 'initialized-frames))))
|
||||
(dolist (frame (if reload (frame-list) (list (selected-frame))))
|
||||
(unless (member frame initialized-frames)
|
||||
(dolist (map `((default . ,doom-font)
|
||||
(fixed-pitch . ,doom-font)
|
||||
(fixed-pitch-serif . ,doom-serif-font)
|
||||
(variable-pitch . ,doom-variable-pitch-font)))
|
||||
(condition-case e
|
||||
(when-let* ((face (car map))
|
||||
(font (cdr map)))
|
||||
(when (display-multi-font-p frame)
|
||||
(set-face-attribute face frame
|
||||
:width 'normal :weight 'normal
|
||||
:slant 'normal :font font))
|
||||
(custom-push-theme
|
||||
'theme-face face 'user 'set
|
||||
(let* ((base-specs (cadr (assq 'user (get face 'theme-face))))
|
||||
(base-specs (or base-specs '((t nil))))
|
||||
(attrs '(:family :foundry :slant :weight :height :width))
|
||||
(new-specs nil))
|
||||
(dolist (spec base-specs)
|
||||
(let ((display (car spec))
|
||||
(plist (copy-tree (nth 1 spec))))
|
||||
(when (or (memq display '(t default))
|
||||
(face-spec-set-match-display display frame))
|
||||
(dolist (attr attrs)
|
||||
(setq plist (plist-put plist attr (face-attribute face attr)))))
|
||||
(push (list display plist) new-specs)))
|
||||
(nreverse new-specs)))
|
||||
(put face 'face-modified nil))
|
||||
('error
|
||||
(ignore-errors (doom--reset-inhibited-vars-h))
|
||||
(if (string-prefix-p "Font not available" (error-message-string e))
|
||||
(signal 'doom-font-error (list (font-get (cdr map) :family)))
|
||||
(signal (car e) (cdr e))))))
|
||||
(put 'doom-font 'initialized-frames
|
||||
(cons frame (cl-delete-if-not #'frame-live-p initialized-frames))))))
|
||||
;; Only do this once per session (or on `doom/reload-fonts'); superfluous
|
||||
;; `set-fontset-font' calls may segfault in some contexts.
|
||||
(when (or reload (not (get 'doom-font 'initialized)))
|
||||
(when (fboundp 'set-fontset-font) ; unavailable in emacs-nox
|
||||
(let* ((fn (doom-rpartial #'member (font-family-list)))
|
||||
(symbol-font (or doom-symbol-font
|
||||
(cl-find-if fn doom-symbol-fallback-font-families)))
|
||||
(emoji-font (or doom-emoji-font
|
||||
(cl-find-if fn doom-emoji-fallback-font-families))))
|
||||
(when symbol-font
|
||||
(dolist (script '(symbol mathematical))
|
||||
(set-fontset-font t script symbol-font)))
|
||||
(when emoji-font
|
||||
;; DEPRECATED: make unconditional when we drop 27 support
|
||||
(when (version<= "28.1" emacs-version)
|
||||
(set-fontset-font t 'emoji emoji-font))
|
||||
;; some characters in the Emacs symbol script are often covered by
|
||||
;; emoji fonts
|
||||
(set-fontset-font t 'symbol emoji-font nil 'append)))
|
||||
;; Nerd Fonts use these Private Use Areas
|
||||
(dolist (range '((#xe000 . #xf8ff) (#xf0000 . #xfffff)))
|
||||
(set-fontset-font t range "Symbols Nerd Font Mono")))
|
||||
(run-hooks 'after-setting-font-hook))
|
||||
(put 'doom-font 'initialized t))
|
||||
|
||||
(defun doom-init-theme-h (&rest _)
|
||||
"Load the theme specified by `doom-theme' in FRAME."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue