Como substituir um rosto predefinido por fundos claros e escuros?

9

Gostaria de usar set-face-attributepara escolher uma das duas cores para primeiro plano, dependendo se o plano de fundo do tema atual é claro ou escuro.

O comportamento esperado é que o primeiro plano mude automaticamente se eu alternar de um tema de plano de fundo claro para um tema de plano de fundo escuro ou vice-versa.

Aqui está um caso de uso:

Eu personalizo a face da stripe-hl-lineseguinte forma:

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

Mas eu gostaria de mudar o primeiro plano com base apenas se o tema for claro ou escuro. Dessa forma, não preciso me preocupar em personalizar esse rosto em cada tema.

Kaushal Modi
fonte
Isso é algo normalmente feito na definição do tema.
wasamasa
Embora possa ficar complicado, parece que você pode usar a colorbiblioteca aqui. Você provavelmente pode obter o valor rgb ou hexadecimal da face do plano de fundo, determinar algum valor limite para "escuro" e definir o primeiro plano de acordo.
Dan
@wasamasa Sim. Mas, para alguns rostos, não me importo com a cor específica do tema. Atualizei minha pergunta com um exemplo de rosto que quero personalizar.
Kaushal Modi
@ Dan Qual seria um gancho apropriado para reavaliar o hexadecimal em segundo plano?
Kaushal Modi
esta é a lógica que você pode usar `(deffface changing-face '((((fundo escuro)): primeiro plano" Branco ") (t: primeiro plano" Preto ")): agrupe' x-mode-faces)` ... Como se você quiser usar a face existente, poderá adicionar as 2 linhas do meio ao formulário de desfoque existente.
21415 Madhavan

Respostas:

9

Graças a @MhavhavanKumar, concentrei-me em obter uma solução baseada em defface.

Percebi que não posso substituir um existente, deffacemas sempre posso criar minha própria cor de plano de fundo sensível defface. Em seguida, a única questão era como usar meu deffface personalizado em vez do original.

Usarei o mesmo exemplo de substituição do stripe-hl-linerosto para percorrer a solução. Essa cara é definida no pacote stripe-buffer.

Aqui estão os passos:

Etapa 1. Defina seu próprio 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)

Isso fará com que a cor do primeiro plano do my/stripe-hl-linerosto fique azul desobstruída para fundos escuros e vermelha para fundos claros.

Etapa 2. Crie uma função para remapear a face

A face-remap-add-relativefunção é usada para remapear uma face existente para uma nova face. Neste caso, estou remapeando o stripe-hl-linerosto para my/stripe-hl-line.

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

Etapa 3. Faça o remapeamento no local apropriado

Da stripe-bufferfonte, vejo que o hl-linerosto é remapeado para o stripe-hl-linerosto. Então, precisamos fazer o remapeamento depois que o remapeamento acontecer (que está na stripe-listify-bufferdefinição da função).

Então, fazemos o remapeamento aconselhando o stripe-listify-bufferuso do combinador.:after advice

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

Feito!

Dito isto, teria sido incrível usar diretamente algo como set-face-attributedefinir rostos com base na escuridão do fundo.

Kaushal Modi
fonte