branch: externals/modus-themes
commit 27558488efabc3cd164a6f7fee979de0bc9ed42b
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>

    Change how themes are activated and fix known issues with 
modus-themes-get-theme-palette
---
 modus-themes.el | 68 ++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/modus-themes.el b/modus-themes.el
index 8f0eec37ff..51321f4c04 100644
--- a/modus-themes.el
+++ b/modus-themes.el
@@ -4585,13 +4585,19 @@ must define theme properties to include those that the 
macro specifies.
 
 Also see `modus-themes-get-all-known-themes'.")
 
-(defun modus-themes--activate (theme)
-  "Load THEME if it is not already, but do not activate it."
+(defvar modus-themes--activated-themes nil
+  "List of themes that `modus-themes--activate' operated on.")
+
+(defun modus-themes--activate (theme &optional forcefully)
+  "Load THEME if it is not defined but do not activate it.
+With non-nil FORCEFULLY, load the theme regardless."
   ;; NOTE 2025-09-29: We need to do this instead of pushing to the
   ;; `custom-known-themes' because loading the theme has the desired
   ;; side effect of adding the relevant `theme-properties' to it.
-  (unless (custom-theme-p theme)
-    (load-theme theme t t)))
+  (unless (memq theme modus-themes--activated-themes)
+    (when (or forcefully (not (custom-theme-p theme)))
+      (load-theme theme t t)
+      (push theme modus-themes--activated-themes))))
 
 (defun modus-themes--belongs-to-family-p (theme family)
   "Return non-nil if THEME has FAMILY property."
@@ -4646,26 +4652,32 @@ With optional SHOW-ERROR, throw an error instead of 
returning nil."
   "Return first enabled Modus theme."
   (car (modus-themes--list-enabled-themes)))
 
-(defun modus-themes--get-theme-palette-subr (theme)
-  "Get THEME `modus-themes-get-theme-palette' without `modus-themes-known-p'."
+(defun modus-themes--get-theme-palette-subr (theme with-overrides 
with-user-palette)
+  "Get THEME palette without `modus-themes-known-p'.
+WITH-OVERRIDES and WITH-USER-PALETTE are described in
+`modus-themes-get-theme-palette'."
   (if-let* ((properties (get theme 'theme-properties))
             (core-palette (symbol-value (plist-get properties 
:modus-core-palette))))
-      (let* ((user-palette (symbol-value (plist-get properties 
:modus-user-palette)))
-             (overrides-palette (symbol-value (plist-get properties 
:modus-overrides-palette)))
+      (let* ((user-palette (when with-user-palette (symbol-value (plist-get 
properties :modus-user-palette))))
+             (overrides-palette (when with-overrides (symbol-value (plist-get 
properties :modus-overrides-palette))))
              (family (plist-get properties :family))
-             (all-overrides (append
-                             overrides-palette
-                             (when (eq family 'modus-themes)
-                               modus-themes-common-palette-overrides))))
+             (all-overrides (when with-overrides
+                              (append
+                               overrides-palette
+                               (when (eq family 'modus-themes)
+                                 modus-themes-common-palette-overrides)))))
         (append all-overrides user-palette core-palette))
     (error "The theme must have at least a `:modus-core-palette' property")))
 
-(defun modus-themes-get-theme-palette (&optional theme)
+(defun modus-themes-get-theme-palette (&optional theme with-overrides 
with-user-palette)
   "Return palette value of active `modus-themes-get-themes' THEME.
-If THEME is nil, use the return value of `modus-themes-get-current-theme'."
+If THEME is nil, use the return value of `modus-themes-get-current-theme'.
+With WITH-OVERRIDES, include all overrides in the combined palette.
+With WITH-USER-PALETTE do the same for the user-defined palette
+extension."
   (let ((theme (or theme (modus-themes-get-current-theme))))
     (when (modus-themes-known-p theme :err-if-needed)
-      (modus-themes--get-theme-palette-subr theme))))
+      (modus-themes--get-theme-palette-subr theme with-overrides 
with-user-palette))))
 
 (defun modus-themes--disable-themes ()
   "Disable themes per `modus-themes-disable-other-themes'."
@@ -4711,7 +4723,8 @@ This function is used in the macros `modus-themes-theme',
      (t
       'unspecified))))
 
-(defun modus-themes-get-color-value (color &optional overrides theme)
+;; NOTE 2025-09-29: We keep THEME at that position for backward-compatibility.
+(defun modus-themes-get-color-value (color &optional with-overrides theme)
   "Return color value of named COLOR for current Modus theme.
 
 COLOR is a symbol that represents a named color entry in the
@@ -4721,16 +4734,17 @@ If the value is the name of another color entry in the
 palette (so a mapping), recur until you find the underlying color
 value.
 
-With optional OVERRIDES as a non-nil value, account for palette
+With optional WITH-OVERRIDES as a non-nil value, include palette
 overrides.  Else use the default palette.
 
-With optional THEME as a symbol among `modus-themes-items', use
-the palette of that item.  Else use the current Modus theme.
+With optional THEME among `modus-themes-get-all-known-themes', use the
+palette of that item.  Else use the current theme.
 
 If COLOR is not present in the palette, return the `unspecified'
 symbol, which is safe when used as a face attribute's value."
-  (if-let* ((palette ;; FIXME for the ovrrides (modus-themes-get-theme-palette 
theme overrides)
-             (modus-themes-get-theme-palette theme))
+  (when theme
+    (modus-themes--activate theme :make-sure-theme-is-reified))
+  (if-let* ((palette (modus-themes-get-theme-palette theme with-overrides 
:with-user-palette))
             (value (modus-themes--retrieve-palette-value color palette)))
       value
     'unspecified))
@@ -4923,8 +4937,7 @@ PALETTE is the value of a variable like 
`modus-operandi-palette'."
 
 (defun modus-themes--list-colors-tabulated (theme &optional mappings)
   "Return a data structure of THEME palette or MAPPINGS for tabulated list."
-  (let* ((current-palette ;; FIXME for the overrides 
(modus-themes-get-theme-palette theme :include-overrides)
-          (modus-themes-get-theme-palette theme :include-overrides))
+  (let* ((current-palette (modus-themes-get-theme-palette theme 
:with-overrides :with-user-palette))
          (palette (if mappings
                       (modus-themes--list-colors-get-mappings current-palette)
                     current-palette)))
@@ -4967,7 +4980,7 @@ color mappings instead of the complete palette."
      (list
       (modus-themes-select-prompt prompt)
       current-prefix-arg)))
-  (load-theme theme t t)
+  (modus-themes--activate theme :make-sure-theme-is-reified)
   (let ((buffer (get-buffer-create (format (if mappings "*%s-list-mappings*" 
"*%s-list-all*") theme))))
     (with-current-buffer buffer
       (let ((modus-themes-current-preview theme)
@@ -8082,7 +8095,7 @@ are symbols of variables which define palettes 
commensurate with
            (list
             `(modus-themes-register ',name)))
        (let* ((c '((class color) (min-colors 256)))
-              (,sym (modus-themes--get-theme-palette-subr ',name))
+              (,sym (modus-themes--get-theme-palette-subr ',name 
:with-overrides :with-user-palette))
               ,@(mapcar (lambda (color)
                           (list color
                                 `(modus-themes--retrieve-palette-value ',color 
,sym)))
@@ -8099,14 +8112,15 @@ are symbols of variables which define palettes 
commensurate with
   "Evaluate BODY with colors from current palette bound."
   (declare (indent 0))
   (let* ((sym (gensym))
+         (palette (modus-themes-get-theme-palette nil :with-overrides 
:with-user-palette))
          ;; NOTE 2022-08-23: We just give it a sample palette at this
          ;; stage.  It only needs to collect each car.  Then we
          ;; instantiate the actual theme's palette.  We have to do this
          ;; otherwise the macro does not work properly when called from
          ;; inside a function.
-         (colors (mapcar #'car (modus-themes-get-theme-palette))))
+         (colors (mapcar #'car palette)))
     `(let* ((c '((class color) (min-colors 256)))
-            (,sym (modus-themes--current-theme-palette :overrides))
+            (,sym (modus-themes-get-theme-palette nil :with-overrides 
:with-user-palette))
             ,@(mapcar (lambda (color)
                         (list color
                               `(modus-themes--retrieve-palette-value ',color 
,sym)))

Reply via email to