[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

face inheritance [was: Find out what is setting color in minibufer]

From: Drew Adams
Subject: face inheritance [was: Find out what is setting color in minibufer]
Date: Sun, 27 Nov 2016 10:15:25 -0800 (PST)

> After all, I would say it's a Geiser problem: faces should 
> inherit from other (particuarly 'font-lock') faces and
> should not copy their specs as it is done in Geiser faces.

I have nothing to say about the particular question raised
in this thread.  But I have a comment about the last, "faces 
should" statement (which is a _general guideline_ and, like
my comment, not a judgment about this particular Geiser

I could not disgree more - both with the general claim and
with the "particularly 'font-lock'" part.

Code should NOT create faces that inherit from other faces,
unless the intention is precisely to create such a default
dependence (only by default, since faces can always be

In particular, faces should generally NOT inherit from
font-lock faces, unless you really want/need such a

If you don't believe me, just ask yourself what happens
when a user customizes your new face: the dependence is
gone. If you are relying on it as more than just a
convenience for defaulting attribute values, then you
are out of luck.

And if for some reason your code really needs such a
dependency to remain, so that there is no way to customize
the new face, and the only change a user should make is to 
customize the inherited (e.g. font-lock) face, then your
code should just use that face directly and not define a
new face that inherits from it.

The easiest way to see what the right approach is for your
code is to play user and customize the face.  If the result
is broken behavior then you should not have defined the face
in the first place.

If you define a face, then users are, and should be, able to
change it.  If your code tries to highlight something with
that face, and if that something is also being highlighted
by some other code, in particular by font-locking, then that
is a conflict that you need to take care of.

It should be quite possible for a user to customize certain
faces whose effect is NOT changed by imposing or changing a
theme.  Other faces, on the other hand, are expected to be
changed by a given theme.  A theme typically does not affect
all faces.  It all depends on what you want for your code,
including what you want its users to be able to do.

IMHO, there is far too much code that defines faces using
inheritance (and this includes some in the distributed Emacs
code).  That can be useful, but its strength is also its
weakness: Any change to the inherited face affects the new
face - unless the user customizes the latter.

Faces are defined for a given initial context.  When they
are reused for a completely different context the result
is something else again.  If the contexts are similar enough
then the reuse might still work; otherwise, it might not.

For example, a particular color for a font-lock face such
as `font-lock-lock-keyword-face', might make perfect sense
for typical font-lock, programming contexts.  But it might
not make sense for some other context - even if it might
seem to its author to look good in the default context.

Font-lock faces, in particular, work together.  If a user
changes one or two to fit her context, she may also change
some of the others.

The reflection of such a change in the context of a
library that defines a face that inherits from a font-lock
face will not necessarily be TRT.  And that can force a
user to customize the face that inherits.

When you use a face for your library, ask yourself how
similar its use/behavior is to that of a face defined for
another context:

* If it is very, VERY similar, then you might want to just
  use that existing face (no new face).

* If it is very similar, but you want users to be able to
  change it independently, then you might want to use a
  new face that inherits from the existing face.

* If it is not very similar then you might want to define
  it without using inheritance.

In particular, do NOT inherit from a face just because you
think its default attributes (e.g. colors) are appropriate
as defaults for your context.  If that is the ONLY reason
you are considering inheritance then just define a new
face with the same attribute values - no inheritance.

The goal should be to do something appropriate for your
specific context that is also the most helpful for users.
The goal should NOT be to minimize the number of faces.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]