Thanks to @MadhavanKumar, I focused on deriving a solution based on defface
.
I realized that I can't override an existing defface
but I can always create my own background color sensitive defface
. Then the only question was how to use my custom defface instead of the original.
I'll use the same example of overriding the stripe-hl-line
face to walk through the solution. This face is defined in the package stripe-buffer
.
Here are the steps:
Step 1. Define your own defface
(defface my/stripe-hl-line
'((((background dark)) (:overline "gray" :underline "gray" :foreground "dodger blue"))
(t (:overline "gray" :underline "gray" :foreground "red")))
"Bold face for highlighting the current line in Hl-Line mode."
:group 'stripe-buffer)
This will result in the foreground color of my/stripe-hl-line
face being dodger blue for dark backgrounds and red for light backgrounds.
Step 2. Create a function to remap the face
The face-remap-add-relative
function is used to remap an existing face to a new face. In this case, I am remapping the stripe-hl-line
face to my/stripe-hl-line
.
(defun my/stripe-hl-line-face-remap ()
(face-remap-add-relative 'stripe-hl-line 'my/stripe-hl-line))
Step 3. Do the remapping at appropriate location
From the stripe-buffer
source, I see that the hl-line
face is remapped to stripe-hl-line
face. So we need to do our remapping after that remapping happens (which is in the stripe-listify-buffer
function definition).
So we do our remapping by advising stripe-listify-buffer
using the :after
advice
combinator.
(advice-add 'stripe-listify-buffer :after #'my/stripe-hl-line-face-remap)
Done!
That said, it would have been awesome to directly use something like set-face-attribute
to set faces based on the background darkness.