Rewrite how themes are loaded, and fonts reloaded
A follow-up to 578dddd
, which wasn't sufficient.
Fixes #5000 (again)
This commit is contained in:
parent
113dcd74cf
commit
f989bf60f0
6 changed files with 51 additions and 92 deletions
|
@ -71,9 +71,7 @@ FRAME parameter defaults to current frame."
|
||||||
"Reload your fonts, if they're set.
|
"Reload your fonts, if they're set.
|
||||||
See `doom-init-fonts-h'."
|
See `doom-init-fonts-h'."
|
||||||
(interactive)
|
(interactive)
|
||||||
(when doom-font
|
(doom-init-fonts-h 'reload))
|
||||||
(set-frame-font doom-font t))
|
|
||||||
(doom-init-fonts-h))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/increase-font-size (count)
|
(defun doom/increase-font-size (count)
|
||||||
|
|
|
@ -28,14 +28,15 @@ all themes. It will apply to all themes once they are loaded."
|
||||||
`(progn
|
`(progn
|
||||||
(defun ,fn ()
|
(defun ,fn ()
|
||||||
(let (custom--inhibit-theme-enable)
|
(let (custom--inhibit-theme-enable)
|
||||||
(dolist (theme (doom-enlist (or ,theme 'user)))
|
(dolist (theme (doom-enlist (or ,theme 'doom)))
|
||||||
(when (or (eq theme 'user)
|
(when (or (eq theme 'user)
|
||||||
(custom-theme-enabled-p theme))
|
(custom-theme-enabled-p theme))
|
||||||
(apply #'custom-theme-set-faces theme
|
(apply #'custom-theme-set-faces theme
|
||||||
(mapcan #'doom--custom-theme-set-face
|
(mapcan #'doom--custom-theme-set-face
|
||||||
(list ,@specs)))))))
|
(list ,@specs)))))))
|
||||||
(when (or doom-init-theme-p (null doom-theme))
|
(unless doom-theme (funcall #',fn))
|
||||||
(funcall #',fn))
|
;; TODO Append to `doom-load-theme-hook' with DEPTH instead when Emacs
|
||||||
|
;; 26.x support is dropped.
|
||||||
(add-hook 'doom-customize-theme-hook #',fn 'append))))
|
(add-hook 'doom-customize-theme-hook #',fn 'append))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
@ -46,17 +47,15 @@ This is a convenience macro alternative to `custom-set-face' which allows for a
|
||||||
simplified face format, and takes care of load order issues, so you can use
|
simplified face format, and takes care of load order issues, so you can use
|
||||||
doom-themes' API without worry."
|
doom-themes' API without worry."
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
`(custom-theme-set-faces! 'user ,@specs))
|
`(custom-theme-set-faces! 'doom ,@specs))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/reload-theme ()
|
(defun doom/reload-theme ()
|
||||||
"Reload the current color theme."
|
"Reload the current color theme."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((themes (copy-sequence custom-enabled-themes)))
|
(let ((themes (copy-sequence custom-enabled-themes)))
|
||||||
(mapc #'disable-theme custom-enabled-themes)
|
(load-theme doom-theme t)
|
||||||
(dolist (theme themes)
|
(doom/reload-font)
|
||||||
(if (get theme 'theme-feature)
|
(message "%s %s"
|
||||||
(load-theme theme t)
|
(propertize "Reloaded themes:" 'face 'bold)
|
||||||
(enable-theme theme)))
|
(mapconcat #'prin1-to-string themes ", "))))
|
||||||
(message "Reloaded themes: %s" (mapconcat #'prin1-to-string themes ", "))
|
|
||||||
(doom/reload-font)))
|
|
||||||
|
|
106
core/core-ui.el
106
core/core-ui.el
|
@ -3,9 +3,6 @@
|
||||||
;;
|
;;
|
||||||
;;; Variables
|
;;; Variables
|
||||||
|
|
||||||
(defvar doom-init-theme-p nil
|
|
||||||
"If non-nil, a theme has been loaded.")
|
|
||||||
|
|
||||||
(defvar doom-theme nil
|
(defvar doom-theme nil
|
||||||
"A symbol representing the Emacs theme to load at startup.
|
"A symbol representing the Emacs theme to load at startup.
|
||||||
|
|
||||||
|
@ -570,23 +567,22 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
;;
|
;;
|
||||||
;;; Theme & font
|
;;; Theme & font
|
||||||
|
|
||||||
|
;; Use a psuedo theme to store internal and user faces + custom.el settings
|
||||||
|
;; without risk of them being written to `custom-file'.
|
||||||
|
(custom-declare-theme 'doom nil)
|
||||||
|
|
||||||
;; User themes should live in ~/.doom.d/themes, not ~/.emacs.d
|
;; User themes should live in ~/.doom.d/themes, not ~/.emacs.d
|
||||||
(setq custom-theme-directory (concat doom-private-dir "themes/"))
|
(setq custom-theme-directory (concat doom-private-dir "themes/"))
|
||||||
|
|
||||||
;; Always prioritize the user's themes above the built-in/packaged ones.
|
;; Always prioritize the user's themes above the built-in/packaged ones.
|
||||||
(setq custom-theme-load-path
|
(setq custom-theme-load-path
|
||||||
(cons 'custom-theme-directory
|
(cons 'custom-theme-directory
|
||||||
(remq 'custom-theme-directory custom-theme-load-path)))
|
(delq 'custom-theme-directory custom-theme-load-path)))
|
||||||
|
|
||||||
;; Underline looks a bit better when drawn lower
|
;; Underline looks a bit better when drawn lower
|
||||||
(setq x-underline-at-descent-line t)
|
(setq x-underline-at-descent-line t)
|
||||||
|
|
||||||
;; DEPRECATED In Emacs 27
|
(defun doom-init-fonts-h (&optional reload)
|
||||||
(defvar doom--prefer-theme-elc nil
|
|
||||||
"If non-nil, `load-theme' will prefer the compiled theme (unlike its default
|
|
||||||
behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
|
|
||||||
|
|
||||||
(defun doom-init-fonts-h ()
|
|
||||||
"Loads `doom-font'."
|
"Loads `doom-font'."
|
||||||
(when (fboundp 'set-fontset-font)
|
(when (fboundp 'set-fontset-font)
|
||||||
(let ((fn (doom-rpartial #'member (font-family-list))))
|
(let ((fn (doom-rpartial #'member (font-family-list))))
|
||||||
|
@ -596,22 +592,27 @@ behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
|
||||||
(set-fontset-font t 'unicode font))
|
(set-fontset-font t 'unicode font))
|
||||||
(when doom-unicode-font
|
(when doom-unicode-font
|
||||||
(set-fontset-font t 'unicode doom-unicode-font))))
|
(set-fontset-font t 'unicode doom-unicode-font))))
|
||||||
(apply #'custom-theme-set-faces 'doom
|
;; Changes to a theme don't take effect immediately if the theme isn't `user',
|
||||||
(append (when doom-font
|
;; so we must force it to.
|
||||||
`((fixed-pitch ((t (:font ,doom-font))))))
|
(let (custom--inhibit-theme-enable)
|
||||||
(when doom-serif-font
|
(apply #'custom-theme-set-faces 'doom
|
||||||
`((fixed-pitch-serif ((t (:font ,doom-serif-font))))))
|
(append (when doom-font
|
||||||
(when doom-variable-pitch-font
|
`((fixed-pitch ((t (:font ,doom-font))))))
|
||||||
`((variable-pitch ((t (:font ,doom-variable-pitch-font))))))))
|
(when doom-serif-font
|
||||||
|
`((fixed-pitch-serif ((t (:font ,doom-serif-font))))))
|
||||||
|
(when doom-variable-pitch-font
|
||||||
|
`((variable-pitch ((t (:font ,doom-variable-pitch-font)))))))))
|
||||||
(cond
|
(cond
|
||||||
(doom-font
|
(doom-font
|
||||||
;; I avoid `set-frame-font' because it does a lot of extra, expensive work
|
;; I avoid `set-frame-font' at startup because it is expensive; doing extra,
|
||||||
;; we can avoid by setting the font frame parameter directly.
|
;; unnecessary work we can avoid by setting the frame parameter directly.
|
||||||
(setf (alist-get 'font default-frame-alist)
|
(setf (alist-get 'font default-frame-alist)
|
||||||
(cond ((stringp doom-font) doom-font)
|
(cond ((stringp doom-font) doom-font)
|
||||||
((fontp doom-font) (font-xlfd-name doom-font))
|
((fontp doom-font) (font-xlfd-name doom-font))
|
||||||
((signal 'wrong-type-argument (list '(fontp stringp)
|
((signal 'wrong-type-argument
|
||||||
doom-font))))))
|
(list '(fontp stringp) doom-font)))))
|
||||||
|
(when reload
|
||||||
|
(set-frame-font doom-font t)))
|
||||||
((display-graphic-p)
|
((display-graphic-p)
|
||||||
(setq font-use-system-font t)))
|
(setq font-use-system-font t)))
|
||||||
;; Give users a chance to inject their own font logic.
|
;; Give users a chance to inject their own font logic.
|
||||||
|
@ -619,58 +620,27 @@ behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
|
||||||
|
|
||||||
(defun doom-init-theme-h (&optional frame)
|
(defun doom-init-theme-h (&optional frame)
|
||||||
"Load the theme specified by `doom-theme' in FRAME."
|
"Load the theme specified by `doom-theme' in FRAME."
|
||||||
(when (and doom-theme
|
(when (and doom-theme (not (custom-theme-enabled-p doom-theme)))
|
||||||
(not (eq doom-theme 'default))
|
;; Fix #1397: if `doom-init-theme-h' is used on `after-make-frame-functions'
|
||||||
(not (memq doom-theme custom-enabled-themes)))
|
;; (for daemon sessions), the new frame must be focused to ensure the theme
|
||||||
|
;; loads correctly.
|
||||||
(with-selected-frame (or frame (selected-frame))
|
(with-selected-frame (or frame (selected-frame))
|
||||||
(let ((doom--prefer-theme-elc t)) ; DEPRECATED in Emacs 27
|
(load-theme doom-theme t))))
|
||||||
(load-theme doom-theme t)))))
|
|
||||||
|
|
||||||
(defadvice! doom--load-theme-a (orig-fn theme &optional no-confirm no-enable)
|
(defadvice! doom--load-theme-a (orig-fn theme &optional no-confirm no-enable)
|
||||||
"Run `doom-load-theme-hook' on `load-theme' and fix its issues.
|
"Record `doom-theme', disable old themes, and trigger `doom-load-theme-hook'."
|
||||||
|
|
||||||
1. Disable previously enabled themes.
|
|
||||||
2. Don't let face-remapping screw up loading the new theme
|
|
||||||
(*cough*`mixed-pitch-mode').
|
|
||||||
3. Record the current theme in `doom-theme'."
|
|
||||||
:around #'load-theme
|
:around #'load-theme
|
||||||
;; HACK Run `load-theme' from an estranged buffer, where we can be assured
|
;; Run `load-theme' from an estranged buffer, where we can ensure that
|
||||||
;; that buffer-local face remaps (by `mixed-pitch-mode', for instance)
|
;; buffer-local face remaps (by `mixed-pitch-mode', for instance) won't
|
||||||
;; won't interfere with changing themes.
|
;; interfere with recalculating faces in new themes.
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(when-let (result (funcall orig-fn theme no-confirm no-enable))
|
;; Disable previous themes so there are no conflicts. If you truly want
|
||||||
(unless no-enable
|
;; multiple themes enabled, then use `enable-theme' instead.
|
||||||
(setq doom-theme theme
|
(mapc #'disable-theme custom-enabled-themes)
|
||||||
doom-init-theme-p t)
|
(prog1 (funcall orig-fn theme no-confirm no-enable)
|
||||||
;; `load-theme' doesn't disable previously enabled themes, which seems
|
(when (and (not no-enable) (custom-theme-enabled-p theme))
|
||||||
;; like what you'd want. You could always use `enable-theme' to activate
|
(setq doom-theme theme)
|
||||||
;; multiple themes instead.
|
(doom-run-hooks 'doom-load-theme-hook)))))
|
||||||
(mapc #'disable-theme (remq theme custom-enabled-themes))
|
|
||||||
(run-hooks 'doom-load-theme-hook))
|
|
||||||
result)))
|
|
||||||
|
|
||||||
(eval-when! (not EMACS27+)
|
|
||||||
;; DEPRECATED `doom--load-theme-a' handles this for us after the theme is
|
|
||||||
;; loaded, but this only works on Emacs 27+. Disabling old themes
|
|
||||||
;; must be done *before* the theme is loaded in Emacs 26.
|
|
||||||
(defadvice! doom--disable-previous-themes-a (theme &optional _no-confirm no-enable)
|
|
||||||
"Disable other themes when loading a new one."
|
|
||||||
:before #'load-theme
|
|
||||||
(unless no-enable
|
|
||||||
(mapc #'disable-theme custom-enabled-themes)))
|
|
||||||
|
|
||||||
;; DEPRECATED Not needed in Emacs 27
|
|
||||||
(defadvice! doom--prefer-compiled-theme-a (orig-fn &rest args)
|
|
||||||
"Have `load-theme' prioritize the byte-compiled theme.
|
|
||||||
This offers a moderate boost in startup (or theme switch) time, so long as
|
|
||||||
`doom--prefer-theme-elc' is non-nil."
|
|
||||||
:around #'load-theme
|
|
||||||
(if (or (null after-init-time)
|
|
||||||
doom--prefer-theme-elc)
|
|
||||||
(letf! (defun locate-file (filename path &optional _suffixes predicate)
|
|
||||||
(funcall locate-file filename path '("c" "") predicate))
|
|
||||||
(apply orig-fn args))
|
|
||||||
(apply orig-fn args))))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -58,13 +58,6 @@ envvar will enable this at startup.")
|
||||||
(define-error 'doom-private-error "Error in private config" 'doom-error)
|
(define-error 'doom-private-error "Error in private config" 'doom-error)
|
||||||
(define-error 'doom-package-error "Error with packages" 'doom-error)
|
(define-error 'doom-package-error "Error with packages" 'doom-error)
|
||||||
|
|
||||||
;;; Declare a psuedo theme to store faces and variables in, with no risk of it
|
|
||||||
;;; getting saved to `custom-file', or accidentally overwritten by user config.
|
|
||||||
(custom-declare-theme 'doom nil)
|
|
||||||
(enable-theme 'doom)
|
|
||||||
;; But immediately hide it, because it's not a real theme.
|
|
||||||
(setq custom-enabled-themes (remq 'doom custom-enabled-themes))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Directory variables
|
;;; Directory variables
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
(use-package! doom-themes
|
(use-package! doom-themes
|
||||||
:defer t
|
:defer t
|
||||||
:init
|
:init
|
||||||
(unless doom-theme
|
(setq doom-theme 'doom-one)
|
||||||
(setq doom-theme 'doom-one))
|
|
||||||
;; improve integration w/ org-mode
|
;; improve integration w/ org-mode
|
||||||
(add-hook 'doom-load-theme-hook #'doom-themes-org-config)
|
(add-hook 'doom-load-theme-hook #'doom-themes-org-config)
|
||||||
;; more Atom-esque file icons for neotree/treemacs
|
;; more Atom-esque file icons for neotree/treemacs
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
;; access to 256 colors. So if the user uses a daemon we must wait for
|
;; access to 256 colors. So if the user uses a daemon we must wait for
|
||||||
;; the first graphical frame to be available to do.
|
;; the first graphical frame to be available to do.
|
||||||
(add-hook 'doom-load-theme-hook #'+indent-guides-init-faces-h)
|
(add-hook 'doom-load-theme-hook #'+indent-guides-init-faces-h)
|
||||||
(when doom-init-theme-p
|
(when doom-theme
|
||||||
(+indent-guides-init-faces-h))
|
(+indent-guides-init-faces-h))
|
||||||
|
|
||||||
;; `highlight-indent-guides' breaks when `org-indent-mode' is active
|
;; `highlight-indent-guides' breaks when `org-indent-mode' is active
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue