branch: externals/modus-themes
commit 7e06d30099081bd0405f0658dab4e3fcc17a6035
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>
Make modus-themes-with-colors call a function and update CRITICAL FIXME
findings
The updated code of the macro relative to commit 16c2c66 works
correectly at all times ONLY WHEN the function that uses
modus-themes-with-colors is added to the modus-themes-after-load-theme-hook
and thus triggered by modus-themes-load-theme.
The enable-theme-functions and load-theme combination is not working
though and I need to figure out why. It leads to excessive lisp nesting.
---
modus-themes.el | 117 ++++++++++++++++++--------------------------------------
1 file changed, 37 insertions(+), 80 deletions(-)
diff --git a/modus-themes.el b/modus-themes.el
index fd419be186..954d196159 100644
--- a/modus-themes.el
+++ b/modus-themes.el
@@ -7306,97 +7306,54 @@ Consult the manual for details on how to build a theme
on top of the
;;;; Use theme colors
-;; CRITICAL FIXME 2025-11-03: When we define a function that calls
-;; `modus-themes-with-colors' and restart Emacs that function never
-;; returns the expected result: the current palette is not `let' bound
-;; when the BODY is evaluated. If after loading with the error we go
-;; and evaluate the same function, then loading the theme works as
-;; expected. Same if we first load the theme, then define the
-;; function, and then load the theme again.
+;; CRITICAL FIXME 2025-11-03: The `modus-themes-with-colors' is not
+;; working with the `enable-theme-functions' and `load-theme'
+;; combination: it leads to excessive lisp nesting. Whereas
+;; `modus-themes-after-load-theme-hook' and `modus-themes-load-theme'
+;; do the right thing.
;;
-;; Here is the FAULTY result:
+;; BAD:
;;
-;; (defun test (theme)
-;; (condition-case data
-;; (progn
-;; (message "Theme: %s MODUS: %s" theme
(modus-themes-get-current-theme))
-;; (modus-themes-with-colors
-;; (message "Cursor: %s" (or cursor (error "We failed")))))
-;; (error (message "Something wrong with theme %s: %s" theme data))))
+;; (defun test (_theme)
+;; (modus-themes-with-colors
+;; (message "Modus cursor color: %s" cursor)))
;;
-;; (add-hook 'enable-theme-functions #'test)
+;; (add-hook 'enable-theme-functions #'test)
;;
-;; (load-theme 'modus-vivendi-tinted t)
+;; (load-theme 'modus-vivendi t)
;;
-;; And here is the CORRECT result, even though loading the theme twice is
bogus:
+;; GOOD:
;;
-;; (load-theme 'modus-vivendi-tinted t)
+;; (defun test (&optional theme)
+;; (modus-themes-with-colors
+;; (message "Modus cursor color: %s" cursor)))
;;
-;; (defun test (theme)
-;; (condition-case data
-;; (progn
-;; (message "Theme: %s MODUS: %s" theme
(modus-themes-get-current-theme))
-;; (modus-themes-with-colors
-;; (message "Cursor: %s" (or cursor (error "We failed")))))
-;; (error (message "Something wrong with theme %s: %s" theme data))))
+;; (add-hook 'modus-themes-after-load-theme-hook #'test)
;;
-;; (add-hook 'enable-theme-functions #'test)
-;;
-;; (load-theme 'modus-vivendi-tinted t)
-;;
-;; What I believe is happening:
-;;
-;; - The `modus-thems-theme' is a function. It is evaluated at runtime.
-;; - The `modus-thems-theme' is what reifies a theme. Before htat there is no
theme.
-;; - This means that `modus-themes-get-theme-palette' cannot work at
macroexpand time.
-;;
-;; Maybe we can solve it this way, without breaking existing code:
-;;
-;; - Have a function that does the actual work of binding the palette and
evaluating BODY.
-;; - Make the macro simply set up the function to evaluate BODY.
-;;
-;; HOWEVER, doing the following leads to excessive lisp nesting errors
-;; at startup when the `modus-themes-with-colors' is inside of a
-;; function. If we evaluate the function after the themes are loaded,
-;; then everything works as expected;
-;;
-;; (defun modus-themes-with-colors-subr (expressions)
-;; "Do the work of `modus-themes-with-colors' for EXPRESSIONS."
-;; (when-let* ((theme (modus-themes-get-current-theme))
-;; (palette (modus-themes--get-theme-palette-subr theme
:with-overrides :with-user-palette)))
-;; (eval
-;; `(let* ((c '((class color) (min-colors 256)))
-;; (palette ',palette)
-;; ,@(mapcar
-;; (lambda (entry)
-;; (let ((name (car entry)))
-;; (list name `(modus-themes--retrieve-palette-value
',name palette))))
-;; palette))
-;; ,@expressions))))
-;;
-;; (defmacro modus-themes-with-colors (&rest body)
-;; "Evaluate BODY with colors from current palette bound."
-;; (declare (indent 0))
-;; `(modus-themes-with-colors-subr ',body))
+;; (modus-themes-load-theme 'modus-vivendi)
+(defun modus-themes--with-colors-resolve-palette (theme)
+ "Return THEME `let' bindings for `modus-themes-with-colors'."
+ (let* ((palette (modus-themes--get-theme-palette-subr theme :with-overrides
:with-user-palette)))
+ (mapcar
+ (lambda (entry)
+ (if (eq (cadr entry) 'unspecified)
+ (list (car entry) ''unspecified)
+ entry))
+ palette)))
+
+(defun modus-themes-with-colors-subr (expressions)
+ "Do the work of `modus-themes-with-colors' for EXPRESSIONS."
+ (condition-case data
+ (when-let* ((theme (modus-themes-get-current-theme)))
+ (eval
+ `(let* (,@(modus-themes--with-colors-resolve-palette theme))
+ ,@expressions)))
+ (error (message "Error in `modus-themes-with-colors': %s" data))))
+
(defmacro modus-themes-with-colors (&rest body)
"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 palette)))
- `(when-let* ((c '((class color) (min-colors 256)))
- (,sym (modus-themes-get-theme-palette nil :with-overrides
:with-user-palette))
- ,@(mapcar (lambda (color)
- (list color
- `(modus-themes--retrieve-palette-value
',color ,sym)))
- colors))
- (ignore c ,@colors) ; Silence unused variable warnings
- ,@body)))
+ `(modus-themes-with-colors-subr ',body))
;;;; Declare all the Modus themes