[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#51715: defface forms not having dynamic value
From: |
irenezerafa |
Subject: |
bug#51715: defface forms not having dynamic value |
Date: |
Tue, 09 Nov 2021 14:17:03 +0000 |
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, November 9th, 2021 at 1:26 PM, Eli Zaretskii <eliz@gnu.org> wrote:
> > Date: Tue, 09 Nov 2021 11:41:10 +0000
> > From: irenezerafa via "Bug reports for GNU Emacs,
> > the Swiss army knife of text editors" bug-gnu-emacs@gnu.org
> >
> > I am getting into quite messy code because my macro creates
> > defface forms. Those do not have a dynamic value, but use the
> > value they get at the time they are evaluated. So using something
> > like a variable purple-intense does not help, because its value
> > would be a reference to one value, not a function that returns a
> > value (and having a function as a value would not be possible for
> > a face).
> >
> > Because the purpose of faces is to be configurable by the user,
> > could there be some improvements to easily tackle such problems?
>
> Please tell more. Which face attributes did you want to make dynamic,
> and how?
I take rainbow-delimiters as example. Specifically, the
(eval-when-compile
(defmacro rainbow-delimiters--define-depth-faces ()
(let ( (faces '())
(dark-colors [ "#ff62d4" "#3fdfd0" "#fba849" "#9f80ff"
"#4fe42f" "#fe6060" "#4fafff" "#f0dd60" "#ffffff" ])
(light-colors [ "#a8007f" "#005f88" "#904200" "#7f10d0"
"#006800" "#b60000" "#1f1fce" "#605b00" "#000000"]) )
(dotimes (i 9)
(push `( defface ,(intern (format "rainbow-delimiters-depth-%d-face"
(1+ i)))
'( (default (:inherit rainbow-delimiters-base-face))
( ((class color) (background dark))
:foreground ,(aref dark-colors i))
( ((class color) (background light))
:foreground ,(aref light-colors i)) )
,(format "Nested delimiter face, depth %d." (1+ i))
:group 'rainbow-delimiters-faces )
faces))
`(progn ,@faces)) ))
(rainbow-delimiters--define-depth-faces)
Now, suppose I want to use a colour scheme from modus-themes.
(require 'modus-themes)
(eval-when-compile
(defmacro rainbow-delimiters--define-depth-faces ()
(let ( (faces '())
(dark-colors (rainbow-delimiters-modus-vivendi-intense-colours
(list magenta-intense cyan-intense orange-intense
purple-intense green-intense red-intense
blue-intense yellow-intense fg-main)))
(light-colors (rainbow-delimiters-modus-operandi-intense-colours
(list magenta-intense cyan-intense orange-intense
purple-intense green-intense red-intense
blue-intense yellow-intense fg-main))) )
(dotimes (i 9)
(push `(defface ,(intern (format "rainbow-delimiters-depth-%d-face" (1+
i)))
'( (default (:inherit rainbow-delimiters-base-face))
( ((class color) (background light))
:foreground ,(nth i light-colors))
( ((class color) (background dark))
:foreground ,(nth i dark-colors)) )
,(format "Nested delimiter face, depth %d." (1+ i))
:group 'rainbow-delimiters-faces)
faces))
`(progn ,@faces)) ))
This would not be workable in practice. Because the dependency only
matters when your macro is being evaluated and the faces are reified.
Since you have a package, that will be the moment the package gets
required. So you are making it a dependency for everyone.
Ideally, one could simply add the colour values directly so it would
work everywhere, or use the modus-themes dependency for those who are
using modus-themes.