From d0a4d673ee2eb78bd1d3d0055b87c13698f3ffd4 Mon Sep 17 00:00:00 2001 From: Protesilaos Stavrou Date: Sun, 28 Sep 2025 20:16:31 +0300 Subject: [PATCH] Revert "Redefine how themes are registered (the macro) and retrieved" This reverts commit 6be21f1119b60334d8ac1891a5f8b744f92c7457. --- modus-operandi-deuteranopia-theme.el | 33 +++--- modus-operandi-theme.el | 29 ++--- modus-operandi-tinted-theme.el | 29 ++--- modus-operandi-tritanopia-theme.el | 33 +++--- modus-themes.el | 162 ++++++++++++++------------- modus-vivendi-deuteranopia-theme.el | 33 +++--- modus-vivendi-theme.el | 29 ++--- modus-vivendi-tinted-theme.el | 29 ++--- modus-vivendi-tritanopia-theme.el | 33 +++--- 9 files changed, 221 insertions(+), 189 deletions(-) diff --git a/modus-operandi-deuteranopia-theme.el b/modus-operandi-deuteranopia-theme.el index cc9721f..2d6d412 100644 --- a/modus-operandi-deuteranopia-theme.el +++ b/modus-operandi-deuteranopia-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,19 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-operandi-deuteranopia + "Deuteranopia-optimized theme with a white background. +This variant is optimized for users with red-green color +deficiency (deuteranopia). It conforms with the highest +legibility standard for color contrast between background and +foreground in any given piece of text, which corresponds to a +minimum contrast in relative luminance of 7:1 (WCAG AAA +standard)." + :background-mode 'light + :kind 'color-scheme + :family 'modus) + (defconst modus-operandi-deuteranopia-palette '( ;;; Basic values @@ -519,19 +531,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-operandi-deuteranopia - modus-themes - "Deuteranopia-optimized theme with a white background. -This variant is optimized for users with red-green color -deficiency (deuteranopia). It conforms with the highest -legibility standard for color contrast between background and -foreground in any given piece of text, which corresponds to a -minimum contrast in relative luminance of 7:1 (WCAG AAA -standard)." - light - modus-operandi-deuteranopia-palette - modus-operandi-deuteranopia-palette-user - modus-operandi-deuteranopia-palette-overrides)) + (modus-themes-theme modus-operandi-deuteranopia + modus-operandi-deuteranopia-palette + modus-operandi-deuteranopia-palette-overrides) + + (provide-theme 'modus-operandi-deuteranopia)) ;;; modus-operandi-deuteranopia-theme.el ends here diff --git a/modus-operandi-theme.el b/modus-operandi-theme.el index 5bcba9e..2de5901 100644 --- a/modus-operandi-theme.el +++ b/modus-operandi-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,17 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-operandi + "Elegant, highly legible theme with a white background. +Conforms with the highest legibility standard for color contrast +between background and foreground in any given piece of text, +which corresponds to a minimum contrast in relative luminance of +7:1 (WCAG AAA standard)." + :background-mode 'light + :kind 'color-scheme + :family 'modus) + (defconst modus-operandi-palette '( ;;; Basic values @@ -519,17 +529,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-operandi - modus-themes - "Elegant, highly legible theme with a white background. -Conforms with the highest legibility standard for color contrast -between background and foreground in any given piece of text, -which corresponds to a minimum contrast in relative luminance of -7:1 (WCAG AAA standard)." - light - modus-operandi-palette - modus-operandi-palette-user - modus-operandi-palette-overrides)) + (modus-themes-theme modus-operandi + modus-operandi-palette + modus-operandi-palette-overrides) + + (provide-theme 'modus-operandi)) ;;; modus-operandi-theme.el ends here diff --git a/modus-operandi-tinted-theme.el b/modus-operandi-tinted-theme.el index 5399940..297b978 100644 --- a/modus-operandi-tinted-theme.el +++ b/modus-operandi-tinted-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,17 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-operandi-tinted + "Elegant, highly legible theme with a light ochre background. +Conforms with the highest legibility standard for color contrast +between background and foreground in any given piece of text, +which corresponds to a minimum contrast in relative luminance of +7:1 (WCAG AAA standard)." + :background-mode 'light + :kind 'color-scheme + :family 'modus) + (defconst modus-operandi-tinted-palette '( ;;; Basic values @@ -519,17 +529,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-operandi-tinted - modus-themes - "Elegant, highly legible theme with a light ochre background. -Conforms with the highest legibility standard for color contrast -between background and foreground in any given piece of text, -which corresponds to a minimum contrast in relative luminance of -7:1 (WCAG AAA standard)." - light - modus-operandi-tinted-palette - modus-operandi-tinted-palette-user - modus-operandi-tinted-palette-overrides)) + (modus-themes-theme modus-operandi-tinted + modus-operandi-tinted-palette + modus-operandi-tinted-palette-overrides) + + (provide-theme 'modus-operandi-tinted)) ;;; modus-operandi-tinted-theme.el ends here diff --git a/modus-operandi-tritanopia-theme.el b/modus-operandi-tritanopia-theme.el index a176d14..fd256ea 100644 --- a/modus-operandi-tritanopia-theme.el +++ b/modus-operandi-tritanopia-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,19 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-operandi-tritanopia + "Tritanopia-optimized theme with a white background. +This variant is optimized for users with blue-yellow color +deficiency (tritanopia). It conforms with the highest +legibility standard for color contrast between background and +foreground in any given piece of text, which corresponds to a +minimum contrast in relative luminance of 7:1 (WCAG AAA +standard)." + :background-mode 'light + :kind 'color-scheme + :family 'modus) + (defconst modus-operandi-tritanopia-palette '( ;;; Basic values @@ -519,19 +531,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-operandi-tritanopia - modus-themes - "Tritanopia-optimized theme with a white background. -This variant is optimized for users with blue-yellow color -deficiency (tritanopia). It conforms with the highest -legibility standard for color contrast between background and -foreground in any given piece of text, which corresponds to a -minimum contrast in relative luminance of 7:1 (WCAG AAA -standard)." - light - modus-operandi-tritanopia-palette - modus-operandi-tritanopia-palette-user - modus-operandi-tritanopia-palette-overrides)) + (modus-themes-theme modus-operandi-tritanopia + modus-operandi-tritanopia-palette + modus-operandi-tritanopia-palette-overrides) + + (provide-theme 'modus-operandi-tritanopia)) ;;; modus-operandi-tritanopia-theme.el ends here diff --git a/modus-themes.el b/modus-themes.el index 190ecc3..8d96081 100644 --- a/modus-themes.el +++ b/modus-themes.el @@ -995,40 +995,68 @@ C1 and C2 are color values written in hexadecimal RGB." (+ (modus-themes-wcag-formula c2) 0.05)))) (max ct (/ ct)))) -(defvar modus-themes-registered-items nil - "List of defined themes. -This list is instantiated by the `modus-themes-theme' macro. Themes -that build on top of Modus but for some reason cannot use that macro -must define theme properties to include those that the macro specifies.") +(defun modus-themes--modus-p (theme) + "Return non-nil if THEME name has a modus- prefix." + (string-prefix-p "modus-" (symbol-name theme))) (defun modus-themes--list-enabled-themes () "Return list of `custom-enabled-themes' with modus- prefix." - (seq-intersection modus-themes-registered-items custom-enabled-themes)) + (seq-filter #'modus-themes--modus-p custom-enabled-themes)) -(defun modus-themes-get-current-theme () +(defun modus-themes--load-no-enable (theme) + "Load but do not enable THEME if it belongs to `custom-known-themes'." + (unless (memq theme custom-known-themes) + (load-theme theme :no-confirm :no-enable))) + +(defun modus-themes--enable-themes () + "Enable the Modus themes." + (mapc #'modus-themes--load-no-enable modus-themes-items)) + +(defun modus-themes--list-known-themes () + "Return list of `custom-known-themes' with modus- prefix." + (modus-themes--enable-themes) + (seq-filter #'modus-themes--modus-p custom-known-themes)) + +(defun modus-themes--current-theme () "Return first enabled Modus theme." (car (modus-themes--list-enabled-themes))) -(defun modus-themes-get-theme-palette (&optional theme) - "Return palette value of active `modus-themes-registered-items' THEME. -If THEME is nil, use the return value of `modus-themes-get-current-theme'." - (let ((theme (or theme (modus-themes-get-current-theme)))) - (unless (memq theme modus-themes-registered-items) - (error "The theme `%s' is not among `modus-themes-registered-items'" theme)) - (if-let* ((properties (get theme 'theme-properties)) - (core-palette (plist-get properties :modus-core-palette))) - (let ((user-palette (plist-get properties :modus-user-palette)) - (overrides-palette (plist-get properties :modus-overrides-palette))) - (append core-palette user-palette overrides-palette)) - (error "The theme must have at least a `:modus-core-palette' property")))) +(defun modus-themes--palette-symbol (theme &optional suffix) + "Return THEME palette as a symbol of the form THEME-palette. +With optional SUFFIX, return THEME-palette-SUFFIX as a symbol." + (when theme + (intern + (if suffix + (format "%s-palette-%s" theme suffix) + (format "%s-palette" theme))))) + +(defun modus-themes--palette-value (theme &optional overrides) + "Return palette value of THEME with optional OVERRIDES." + (let* ((core-palette (symbol-value (modus-themes--palette-symbol theme))) + (user-palette (symbol-value (modus-themes--palette-symbol theme "user"))) + (base-value (append user-palette modus-themes-common-palette-user core-palette))) + (if overrides + (append (symbol-value (modus-themes--palette-symbol theme "overrides")) + modus-themes-common-palette-overrides + base-value) + base-value))) + +(defun modus-themes--current-theme-palette (&optional overrides) + "Return palette value of active Modus theme, else produce `user-error'. +With optional OVERRIDES return palette value plus whatever +overrides." + (if-let* ((theme (modus-themes--current-theme))) + (if overrides + (modus-themes--palette-value theme :overrides) + (modus-themes--palette-value theme)) + (user-error "No enabled Modus theme could be found"))) (defun modus-themes--disable-themes () "Disable themes per `modus-themes-disable-other-themes'." - (mapc - #'disable-theme - (if modus-themes-disable-other-themes - custom-enabled-themes - modus-themes-registered-items))) + (mapc #'disable-theme + (if modus-themes-disable-other-themes + custom-enabled-themes + (modus-themes--list-known-themes)))) (defun modus-themes-load-theme (theme) "Load THEME while disabling other themes. @@ -1057,9 +1085,11 @@ This function is used in the macros `modus-themes-theme', `modus-themes-with-colors'." (let ((value (car (alist-get color palette)))) (cond - ((stringp value) + ((or (stringp value) + (eq value 'unspecified)) value) - ((and (symbolp value) value) + ((and (symbolp value) + value) (modus-themes--retrieve-palette-value value palette)) (t 'unspecified)))) @@ -1084,7 +1114,7 @@ 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 (if theme (modus-themes--palette-value theme overrides) - (modus-themes-get-theme-palette overrides))) + (modus-themes--current-theme-palette overrides))) (value (modus-themes--retrieve-palette-value color palette))) value 'unspecified)) @@ -1113,8 +1143,13 @@ symbol, which is safe when used as a face attribute's value." (complete-with-action action candidates string pred))))) (defun modus-themes--completion-table-candidates () - "Render `modus-themes-registered-items' as completion table with theme category." - (modus-themes--completion-table 'theme modus-themes-registered-items)) + "Render `modus-themes--list-known-themes' as completion with theme category." + (modus-themes--completion-table 'theme (modus-themes--list-known-themes))) + +(define-obsolete-function-alias + 'modus-themes--select-prompt + 'modus-themes-select-prompt + "4.9.0") (defun modus-themes-select-prompt (&optional prompt themes history) "Minibuffer prompt to select a Modus theme. @@ -1275,7 +1310,7 @@ color mappings instead of the complete palette." (defun modus-themes-list-colors-current (&optional mappings) "Like `modus-themes-list-colors' with optional MAPPINGS for the current theme." (interactive "P") - (modus-themes-list-colors (modus-themes-get-current-theme) mappings)) + (modus-themes-list-colors (modus-themes--current-theme) mappings)) (defalias 'modus-themes-preview-colors-current 'modus-themes-list-colors-current "Alias for `modus-themes-list-colors-current'.") @@ -4334,54 +4369,27 @@ FG and BG are the main colors." ;;;; Instantiate a Modus theme ;;;###autoload -(defmacro modus-themes-theme (name family description background-mode core-palette user-palette overrides-palette) - "Define Modus theme with symbol NAME. -FAMILY is a symbol of the collection to which the theme belongs. -DESCRIPTION is a string describing the theme. BACKGROUND-MODE is a -symbol of either `dark' or `light', in reference to the theme's background. +(defmacro modus-themes-theme (name palette &optional overrides) + "Bind NAME's color PALETTE around face specs and variables. +Face specifications are passed to `custom-theme-set-faces'. +While variables are handled by `custom-theme-set-variables'. +Those are stored in `modus-themes-faces' and +`modus-themes-custom-variables' respectively. -CORE-PALETTE is the symbol of an alist in which each element is of the -form (SYMBOL COLOR). USER-PALETTE is for themes that build on top of -the CORE-PALETTE and, as such, can be nil. OVERRIDES-PALETTE is the -symbol of a palette like the aforementioned intended for user -customization and, as such, can be nil. - -The values of CORE-PALETTE and USER-PALETTE are used to instantiate the -theme. OVERRIDES-PALETTE is only registed as a theme property. - -Make the defined theme symbol have the following `theme-properties': - -- :kind -- :background-mode -- :family -- :modus-core-palette -- :modus-user-palette -- :modus-overrides-palette" +Optional OVERRIDES are appended to PALETTE, overriding +corresponding entries." (declare (indent 0)) (let ((sym (gensym)) - (colors (mapcar #'car (symbol-value core-palette))) - (theme-exists-p (custom-theme-p name))) - `(progn - (let* ((c '((class color) (min-colors 256))) - (,sym (append ,core-palette ,user-palette nil)) - ,@(mapcar (lambda (color) - (list color - `(modus-themes--retrieve-palette-value ',color ,sym))) - colors)) - ,@(unless theme-exists-p - (list `(custom-declare-theme - ',name ',family - ,description - (list :kind 'color-scheme :background-mode ',background-mode :family ',family - :modus-core-palette ',core-palette :modus-user-palette ',user-palette - :modus-overrides-palette ',overrides-palette)))) - ,@(when user-palette - (list `(add-to-list 'modus-themes-registered-items ',name))) - (ignore c ,@colors) ; Silence unused variable warnings - (custom-theme-set-faces ',name ,@modus-themes-faces) - (custom-theme-set-variables ',name ,@modus-themes-custom-variables) - ,@(unless theme-exists-p - (list `(provide-theme ',name))))))) + (colors (mapcar #'car (symbol-value palette)))) + `(let* ((c '((class color) (min-colors 256))) + (,sym (modus-themes--palette-value ',name ',overrides)) + ,@(mapcar (lambda (color) + (list color + `(modus-themes--retrieve-palette-value ',color ,sym))) + colors)) + (ignore c ,@colors) ; Silence unused variable warnings + (custom-theme-set-faces ',name ,@modus-themes-faces) + (custom-theme-set-variables ',name ,@modus-themes-custom-variables)))) ;;;; Use theme colors @@ -4394,9 +4402,9 @@ Make the defined theme symbol have the following `theme-properties': ;; 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 (modus-themes--current-theme-palette)))) `(let* ((c '((class color) (min-colors 256))) - (,sym (modus-themes-get-theme-palette :overrides)) + (,sym (modus-themes--current-theme-palette :overrides)) ,@(mapcar (lambda (color) (list color `(modus-themes--retrieve-palette-value ',color ,sym))) diff --git a/modus-vivendi-deuteranopia-theme.el b/modus-vivendi-deuteranopia-theme.el index ff5e328..e9e617c 100644 --- a/modus-vivendi-deuteranopia-theme.el +++ b/modus-vivendi-deuteranopia-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,19 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-vivendi-deuteranopia + "Deuteranopia-optimized theme with a black background. +This variant is optimized for users with red-green color +deficiency (deuteranopia). It conforms with the highest +legibility standard for color contrast between background and +foreground in any given piece of text, which corresponds to a +minimum contrast in relative luminance of 7:1 (WCAG AAA +standard)." + :background-mode 'dark + :kind 'color-scheme + :family 'modus) + (defconst modus-vivendi-deuteranopia-palette '( ;;; Basic values @@ -519,19 +531,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-vivendi-deuteranopia - modus-themes - "Deuteranopia-optimized theme with a black background. -This variant is optimized for users with red-green color -deficiency (deuteranopia). It conforms with the highest -legibility standard for color contrast between background and -foreground in any given piece of text, which corresponds to a -minimum contrast in relative luminance of 7:1 (WCAG AAA -standard)." - dark - modus-vivendi-deuteranopia-palette - modus-vivendi-deuteranopia-palette-user - modus-vivendi-deuteranopia-palette-overrides)) + (modus-themes-theme modus-vivendi-deuteranopia + modus-vivendi-deuteranopia-palette + modus-vivendi-deuteranopia-palette-overrides) + + (provide-theme 'modus-vivendi-deuteranopia)) ;;; modus-vivendi-deuteranopia-theme.el ends here diff --git a/modus-vivendi-theme.el b/modus-vivendi-theme.el index 5a895e8..10b95ec 100644 --- a/modus-vivendi-theme.el +++ b/modus-vivendi-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,17 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-vivendi + "Elegant, highly legible theme with a black background. +Conforms with the highest legibility standard for color contrast +between background and foreground in any given piece of text, +which corresponds to a minimum contrast in relative luminance of +7:1 (WCAG AAA standard)." + :background-mode 'dark + :kind 'color-scheme + :family 'modus) + (defconst modus-vivendi-palette '( ;;; Basic values @@ -519,17 +529,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-vivendi - modus-themes - "Elegant, highly legible theme with a black background. -Conforms with the highest legibility standard for color contrast -between background and foreground in any given piece of text, -which corresponds to a minimum contrast in relative luminance of -7:1 (WCAG AAA standard)." - dark - modus-vivendi-palette - modus-vivendi-palette-user - modus-vivendi-palette-overrides)) + (modus-themes-theme modus-vivendi + modus-vivendi-palette + modus-vivendi-palette-overrides) + + (provide-theme 'modus-vivendi)) ;;; modus-vivendi-theme.el ends here diff --git a/modus-vivendi-tinted-theme.el b/modus-vivendi-tinted-theme.el index ad4739f..f5e6d1d 100644 --- a/modus-vivendi-tinted-theme.el +++ b/modus-vivendi-tinted-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,17 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-vivendi-tinted + "Elegant, highly legible theme with a night sky background. +Conforms with the highest legibility standard for color contrast +between background and foreground in any given piece of text, +which corresponds to a minimum contrast in relative luminance of +7:1 (WCAG AAA standard)." + :background-mode 'dark + :kind 'color-scheme + :family 'modus) + (defconst modus-vivendi-tinted-palette '( ;;; Basic values @@ -519,17 +529,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-vivendi-tinted - modus-themes - "Elegant, highly legible theme with a night sky background. -Conforms with the highest legibility standard for color contrast -between background and foreground in any given piece of text, -which corresponds to a minimum contrast in relative luminance of -7:1 (WCAG AAA standard)." - dark - modus-vivendi-tinted-palette - modus-vivendi-tinted-palette-user - modus-vivendi-tinted-palette-overrides)) + (modus-themes-theme modus-vivendi-tinted + modus-vivendi-tinted-palette + modus-vivendi-tinted-palette-overrides) + + (provide-theme 'modus-vivendi-tinted)) ;;; modus-vivendi-tinted-theme.el ends here diff --git a/modus-vivendi-tritanopia-theme.el b/modus-vivendi-tritanopia-theme.el index f93db8f..d802736 100644 --- a/modus-vivendi-tritanopia-theme.el +++ b/modus-vivendi-tritanopia-theme.el @@ -34,7 +34,6 @@ -;;;###theme-autoload (eval-and-compile (unless (and (fboundp 'require-theme) load-file-name @@ -43,6 +42,19 @@ (require-theme 'modus-themes t)) (require 'modus-themes)) +;;;###theme-autoload + (deftheme modus-vivendi-tritanopia + "Tritanopia-optimized theme with a black background. +This variant is optimized for users with blue-yellow color +deficiency (tritanopia). It conforms with the highest +legibility standard for color contrast between background and +foreground in any given piece of text, which corresponds to a +minimum contrast in relative luminance of 7:1 (WCAG AAA +standard)." + :background-mode 'dark + :kind 'color-scheme + :family 'modus) + (defconst modus-vivendi-tritanopia-palette '( ;;; Basic values @@ -519,19 +531,10 @@ represents." :initialize #'custom-initialize-default :link '(info-link "(modus-themes) Palette overrides")) - (modus-themes-theme - modus-vivendi-tritanopia - modus-themes - "Tritanopia-optimized theme with a black background. -This variant is optimized for users with blue-yellow color -deficiency (tritanopia). It conforms with the highest -legibility standard for color contrast between background and -foreground in any given piece of text, which corresponds to a -minimum contrast in relative luminance of 7:1 (WCAG AAA -standard)." - dark - modus-vivendi-tritanopia-palette - modus-vivendi-tritanopia-palette-user - modus-vivendi-tritanopia-palette-overrides)) + (modus-themes-theme modus-vivendi-tritanopia + modus-vivendi-tritanopia-palette + modus-vivendi-tritanopia-palette-overrides) + + (provide-theme 'modus-vivendi-tritanopia)) ;;; modus-vivendi-tritanopia-theme.el ends here