On Fri, Feb 4, 2011 at 6:10 AM, Drew Adams wrote: > > As Drew said, faces need to make sense in their context. > > > > I just spent some time picking sensible faces from the font-lock-* > > palette for dired+, which by default defines its own static faces. > > That's my fault. I defined the default Dired+ face colors only for light > backgrounds. I DTRT for Icicles long ago, but I never got around to doing > the > same for Dired+. > > I've done that now, thanks to your reminder. (However, I intentionally do > not > use face inheritance - see below.) > > FWIW, for this I simply use the complements of the light-background default > colors as the dark-background colors. That is not necessarily ideal, but > it at > least is reasonable and consistent. It is also very quick to do, given > some > code (e.g. hexrgb.el or palette.el) that quickly gives you color > complements. > > Such defaulting could presumably even be built-in (optionally). For > example, we > could allow a dark-background setting to be just a symbol `complement' or > `:complement', which would mean to pick up the `t' setting or the > light-background setting (if present) and use its complement. Likewise for > light-background setting - whatever is defined would be used for the other > setting, as a complement. That way a coder could provide a minimal face > definition and still get something reasonable for other background modes. > > This could obviously be made more sophisticated, but any such feature could > be > an improvement, helping with the problem of coders being lazy and just > defining > defaults for one background mode (e.g. light in my case; that is, I > designed for > light but defined it as `t', meaning all). > > ---- > > Wrt face inheritance - > > Faces are customizable - they are just like user options. In particular, > faces > are _not colors_ and faces are _not constants_. Color names and RGB hex > codes > are essentially constants (even if they can appear slightly different on > different systems etc.). > > IMO, it makes sense for a face B to inherit from another face A _only_ when > what > is wanted is that customization of A automatically is reflected in B. When > doing this, we should _always_ expect and assume that A will be customized > by > users. This is true no matter how "basic" A is. > > This is why (IMO) it does _not_ make sense in general for faces to inherit > from > font-lock faces. A user will want to customize a font-lock face in order > to > affect the appearance of _font-locking_, typically in code. It does not > generally make sense for a non-font-lock face to automatically become > affected > by such customization. Example: basing a Dired face on a font-lock face > would > be perverted (IMO). > > My guess is that people who are thinking that inheritance from a few (or > even > many) "basic" faces (font-lock or others) is a good idea are not taking > customization of such basic faces by users into account. IOW, they are not > considering them as _faces_, but rather as constants (e.g. as colors or > color > combos). > > There would be nothing wrong with defining some _constants_ from which > faces > could inherit - not defface but something else that indicates the intention > of > not being customized. Nothing wrong with coming up with such "basic faces" > that > would never be customized. > > But what would that mean? In this case what is important is not the > _usage_ of > the face (it cannot be; that cannot be known), but just its attributes: > colors > etc. IOW, instead of a basic face `highlight' intended for highlighting we > would have basic faces whose names reflect only their appearance: > `red-foreground-bold-boxed' etc. > > But though there would be nothing wrong with defining such constant faces, > it > would be truly silly. There is no sense defining such attribute > combinations - > no sense defining (uncustomizable) faces for this. We already have such > constants: the colors themselves (names and #RGB hex codes). And numbers > for > weights etc. Defining combinations as constants makes little sense. > > It is proper to base defface definitions on such constants, but not (in > general) > on other faces. The only time the latter is appropriate (IMO) is when we > really > want customizing face A to affect face B which inherits from A. You do > not, I > think, want a Dired face to change just because a user tweaks a font-lock > face > to make code comments stand out differently. > > The real problem that I'm guessing motivates the (misguided) attempts to > base > faces upon each other is that too often the default values of faces are not > defined well enough (see the Dired+ mea culpa above). Too often too little > effort is devoted to defining the default attributes. > > The other problem that has been mentioned is being able to apply different > themes and have the result be more or less reasonable across sets of faces. > I > think that this is not a fundamental problem but is only derivative from > not > having good defaults. Just having reasonable default values that cover > both > light and dark backgrounds will go a long way toward eliminating this > problem, I > expect. > > In addition, tools that let users easily change whole sets of faces > together, > incrementally, can help. Do Re Mi offers some help in this way, and other > such > tools can be envisaged. > > Example: command `doremi-all-faces-fg+' lets you incrementally modify all > face > foregrounds at once (hue, saturation, brightness, red, green, and/or blue). > Obviously such a command is limited, but in combination with others it can > be a > real help for customizing - and even for defining themes. > > I'd be interested in hearing more arguments in favor of faces inheriting > from > faces (e.g. "basic" faces). So far it all seems misguided to me, but > perhaps > I'm missing a thing or two. Please be clear about (a) the _problems_ you > are > trying to solve this way, and (b) _how_ you think face inheritance can > solve > them. > > OK, I'll have a go.... While I appreciate your point of concern regarding the fact inheritance would 'link' faces with little or no apparent connection to each other , possibly resulting in 'odd' results when a user customizes a face, I disagree with most of your assumptions and resulting conclusions regarding motivation. I am also not convinced that this is a true problem or one of any significant issue. Likewise, while I can understand the argument that the relationship between faces should be based on some obvious/clear relationship, I'm not sure this is a real issue in practice or if it is, it is more a curiosity rather than a problem i.e. wow, that seems like a strange face to inherit from, but not something anyone would spend hours trying to understand. One thing I would recommend doing, if possible, would be to spend some time running emacs with a dark background and on a tty. This would likely reveal how bad some default face definitions are and let you see how tedious it is having to customize lots of individual face definitions just to get ones that work. As I see it, we want to achieve four main goals. We want to make it easier for developers to set appropriate defaults, we want to get the best default possible for end users, regardless of platform or light/dark background preferences, we want to make it as easy as possible for end users to customize their environment and we want to, if possible, avoid a proliferation of different face definitions, especially when the definitions don't really differ in anything other than name as this makes customizing and theme definition more complex than it needs to be. For all environments, there are a fairly limited set of possible usable face definitions and it would be good if we could have something which allows maximum flexibility, but minimum maintenance and easy customization. It was good you pointed out that faces are not just about colour. Sometimes, I think peopoe forget this and only focus on the colour aspect. However, this is understandable as colour is what distinguishes most faces from each other. We need to acknowledge how difficult it is to define good default faces. Many definitions fail to do this. While your suggestion of using colour compliments can help, I'm not convinced it is always that easy. One problem is that different environments have different sets of colours to work with. For example, if you work under the linux console, you don't have compliments for most of the colours available under other environments, such as X or (I presume) Windows/Mac. The problem is further complicated because most developers won't have access to many of these environments, so can't easil test and design appropriate faces even if motivated to do so. I would not argue that inheritance is an ideal solution to this problem, However, I do think it can be part of the solution. Perhaps something along the lines of * Establish guidelines on how to use inheritance i.e. how to select which face to inherit from * Define a good (not too large) set of base faces. Existing font-lock faces may be sufficient, maybe not. Would need review. * Require all face definitions in core emacs packages to either fully define a face (i.e. definition for dark/light, tty, X mac ms etc) OR inherit from a base face (assuming all base faces are fully defined) * Add a section to the manual encouraging developers to either provide a fully defined face or inherit from a base face, but don't just define a single (usually) light background face The key here is that all faces in core emacs packages would end up with a fully defined face, either explicitly or via inherit. One of the reasons I like the use of inherit for face definitions is mainly from an end user perspective. I would rather have faces that are fully defined via inherit, even if that inheritance seems odd, than have a partially defined face which only works if you have a light background or are running under a full gui environment. If, when I change the base face definition, it results in unacceptable changes to some face which inherits from it, I can customize it. My experience has been that this does sometimes happen, but not that often and it is more preferable to fix up the few faces than to spend much more time configuring lots of individual faces. In fact, as the number of individual face definitions has increased, I actaully think we have gone the wrong direction. We have too many faces which are mostly the same. It seems now that every new package is adding its own face definitions and many of them are poorly defined. It now takes much longer for me to establish a consistent set of faces. If we required face definitions to either be fully defined or inherited from a base set that are fully defined, we would likely give a much better default experience to end users. Using inheritance also means that when we find a face definition which is poor for a particular environment, we can refine that base definition rather than having to find all similarly poor definitions and updating them individually. Using inheritance means that it is easier to make broad changes to face definitions, reducing the time spent in customize and lets you then tweak those specific faces which don't quite work. So, using your example, if someone changed the base face that dired+ uses, either they will find the result in dired+ acceptable or they can then tweak that face further. The alternative is that it would be necessary to customize both faces, even when you are going to set them to the same value. The reality is that there are a limited set of good faces and you will usually end up with the same face definition being used in multiple roles. Frequently, those roles have nothing to do with each other. This doesn't matter as the contexts are completely different. From an end user perspective, it is irrelevant that compiler messages inherit from font-lock-string - all the end user sees is that compiler messages use a default face that is green, which may be exactly the same as strings in their code, but so what. Of course, much of this may become less of an issue now that emacs has support for themes. though there isn't yet any environment specific themes i.e tty, terminal etc. Tim