diff --git a/core/autoload/fonts.el b/core/autoload/fonts.el index 3e7910733..93610bc66 100644 --- a/core/autoload/fonts.el +++ b/core/autoload/fonts.el @@ -71,9 +71,7 @@ FRAME parameter defaults to current frame." "Reload your fonts, if they're set. See `doom-init-fonts-h'." (interactive) - (when doom-font - (set-frame-font doom-font t)) - (doom-init-fonts-h)) + (doom-init-fonts-h 'reload)) ;;;###autoload (defun doom/increase-font-size (count) diff --git a/core/autoload/themes.el b/core/autoload/themes.el index cfe85620c..d25af0557 100644 --- a/core/autoload/themes.el +++ b/core/autoload/themes.el @@ -28,14 +28,15 @@ all themes. It will apply to all themes once they are loaded." `(progn (defun ,fn () (let (custom--inhibit-theme-enable) - (dolist (theme (doom-enlist (or ,theme 'user))) + (dolist (theme (doom-enlist (or ,theme 'doom))) (when (or (eq theme 'user) (custom-theme-enabled-p theme)) (apply #'custom-theme-set-faces theme (mapcan #'doom--custom-theme-set-face (list ,@specs))))))) - (when (or doom-init-theme-p (null doom-theme)) - (funcall #',fn)) + (unless doom-theme (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)))) ;;;###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 doom-themes' API without worry." (declare (indent defun)) - `(custom-theme-set-faces! 'user ,@specs)) + `(custom-theme-set-faces! 'doom ,@specs)) ;;;###autoload (defun doom/reload-theme () "Reload the current color theme." (interactive) (let ((themes (copy-sequence custom-enabled-themes))) - (mapc #'disable-theme custom-enabled-themes) - (dolist (theme themes) - (if (get theme 'theme-feature) - (load-theme theme t) - (enable-theme theme))) - (message "Reloaded themes: %s" (mapconcat #'prin1-to-string themes ", ")) - (doom/reload-font))) + (load-theme doom-theme t) + (doom/reload-font) + (message "%s %s" + (propertize "Reloaded themes:" 'face 'bold) + (mapconcat #'prin1-to-string themes ", ")))) diff --git a/core/core-ui.el b/core/core-ui.el index 26f33c9f8..c996f0532 100644 --- a/core/core-ui.el +++ b/core/core-ui.el @@ -3,9 +3,6 @@ ;; ;;; Variables -(defvar doom-init-theme-p nil - "If non-nil, a theme has been loaded.") - (defvar doom-theme nil "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 +;; 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 (setq custom-theme-directory (concat doom-private-dir "themes/")) ;; Always prioritize the user's themes above the built-in/packaged ones. (setq custom-theme-load-path (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 (setq x-underline-at-descent-line t) -;; DEPRECATED In Emacs 27 -(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 () +(defun doom-init-fonts-h (&optional reload) "Loads `doom-font'." (when (fboundp 'set-fontset-font) (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)) (when doom-unicode-font (set-fontset-font t 'unicode doom-unicode-font)))) - (apply #'custom-theme-set-faces 'doom - (append (when doom-font - `((fixed-pitch ((t (:font ,doom-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)))))))) + ;; Changes to a theme don't take effect immediately if the theme isn't `user', + ;; so we must force it to. + (let (custom--inhibit-theme-enable) + (apply #'custom-theme-set-faces 'doom + (append (when doom-font + `((fixed-pitch ((t (:font ,doom-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 (doom-font - ;; I avoid `set-frame-font' because it does a lot of extra, expensive work - ;; we can avoid by setting the font frame parameter directly. + ;; I avoid `set-frame-font' at startup because it is expensive; doing extra, + ;; unnecessary work we can avoid by setting the frame parameter directly. (setf (alist-get 'font default-frame-alist) (cond ((stringp doom-font) doom-font) ((fontp doom-font) (font-xlfd-name doom-font)) - ((signal 'wrong-type-argument (list '(fontp stringp) - doom-font)))))) + ((signal 'wrong-type-argument + (list '(fontp stringp) doom-font))))) + (when reload + (set-frame-font doom-font t))) ((display-graphic-p) (setq font-use-system-font t))) ;; 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) "Load the theme specified by `doom-theme' in FRAME." - (when (and doom-theme - (not (eq doom-theme 'default)) - (not (memq doom-theme custom-enabled-themes))) + (when (and doom-theme (not (custom-theme-enabled-p doom-theme))) + ;; Fix #1397: if `doom-init-theme-h' is used on `after-make-frame-functions' + ;; (for daemon sessions), the new frame must be focused to ensure the theme + ;; loads correctly. (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) - "Run `doom-load-theme-hook' on `load-theme' and fix its issues. - -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'." + "Record `doom-theme', disable old themes, and trigger `doom-load-theme-hook'." :around #'load-theme - ;; HACK Run `load-theme' from an estranged buffer, where we can be assured - ;; that buffer-local face remaps (by `mixed-pitch-mode', for instance) - ;; won't interfere with changing themes. + ;; Run `load-theme' from an estranged buffer, where we can ensure that + ;; buffer-local face remaps (by `mixed-pitch-mode', for instance) won't + ;; interfere with recalculating faces in new themes. (with-temp-buffer - (when-let (result (funcall orig-fn theme no-confirm no-enable)) - (unless no-enable - (setq doom-theme theme - doom-init-theme-p t) - ;; `load-theme' doesn't disable previously enabled themes, which seems - ;; like what you'd want. You could always use `enable-theme' to activate - ;; multiple themes instead. - (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)))) + ;; Disable previous themes so there are no conflicts. If you truly want + ;; multiple themes enabled, then use `enable-theme' instead. + (mapc #'disable-theme custom-enabled-themes) + (prog1 (funcall orig-fn theme no-confirm no-enable) + (when (and (not no-enable) (custom-theme-enabled-p theme)) + (setq doom-theme theme) + (doom-run-hooks 'doom-load-theme-hook))))) ;; diff --git a/core/core.el b/core/core.el index f335b8af4..156e4f6c2 100644 --- a/core/core.el +++ b/core/core.el @@ -58,13 +58,6 @@ envvar will enable this at startup.") (define-error 'doom-private-error "Error in private config" '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 diff --git a/modules/ui/doom/config.el b/modules/ui/doom/config.el index 61c595819..366b23ef9 100644 --- a/modules/ui/doom/config.el +++ b/modules/ui/doom/config.el @@ -8,8 +8,7 @@ (use-package! doom-themes :defer t :init - (unless doom-theme - (setq doom-theme 'doom-one)) + (setq doom-theme 'doom-one) ;; improve integration w/ org-mode (add-hook 'doom-load-theme-hook #'doom-themes-org-config) ;; more Atom-esque file icons for neotree/treemacs diff --git a/modules/ui/indent-guides/config.el b/modules/ui/indent-guides/config.el index 270766bb3..d2c3a89d2 100644 --- a/modules/ui/indent-guides/config.el +++ b/modules/ui/indent-guides/config.el @@ -15,7 +15,7 @@ ;; access to 256 colors. So if the user uses a daemon we must wait for ;; the first graphical frame to be available to do. (add-hook 'doom-load-theme-hook #'+indent-guides-init-faces-h) - (when doom-init-theme-p + (when doom-theme (+indent-guides-init-faces-h)) ;; `highlight-indent-guides' breaks when `org-indent-mode' is active