Как я могу переопределить предопределенное лицо для светлого и темного фона?

9

Я хотел бы использовать set-face-attributeодин из двух цветов для переднего плана в зависимости от того, является ли фон текущей темы светлым или темным.

Ожидаемое поведение заключается в том, что передний план меняется автоматически, если я переключаюсь с темы на светлом фоне на тему на темном фоне или наоборот.

Вот пример использования:

Я настраиваю лицо stripe-hl-lineследующим образом:

 (set-face-attribute 'stripe-hl-line nil
                        :overline   "gray"
                        :underline  "gray"
                        :foreground "dodger blue")

Но я бы хотел изменить передний план, основываясь только на том, светлая или темная тема. Таким образом, мне не нужно беспокоиться о настройке этого лица в каждой теме.

Каушал Моди
источник
Это обычно делается в определении темы.
васамаса
Хотя это может стать сложным, похоже, что вы могли бы использовать colorбиблиотеку здесь. Вы могли бы получить rgb или шестнадцатеричное значение фоновой грани, определить пороговое значение для «темного» и соответственно установить передний план.
Дан
@ wasamasa Да. Но для некоторых лиц меня не волнует их цвет, специфичный для темы. Я обновил свой вопрос с примером лица, которое я хочу настроить.
Каушал Моди
@Dan Что будет подходящим крючком для переоценки фонового гекса?
Каушал Моди
эту логику вы можете использовать `(defface change-face '((((фон темный)): передний план" Белый ") (t: передний план" Черный ")): группа' x-mode-face)` ... Поскольку, если вы хотите использовать существующее лицо, то вы можете добавить две средние строки к существующей форме деффеции.
Мадхаван

Ответы:

9

Благодаря @MadhavanKumar я сосредоточился на поиске решения на основе defface.

Я понял, что не могу переопределить существующее, deffaceно я всегда могу создать свой собственный, чувствительный к цвету фона defface. Тогда единственный вопрос состоял в том, как использовать мою пользовательскую дефекацию вместо оригинальной.

Я буду использовать тот же пример переопределения stripe-hl-lineлица, чтобы пройти через решение. Это лицо определено в упаковке stripe-buffer.

Вот шаги:

Шаг 1. Определите свой собственный 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)

Это приведет к тому, что цвет переднего плана my/stripe-hl-lineлица будет более синим для темного фона и красным для светлого фона.

Шаг 2. Создайте функцию для переназначения лица

face-remap-add-relativeФункция используется для переназначения существующего лицом к новому лицу. В этом случае я переназначаю stripe-hl-lineлицо my/stripe-hl-line.

(defun my/stripe-hl-line-face-remap ()
  (face-remap-add-relative 'stripe-hl-line 'my/stripe-hl-line))

Шаг 3. Сделайте переназначение в соответствующем месте

Из stripe-bufferисточника я вижу, что hl-lineлицо переназначается на stripe-hl-lineлицо. Таким образом, мы должны сделать наше переопределение после того, как это переопределение произойдет (что находится в stripe-listify-bufferопределении функции).

Таким образом, мы делаем переотображение, советуя stripe-listify-bufferиспользовать комбинатор.:after advice

(advice-add 'stripe-listify-buffer :after #'my/stripe-hl-line-face-remap)

Выполнено!

Тем не менее, было бы здорово использовать что-то наподобие set-face-attributeустановки граней на основе темного фона.

Каушал Моди
источник