Jak mogę przesłonić wcześniej zdefiniowaną twarz dla jasnego i ciemnego tła?

9

Chciałbym użyć, set-face-attributeaby wybrać jeden z dwóch kolorów na pierwszym planie, w zależności od tego, czy tło bieżącego motywu jest jasne, czy ciemne.

Oczekiwanym zachowaniem jest to, że pierwszy plan zmienia się automatycznie, jeśli przełączę się z motywu jasnego tła na motyw ciemnego tła lub odwrotnie.

Oto przypadek użycia:

Dostosowuję twarz w stripe-hl-linenastępujący sposób:

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

Chciałbym jednak zmienić pierwszy plan na podstawie tego, czy motyw jest jasny czy ciemny. W ten sposób nie muszę się martwić o dostosowanie tej twarzy w każdym motywie.

Kaushal Modi
źródło
Jest to zwykle wykonywane w definicji motywu.
wasamasa
Chociaż może się to skomplikować, wygląda na to, że możesz skorzystać z colorbiblioteki tutaj. Prawdopodobnie można uzyskać wartość rgb lub heksadecymalną powierzchni tła, określić wartość progową dla „ciemności” i odpowiednio ustawić pierwszy plan.
Dan
@wasamasa Tak. Ale w przypadku niektórych twarzy nie dbam o to, aby ich kolor był specyficzny dla motywu. Zaktualizowałem moje pytanie o przykładową twarz, którą chcę dostosować.
Kaushal Modi
@Dan Jaki byłby odpowiedni hak do ponownej oceny hexu tła?
Kaushal Modi
to jest logika, której możesz użyć `(defface change-face '((((ciemne tło)): pierwszy plan„ White ”) (t: pierwszy plan„ Black ”)): group' x-mode-face)` ... Ponieważ jeśli chcesz użyć istniejącej powierzchni, możesz dodać środkowe 2 linie do istniejącego formularza defface.
Madhavan

Odpowiedzi:

9

Dzięki @MadhavanKumar skupiłem się na opracowaniu rozwiązania opartego na defface.

Uświadomiłem sobie, że nie mogę zastąpić istniejącego, deffaceale zawsze mogę stworzyć własne, wrażliwe na kolor tła defface. Wtedy jedynym pytaniem było, jak użyć mojej niestandardowej definicji zamiast oryginalnej.

Użyję tego samego przykładu przesłonięcia stripe-hl-linetwarzy, aby przejść przez rozwiązanie. Ta twarz jest zdefiniowana w pakiecie stripe-buffer.

Oto kroki:

Krok 1. Zdefiniuj własny 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)

Spowoduje to, że kolor pierwszego planu my/stripe-hl-linetwarzy będzie unikalny na niebiesko dla ciemnego tła i czerwony na jasnym tle.

Krok 2. Utwórz funkcję ponownego mapowania twarzy

face-remap-add-relativeFunkcja służy do przemapować istniejący twarzą nowej twarzy. W tym przypadku mapuję stripe-hl-linetwarz do my/stripe-hl-line.

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

Krok 3. Wykonaj ponowne mapowanie w odpowiednim miejscu

Ze stripe-bufferźródła widzę, że hl-linetwarz jest odwzorowana na stripe-hl-linetwarz. Musimy więc wykonać ponowne mapowanie po tym, jak to nastąpi (co jest w stripe-listify-bufferdefinicji funkcji).

Dokonujemy więc mapowania, doradzając stripe-listify-bufferza pomocą kombinatora.:after advice

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

Gotowy!

To powiedziawszy, byłoby wspaniale bezpośrednio użyć czegoś takiego, jak set-face-attributeustawić twarze na podstawie ciemności tła.

Kaushal Modi
źródło