Wie kann ich ein vordefiniertes Gesicht für helle und dunkle Hintergründe überschreiben?

9

Ich möchte set-face-attributeeine von zwei Farben für den Vordergrund auswählen, je nachdem, ob der Hintergrund des aktuellen Themas hell oder dunkel ist.

Das erwartete Verhalten ist, dass sich der Vordergrund automatisch ändert, wenn ich von einem hellen Hintergrundthema zu einem dunklen Hintergrundthema wechsle oder umgekehrt.

Hier ist ein Anwendungsfall:

Ich passe das Gesicht stripe-hl-linewie folgt an:

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

Aber ich möchte den Vordergrund ändern, je nachdem, ob das Thema hell oder dunkel ist. Auf diese Weise muss ich mich nicht darum kümmern, dieses Gesicht in jedem Thema anzupassen.

Kaushal Modi
quelle
Das wird normalerweise in der Themendefinition gemacht.
Wasamasa
Obwohl es kompliziert werden könnte, scheint es, als könnten Sie die colorBibliothek hier nutzen. Sie könnten wahrscheinlich den RGB- oder Hex-Wert der Hintergrundfläche erhalten, einen Schwellenwert für "Dunkel" bestimmen und den Vordergrund entsprechend einstellen.
Dan
@wasamasa Ja. Aber für einige Gesichter ist es mir egal, ob ihre Farbe themenspezifisch ist. Ich habe meine Frage mit einem Beispielgesicht aktualisiert, das ich anpassen möchte.
Kaushal Modi
@ Dan Was wäre ein geeigneter Hook, um das Hintergrundfeld neu zu bewerten?
Kaushal Modi
Dies ist die Logik, die Sie verwenden können. Wenn Sie ein vorhandenes Gesicht verwenden möchten, können Sie die beiden mittleren Linien zum vorhandenen Defface-Formular hinzufügen.
Madhavan

Antworten:

9

Dank @MadhavanKumar habe ich mich darauf konzentriert, eine Lösung basierend auf abzuleiten defface.

Mir wurde klar, dass ich ein vorhandenes nicht überschreiben deffacekann, aber ich kann immer meinen eigenen Hintergrund farbempfindlich erstellen defface. Dann war die einzige Frage, wie ich mein benutzerdefiniertes Defface anstelle des Originals verwenden sollte.

Ich werde das gleiche Beispiel für das Überschreiben des stripe-hl-lineGesichts verwenden, um durch die Lösung zu gehen. Dieses Gesicht ist im Paket definiert stripe-buffer.

Hier sind die Schritte:

Schritt 1. Definieren Sie Ihre eigenen 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)

Dies führt dazu, dass die Vordergrundfarbe des my/stripe-hl-lineGesichts für dunkle Hintergründe dodgerblau und für helle Hintergründe rot ist .

Schritt 2. Erstellen Sie eine Funktion, um das Gesicht neu zuzuordnen

Die face-remap-add-relativeFunktion wird verwendet, um ein vorhandenes Gesicht einem neuen Gesicht zuzuordnen. In diesem Fall ordne ich das stripe-hl-lineGesicht neu zu my/stripe-hl-line.

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

Schritt 3. Führen Sie die Neuzuordnung an der entsprechenden Stelle durch

Aus der stripe-bufferQuelle sehe ich, dass das hl-lineGesicht dem Gesicht neu zugeordnet wird stripe-hl-line. Wir müssen also unsere Neuzuordnung durchführen, nachdem diese Neuzuordnung erfolgt ist (was in der stripe-listify-bufferFunktionsdefinition enthalten ist).

Deshalb machen wir unsere Neuzuordnung, indem wir die stripe-listify-bufferVerwendung des Kombinators empfehlen .:after advice

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

Getan!

Trotzdem wäre es fantastisch gewesen, so etwas direkt zu verwenden set-face-attribute, um Gesichter basierend auf der Dunkelheit im Hintergrund festzulegen.

Kaushal Modi
quelle