* Eliminating a couple of independent face definitions @ 2011-02-02 4:05 Chong Yidong 2011-02-02 4:11 ` Lennart Borgman ` (2 more replies) 0 siblings, 3 replies; 43+ messages in thread From: Chong Yidong @ 2011-02-02 4:05 UTC (permalink / raw) To: emacs-devel It would be nice if almost all faces in packaged included with Emacs inherit from the basic or font-lock faces. Most faces already do this. This way, users don't have to specify as much when they write a Custom theme or their own personal face customizations. I'd like to inherit-ize most of the remaining faces that don't already do this. For instance, compilation-warning is currently "Orange", and compilation-info is "Green3"; I want to make them inherit from font-lock-doc-face and font-lock comment-face respectively. (The rest of the compilation-mode already inherit from font-lock faces.) There are a few more similar changes here and there. Any objection? ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 4:05 Eliminating a couple of independent face definitions Chong Yidong @ 2011-02-02 4:11 ` Lennart Borgman 2011-02-02 5:02 ` Tim Cross 2011-02-02 17:16 ` Chong Yidong 2011-02-02 9:58 ` Štěpán Němec 2011-02-02 10:05 ` Julien Danjou 2 siblings, 2 replies; 43+ messages in thread From: Lennart Borgman @ 2011-02-02 4:11 UTC (permalink / raw) To: Chong Yidong; +Cc: emacs-devel On Wed, Feb 2, 2011 at 5:05 AM, Chong Yidong <cyd@stupidchicken.com> wrote: > It would be nice if almost all faces in packaged included with Emacs > inherit from the basic or font-lock faces. Most faces already do this. > This way, users don't have to specify as much when they write a Custom > theme or their own personal face customizations. > > I'd like to inherit-ize most of the remaining faces that don't already > do this. For instance, compilation-warning is currently "Orange", and > compilation-info is "Green3"; I want to make them inherit from > font-lock-doc-face and font-lock comment-face respectively. (The rest > of the compilation-mode already inherit from font-lock faces.) > > There are a few more similar changes here and there. Any objection? Yes. It is really good to try to merge some faces, but the specific merges you mentioned seems a bit unfortunate. The colors were obviously chosen to fit into those used in society for "ok" and "warning". Why not create new faces for such things? (I do not think the font-lock faces have the same meaning tighed to them, but maybe I am wrong there.) ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 4:11 ` Lennart Borgman @ 2011-02-02 5:02 ` Tim Cross 2011-02-02 15:15 ` Drew Adams 2011-02-02 17:17 ` Chong Yidong 2011-02-02 17:16 ` Chong Yidong 1 sibling, 2 replies; 43+ messages in thread From: Tim Cross @ 2011-02-02 5:02 UTC (permalink / raw) To: Lennart Borgman; +Cc: Chong Yidong, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2949 bytes --] On Wed, Feb 2, 2011 at 3:11 PM, Lennart Borgman <lennart.borgman@gmail.com>wrote: > On Wed, Feb 2, 2011 at 5:05 AM, Chong Yidong <cyd@stupidchicken.com> > wrote: > > It would be nice if almost all faces in packaged included with Emacs > > inherit from the basic or font-lock faces. Most faces already do this. > > This way, users don't have to specify as much when they write a Custom > > theme or their own personal face customizations. > > > > I'd like to inherit-ize most of the remaining faces that don't already > > do this. For instance, compilation-warning is currently "Orange", and > > compilation-info is "Green3"; I want to make them inherit from > > font-lock-doc-face and font-lock comment-face respectively. (The rest > > of the compilation-mode already inherit from font-lock faces.) > > > > There are a few more similar changes here and there. Any objection? > > Yes. > > It is really good to try to merge some faces, but the specific merges > you mentioned seems a bit unfortunate. The colors were obviously > chosen to fit into those used in society for "ok" and "warning". Why > not create new faces for such things? (I do not think the font-lock > faces have the same meaning tighed to them, but maybe I am wrong > there.) > > I think the concept of using inherited faces so that all packages inherit from a few well designed faces i.e. have appropriate definitions for light/dark backgrounds, work on the console, in a terminal, under X, on windows etc, is a good one. Having a few base faces to maintain in this way would seem like a positive move and I agree it would make defining custom themes easier. In fact, Ive recently been doing exactly this for VM primarily because I thought it was better to use 'core' faces in that package as they were more likely to be defined based on sound reasoning, testing and feedback and would more likely be acceptable to a larger number of users. My only concern is how you define what to inherit from. For example, in your suggestion of compiler warnings inheriting form font-lock-comment-face I immediately wondered why you would not inherit from font-lock-warning face? It isn't clear to me what rationale would guide the decision as to what base face to inherit from. Without this, the choices could become rather arbitrary and could make face customization or theme definition even more difficult, resulting in apparently arbitrary use of font lock properties (which may be OK, I don't know). It would probably be sufficient to have a clear guideline or set of recommendations which could be applied by developers when deciding on what face to inherit from. However, this probably needs to be done prior to changing definitions to use inherit. I would not expect to get it right or even get consensus on the first go, but it could be refined and improved. Developers may also be more likely to use :inherit if they feel there is some guidance on what to inherit from. Tim [-- Attachment #2: Type: text/html, Size: 3542 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-02 5:02 ` Tim Cross @ 2011-02-02 15:15 ` Drew Adams 2011-02-02 17:17 ` Chong Yidong 1 sibling, 0 replies; 43+ messages in thread From: Drew Adams @ 2011-02-02 15:15 UTC (permalink / raw) To: 'Tim Cross', 'Lennart Borgman' Cc: 'Chong Yidong', emacs-devel I cannot really voice an objection. I'd just point out that inheriting means coupling (dependence). The upside is of course the same as the downside: change an ancestor and you change the descendents. That might be what you want sometimes, and it might not be what you want sometimes. (Of course, inheritance can be overridden/broken.) FWIW, in my own use of faces I tend not to inherit too much. Faces have particular uses (contexts), and it is not that common that the use/purpose is similar enough that inheritance is called for (in my usage, at least). And I disagree with the general tendency here to avoid defining new faces (aka the tendency to reuse faces defined for a different purpose). Having two different faces, even with the same attribute values, designed for two different uses/purposes, makes sense in general. It is not a great idea, in general, to reuse a face just because you want the same color etc. Similarly, I've disagreed with the practice of hard-coding `highlight' as the `mouse-face' property (throughout the code). In general, we should use either a face variable or a new face for each such use, so that users can change the behavior/appearance in different contexts (without redefining the hard-coded code). ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 5:02 ` Tim Cross 2011-02-02 15:15 ` Drew Adams @ 2011-02-02 17:17 ` Chong Yidong 2011-02-02 20:33 ` Philipp Haselwarter ` (2 more replies) 1 sibling, 3 replies; 43+ messages in thread From: Chong Yidong @ 2011-02-02 17:17 UTC (permalink / raw) To: Tim Cross; +Cc: Lennart Borgman, emacs-devel Tim Cross <theophilusx@gmail.com> writes: > My only concern is how you define what to inherit from. For example, > in your suggestion of compiler warnings inheriting form > font-lock-comment-face I immediately wondered why you would not > inherit from font-lock-warning face? font-lock-warning-face is already used for compilation errors, which are more serious than warnings. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 17:17 ` Chong Yidong @ 2011-02-02 20:33 ` Philipp Haselwarter 2011-02-02 23:01 ` Lennart Borgman 2011-02-03 19:10 ` Drew Adams 2011-02-02 21:24 ` Eliminating a couple of independent face definitions Tim Cross 2011-02-03 16:14 ` Dan Nicolaescu 2 siblings, 2 replies; 43+ messages in thread From: Philipp Haselwarter @ 2011-02-02 20:33 UTC (permalink / raw) To: emacs-devel "CY" == Chong Yidong <cyd@stupidchicken.com> writes: CY> Tim Cross <theophilusx@gmail.com> writes: >> My only concern is how you define what to inherit from. For example, >> in your suggestion of compiler warnings inheriting form >> font-lock-comment-face I immediately wondered why you would not >> inherit from font-lock-warning face? CY> font-lock-warning-face is already used for compilation errors, which CY> are more serious than warnings. Why not have a font-lock-warning face and a font-lock-error face? I think some more reasonably named generic fonts to pick from would make theming a lot easier. 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. Most themes don't address these, resulting in readability issues. I ended up with a nice looking setup, but the face names make no sense *at all* in their context. Some generic faces, that could guarantee some extend of contrast between them would make consistency much easier. -- Philipp Haselwarter ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 20:33 ` Philipp Haselwarter @ 2011-02-02 23:01 ` Lennart Borgman 2011-02-03 19:10 ` Drew Adams 1 sibling, 0 replies; 43+ messages in thread From: Lennart Borgman @ 2011-02-02 23:01 UTC (permalink / raw) To: Philipp Haselwarter; +Cc: emacs-devel On Wed, Feb 2, 2011 at 9:33 PM, Philipp Haselwarter <philipp.haselwarter@gmx.de> wrote: > > Why not have a font-lock-warning face and a font-lock-error face? +1 And I would also like to see some set of "state" faces, like "wait", "ready", etc. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-02 20:33 ` Philipp Haselwarter 2011-02-02 23:01 ` Lennart Borgman @ 2011-02-03 19:10 ` Drew Adams 2011-02-04 0:12 ` Tim Cross ` (2 more replies) 1 sibling, 3 replies; 43+ messages in thread From: Drew Adams @ 2011-02-03 19:10 UTC (permalink / raw) To: 'Philipp Haselwarter', emacs-devel > 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. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-03 19:10 ` Drew Adams @ 2011-02-04 0:12 ` Tim Cross 2011-02-05 22:11 ` Drew Adams 2011-02-04 0:18 ` Stephen J. Turnbull 2011-02-04 10:26 ` Julien Danjou 2 siblings, 1 reply; 43+ messages in thread From: Tim Cross @ 2011-02-04 0:12 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel, Philipp Haselwarter [-- Attachment #1: Type: text/plain, Size: 12359 bytes --] On Fri, Feb 4, 2011 at 6:10 AM, Drew Adams <drew.adams@oracle.com> 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 [-- Attachment #2: Type: text/html, Size: 13475 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-04 0:12 ` Tim Cross @ 2011-02-05 22:11 ` Drew Adams 2011-02-07 0:59 ` Drew Adams 2011-02-07 1:08 ` Tim Cross 0 siblings, 2 replies; 43+ messages in thread From: Drew Adams @ 2011-02-05 22:11 UTC (permalink / raw) To: 'Tim Cross'; +Cc: emacs-devel, 'Philipp Haselwarter' T> One thing I would recommend doing, if possible, would be to T> spend some time running emacs with a dark background and on a T> tty. This would likely reveal how bad some default face T> definitions are and let you see how tedious it is having to T> customize lots of individual face definitions just to get ones T> that work. I'm not sure what your disagreements are with what I said. I agree that poorly defined default face definitions are a real problem. I even suggested that they are likely _the_ real problem here. Given reasonable face defaults that work out of the box on both dark and light backgrounds, I think many if not most (perhaps all?) of the problems you cited go away. With faces that just work by default, regardless of the background, there is no need to "customize lots of individual face definitions just to get ones that work". T> As I see it, we want to achieve four main goals. We want to T> make it easier for developers to set appropriate defaults, we T> want to get the best default possible for end users, T> regardless of platform or light/dark background preferences, T> we want to make it as easy as possible for end users to T> customize their environment Agree. T> and we want to, if possible, avoid a proliferation of T> different face definitions, especially when the definitions T> don't really differ in anything other than name as this makes T> customizing and theme definition more complex than it needs to T> be. Disagree, if by "don't really differ in anything other than the name" you are referring only to the `defface' default attribute values. I am in favor of there being two faces instead of one, if their use/meaning is different, even if their definitions modulo the names are identical. In particular, this facilitates separate customization. It avoids coupling that is not logical and not necessary. Inheritance (hence coupling) based on physical attributes (appearance) can perhaps occasionally be appropriate, but in general it is a no-no. (Names are generally indicative of meaning, but yes, there could be two faces with different names yet identical meaning. In that case, yes, the duplication could be eliminated.) (There is an orthogonal reason to avoid using too many faces at the same time: performance. But that is a different story altogether.) T> It was good you pointed out that faces are not just about T> colour. Sometimes, I think peopoe forget this and only focus T> on the colour aspect. However, this is understandable as T> colour is what distinguishes most faces from each other. T> T> We need to acknowledge how difficult it is to define good T> default faces. Many definitions fail to do this. While your T> suggestion of using colour compliments can help, I'm not T> convinced it is always that easy. One problem is that T> different environments have different sets of colours to work T> with. For example, if you work under the linux console, you T> don't have compliments for most of the colours available under T> other environments, such as X or (I presume) Windows/Mac. The T> problem is further complicated because most developers won't T> have access to many of these environments, so can't easil test T> and design appropriate faces even if motivated to do so. Agree. I did not mean to raise complementing as any kind of cure-all - far from it. I was just mentioning that I provided a quick-and-dirty set of default settings for dark backgrounds for a particular library by flipping the light-background defaults to their complements. Obviously, any set of defaults for either light or dark deserves to be well thought out. And all of the considerations you mention should be taken into account. The tty thing is a big limitation, in particular. Designing a set of faces for use on tty only is a different task from designing a set for use with many colors and other attributes. For a library that is intended to work with both tty and graphic windows, either tradeoffs are called for or essentially two modes or face schemes are needed: full and degraded (tty). We have constructs like `(type tty pc)' that can help with that. T> I would not argue that inheritance is an ideal solution to T> this problem, However, I do think it can be part of the T> solution. Perhaps something along the lines of T> T> * Establish guidelines on how to use inheritance i.e. how to T> select which face to inherit from T> * Define a good (not too large) set of base faces. Existing T> font-lock faces may be sufficient, maybe not. Would need T> review. T> * Require all face definitions in core emacs packages to T> either fully define a face (i.e. definition for dark/light, T> tty, X mac ms etc) OR inherit from a base face (assuming T> all base faces are fully defined) T> * Add a section to the manual encouraging developers to T> either provide a fully defined face or inherit from a base T> face, but don't just define a single (usually) light T> background face T> T> The key here is that all faces in core emacs packages would T> end up with a fully defined face, either explicitly or via T> inherit. Fully-defined, yes - good. The part that I think can be misguided is basing everything on inheritance from faces that are not necessarily related in terms of use or meaning. Basing a face on a related face is not bad. Stretching things to base all faces on some "basic" faces, no matter how unrelated in terms of meaning or context, is not a great idea. Faces, including "basic" faces, are customizable. You don't want a user who customizes `font-lock-doc-face' to suddenly find that s?he has also affected a chain of unrelated faces that inherit from it. Customizing font-lock faces should not affect Dired or Info or... T> One of the reasons I like the use of inherit for face T> definitions is mainly from an end user perspective. I would T> rather have faces that are fully defined via inherit, even if T> that inheritance seems odd, than have a partially defined face T> which only works if you have a light background or are running T> under a full gui environment. Those are not the only two alternatives - it's not either-or. I am in favor of full face definitions. And I am not against inheritance. The important thing is for a face to inherit only from a related face (in terms of use/meaning). The key is whether it will generally make sense for the inheriting face if the inherited face gets customized. If not, then inheritance is likely not the best way to go. T> If, when I change the base face definition, it results in T> unacceptable changes to some face which inherits from it, I T> can customize it. Sure you can, but now you're back to customizing all over the place - and now across multiple libraries and multiple use contexts, to boot. The cure is at least as bad as the disease. Nothing wrong with inheritance. But boiling everything down to font-lock faces (or similar) is a bad idea. Better for face inheritance to reflect face usage/meaning: families (inheritance hierarchies) of related faces, not just everything inheriting from primordial faces `adam' and `eve'. T> My experience has been that this does sometimes happen, but T> not that often and it is more preferable to fix up the few T> faces than to spend much more time configuring lots of T> individual faces. I think you are again thinking of the fact that you are needing to configure lots of faces because they were defined incompletely or with poor defaults. Take away that presupposition and where is the argument? T> In fact, as the number of individual face definitions has T> increased, I actaully think we have gone the wrong direction. T> We have too many faces which are mostly the same. They are not the same just because they have the same _appearance_ (by _default_ no less). This is a key element in the confusion, I think. It sounds like it motivated Yidong's search for faces to eliminate "duplication" via inheritance. Faces are not the same as their (attribute) values. Faces have identity and purpose as well as values. This is essentially no different from having multiple user options (or other variables) that have the same value: 42, nil, t,... You would not argue that we define a set of "basic" user options and use inheritance to factor out any "duplicate" options that have the same default value of 42 or nil, would you? You would not argue that we should have only one primeval user option with a default value of 42, and inherit from it for wildly different options with different use cases (meanings), so that someone who customizes the "basic" option to change the value 42 to 24 ends up changing lots and lots of inheriting options. Would you? How are faces different in this regard? T> It seems now that every new package is adding its own face T> definitions Good. That should probably happen more than it does. ;-) If reasonable, related faces exist on which to base the new face definitions, then by all means inheritance might well be called for. But a new package should _not_ avoid adding its own face definitions, whether they are defined using inheritance or not (i.e., pointer or copy). On the contrary. What should be avoided is reusing some face that makes no sense in the current context. What is the _practical_ criterion? Whether or not customizing the face wrt its original context/purpose will have a negative effect in the new context. If not, then go for it (reuse/inherit). T> and many of them are poorly defined. It now takes much T> longer for me to establish a consistent set of faces. Bad - agreed. But not a necessary consequence of having many faces. More likely a consequence of poor default definitions (as you mentioned). T> If we required face definitions to either be fully defined or T> inherited from a base set that are fully defined, we would T> likely give a much better default experience to end users. Full face definitions are good, yes. That is independent of the question of inheritance. Well... indiscrimately imposing inheritance (from fully defined faces) can ensure full definitions. But it has a cost: it can also introduce unnecessary and unwanted dependencies with negative consequences. T> Using inheritance also means that when we find a face T> definition which is poor for a particular environment, we can T> refine that base definition rather than having to find all T> similarly poor definitions and updating them individually. Yes and no. "Fixing" it for one environment might do exactly the wrong thing for another context, e.g. for one of its descendents. Inheritance needs to be used carefully, based on intended use/meaning of the faces involved. T> Using inheritance means that it is easier to make broad T> changes to face definitions, reducing the time spent in T> customize and lets you then tweak those specific faces which T> don't quite work. T> T> So, using your example, if someone changed the base face that T> dired+ uses, either they will find the result in dired+ T> acceptable or they can then tweak that face further. The T> alternative is that it would be necessary to customize both T> faces, even when you are going to set them to the same value. Maybe, maybe not. Depends what kind of change you want/need. It's true that if you want to change all occurrences of red foreground to blue then more customization would be involved without inheritance. Maybe we could find a way to make such changes easier - I don't have a problem with that. But we should not be using _inheritance_ for that (in general). A Dired face should either not inherit or it should inherit from a related face, not just some face whose _default appearance_ looks good for Dired. It makes no sense to base a Dired face on a font-lock face, for instance. Just because you might want some Dired face to have a red foreground by default is no reason to go looking for a face with a red foreground to inherit from. Look instead for a face with a related use/meaning. If you find none, then do not use inheritance here. That's the guideline I'd suggest. I emphasize the use/meaning of a given face: what it is for, what it represents, what it does. I think you are emphasizing its default appearance - attribute values (color etc.). To me, a face or a variable `foo' is mainly about its use, not its value. If the opposite were true, then we would name faces and variables after their default values, not after their uses. Yes, I've seen some Lisp code with face names like `underlined-bold-red-foreground-on-gray-background'. (Mea culpa: I even wrote such code at one point.) And there's not necessarily anything wrong with that; for some contexts it might make sense. But in that case it makes more sense for the "face" to be a constant, not customizable. It would be perverse to customize a face named `red-foreground' to have a green foreground. (And in general it is more likely for single attributes to be reuse candidates than it is for combinations of attributes.) T> The reality is that there are a limited set of good faces and T> you will usually end up with the same face definition being T> used in multiple roles. Frequently, those roles have nothing T> to do with each other. This doesn't matter as the contexts T> are completely different. From an end user perspective, it is T> irrelevant that compiler messages inherit from T> font-lock-string - all the end user sees is that compiler T> messages use a default face that is green, which may be T> exactly the same as strings in their code, but so what. I strongly disagree here. If the roles/meanings/use are unrelated, then inheritance is usually inappropriate. It _does_ matter whether a compiler-messages face inherits from `font-lock-string-face' - _if_ someone customizes that parent face. If we defined a compiler-messages face to inherit from `font-lock-string-face' _only_ because we liked the default foreground choice of `LightSalmon', that would be misguided, IMO. If there is no existing face that is related in terms of use/meaning, then the compiler-messages face should not inherit; it should just be defined with a default foreground of `LightSalmon'. That kind of duplication is not a curse but a blessing. Then a user can customize either the compiler-messages face or `font-lock-string-face' without affecting the other. And that makes sense because (by hypothesis) the two are unrelated. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-05 22:11 ` Drew Adams @ 2011-02-07 0:59 ` Drew Adams 2011-02-07 1:30 ` Tim Cross 2011-02-08 13:58 ` Davis Herring 2011-02-07 1:08 ` Tim Cross 1 sibling, 2 replies; 43+ messages in thread From: Drew Adams @ 2011-02-07 0:59 UTC (permalink / raw) To: 'Tim Cross'; +Cc: 'Philipp Haselwarter', emacs-devel Tim pointed out the problem of faces that are not fully defined, in particular, for light and dark backgrounds (and for tty). He pointed to the need for the Emacs source code to define all faces fully so that they work, out-of-the-box, regardless of default background etc. And he pointed to the fact that, given such a basis, inheritance can carry the ball forward so that newly created faces are more likely, themselves, to be fully defined - without programmers needing to be face experts or jump through hoops. I agreed with Tim that it is good to fully define faces. Not doing so makes users customize more than they should need to. But I also explained why inheritance can be overkill as a solution to this problem. Inheritance should be used when the inheriting face is related to the inherited face - similar use/meaning/purpose. It should (generally) be avoided when there is no such relation. Inheritance does a good job of enforcing full face definition (given solid starting points). Can we get the same benefit some other way - a way that is not error prone by relying on programmers to copy full definitions by hand etc.? Sure - just use a copy instead of a pointer. What's bad about inheriting an unrelated fully-defined face is that customizing that face also changes the inheriting face. But that only happens because the new face always points to its ancestor for its attribute values. Why not introduce a new `defface' keyword `:copy-default'? It would define the new face with the same default attribute values as another face. A copy of those values (actually, of the attributes spec) would be made at `defface' time. The two faces would remain independent instead of being joined at the hip. Only the _default_ attribute values would be used; the current values of the reference face would have no effect at any time. If face `barred-foo' is unrelated to font-locking and strings, then instead of this (which is identical to the `defface' for `font-lock-doc-face): (defface barred-foo '((t :inherit font-lock-string-face)) "Face to use for foos that are barred." :group 'foobar) You would use this: (defface barred-foo '((t :copy-default font-lock-string-face)) "Face to use for foos that are barred." :group 'foobar) The new face `barred-foo' would have no relation to `font-lock-string-face'. A user could customize the latter without that change affecting the former. The result of the `defface' would be identical to this complex definition (taken from the definition of `font-lock-string-face'): (defface barred-foo '((((class grayscale) (background light)) (:foreground "DimGray" :slant italic)) (((class grayscale) (background dark)) (:foreground "LightGray" :slant italic)) (((class color) (min-colors 88) (background light)) (:foreground "VioletRed4")) (((class color) (min-colors 88) (background dark)) (:foreground "LightSalmon")) (((class color) (min-colors 16) (background light)) (:foreground "RosyBrown")) (((class color) (min-colors 16) (background dark)) (:foreground "LightSalmon")) (((class color) (min-colors 8)) (:foreground "green")) (t (:slant italic))) "Face to use for foos that are barred." :group 'foobar) Simple for even lazy programmers to use. Not so error-prone for eager programmers who might otherwise try to make such a copy by hand. Guaranteed to be as reasonable for all backgrounds and tty as is the tried-and-true `font-lock-string-face'. Anywhere you might use `:inherit' in a face definition you could use `:copy-default'. The same `defface' could use both `:inherit' and `:copy-default', to inherit some attribute values from one face and copy others (defaults) from another. We would encourage programmers to use `:inherit' when the new face (its use/meaning/purpose) is related to the referenced face - that is, when they want a change in the latter to be reflected in the former. (`font-lock-doc-face' inherits from `font-lock-string-face' because they are related.) We would encourage them to use `:copy-default' when the referenced face is unrelated and all they want to do is reuse its default-attributes spec. (`barred-foo' is about foos, not about font-locking or strings.) I expect that the latter case is more common than the former, but I could be wrong. New faces are often created together, as a group in some library, and these are often related in terms of use/purpose, so inheritance among them can make sense. But it is less likely that there is an existing face outside of that context whose use/meaning/purpose is related. IOW, I see inheritance as most useful within a library or among related libraries. It's worth quoting Tim again here. Having `:copy-default' in addition to `:inherit' would improve the solution, I think. T> I would not argue that inheritance is an ideal solution to T> this problem, However, I do think it can be part of the T> solution. Perhaps something along the lines of T> T> * Establish guidelines on how to use inheritance i.e. how to T> select which face to inherit from T> * Define a good (not too large) set of base faces. Existing T> font-lock faces may be sufficient, maybe not. Would need T> review. T> * Require all face definitions in core emacs packages to T> either fully define a face (i.e. definition for dark/light, T> tty, X mac ms etc) OR inherit from a base face (assuming T> all base faces are fully defined) T> * Add a section to the manual encouraging developers to T> either provide a fully defined face or inherit from a base T> face, but don't just define a single (usually) light T> background face T> T> The key here is that all faces in core emacs packages would T> end up with a fully defined face, either explicitly or via T> inherit. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-07 0:59 ` Drew Adams @ 2011-02-07 1:30 ` Tim Cross 2011-02-07 14:09 ` Drew Adams 2011-02-08 13:58 ` Davis Herring 1 sibling, 1 reply; 43+ messages in thread From: Tim Cross @ 2011-02-07 1:30 UTC (permalink / raw) To: Drew Adams; +Cc: Philipp Haselwarter, emacs-devel [-- Attachment #1: Type: text/plain, Size: 6983 bytes --] On Mon, Feb 7, 2011 at 11:59 AM, Drew Adams <drew.adams@oracle.com> wrote: > Tim pointed out the problem of faces that are not fully defined, in > particular, > for light and dark backgrounds (and for tty). He pointed to the need for > the > Emacs source code to define all faces fully so that they work, > out-of-the-box, > regardless of default background etc. > > And he pointed to the fact that, given such a basis, inheritance can carry > the > ball forward so that newly created faces are more likely, themselves, to be > fully defined - without programmers needing to be face experts or jump > through > hoops. > > I agreed with Tim that it is good to fully define faces. Not doing so > makes > users customize more than they should need to. But I also explained why > inheritance can be overkill as a solution to this problem. Inheritance > should > be used when the inheriting face is related to the inherited face - similar > use/meaning/purpose. It should (generally) be avoided when there is no > such > relation. > > Inheritance does a good job of enforcing full face definition (given solid > starting points). Can we get the same benefit some other way - a way that > is > not error prone by relying on programmers to copy full definitions by hand > etc.? > > Sure - just use a copy instead of a pointer. What's bad about inheriting > an > unrelated fully-defined face is that customizing that face also changes the > inheriting face. But that only happens because the new face always points > to > its ancestor for its attribute values. > > Why not introduce a new `defface' keyword `:copy-default'? It would define > the > new face with the same default attribute values as another face. A copy of > those values (actually, of the attributes spec) would be made at `defface' > time. > The two faces would remain independent instead of being joined at the hip. > Only > the _default_ attribute values would be used; the current values of the > reference face would have no effect at any time. > > If face `barred-foo' is unrelated to font-locking and strings, then instead > of > this (which is identical to the `defface' for `font-lock-doc-face): > > (defface barred-foo '((t :inherit font-lock-string-face)) > "Face to use for foos that are barred." > :group 'foobar) > > You would use this: > > (defface barred-foo '((t :copy-default font-lock-string-face)) > "Face to use for foos that are barred." > :group 'foobar) > > The new face `barred-foo' would have no relation to > `font-lock-string-face'. A > user could customize the latter without that change affecting the former. > > The result of the `defface' would be identical to this complex definition > (taken > from the definition of `font-lock-string-face'): > > (defface barred-foo > '((((class grayscale) (background light)) > (:foreground "DimGray" :slant italic)) > (((class grayscale) (background dark)) > (:foreground "LightGray" :slant italic)) > (((class color) (min-colors 88) > (background light)) (:foreground "VioletRed4")) > (((class color) (min-colors 88) > (background dark)) (:foreground "LightSalmon")) > (((class color) (min-colors 16) > (background light)) (:foreground "RosyBrown")) > (((class color) (min-colors 16) > (background dark)) (:foreground "LightSalmon")) > (((class color) (min-colors 8)) > (:foreground "green")) > (t (:slant italic))) > "Face to use for foos that are barred." > :group 'foobar) > > Simple for even lazy programmers to use. Not so error-prone for eager > programmers who might otherwise try to make such a copy by hand. > Guaranteed to > be as reasonable for all backgrounds and tty as is the tried-and-true > `font-lock-string-face'. > > Anywhere you might use `:inherit' in a face definition you could use > `:copy-default'. The same `defface' could use both `:inherit' and > `:copy-default', to inherit some attribute values from one face and copy > others > (defaults) from another. > > We would encourage programmers to use `:inherit' when the new face (its > use/meaning/purpose) is related to the referenced face - that is, when they > want > a change in the latter to be reflected in the former. > (`font-lock-doc-face' > inherits from `font-lock-string-face' because they are related.) > > We would encourage them to use `:copy-default' when the referenced face is > unrelated and all they want to do is reuse its default-attributes spec. > (`barred-foo' is about foos, not about font-locking or strings.) > > I expect that the latter case is more common than the former, but I could > be > wrong. > > New faces are often created together, as a group in some library, and these > are > often related in terms of use/purpose, so inheritance among them can make > sense. > But it is less likely that there is an existing face outside of that > context > whose use/meaning/purpose is related. IOW, I see inheritance as most > useful > within a library or among related libraries. > > It's worth quoting Tim again here. Having `:copy-default' in addition to > `:inherit' would improve the solution, I think. > > T> I would not argue that inheritance is an ideal solution to > T> this problem, However, I do think it can be part of the > T> solution. Perhaps something along the lines of > T> > T> * Establish guidelines on how to use inheritance i.e. how to > T> select which face to inherit from > T> * Define a good (not too large) set of base faces. Existing > T> font-lock faces may be sufficient, maybe not. Would need > T> review. > T> * Require all face definitions in core emacs packages to > T> either fully define a face (i.e. definition for dark/light, > T> tty, X mac ms etc) OR inherit from a base face (assuming > T> all base faces are fully defined) > T> * Add a section to the manual encouraging developers to > T> either provide a fully defined face or inherit from a base > T> face, but don't just define a single (usually) light > T> background face > T> > T> The key here is that all faces in core emacs packages would > T> end up with a fully defined face, either explicitly or via > T> inherit. > > Ignoring implementation issues, your suggestion appears to meet the main objective i.e. making it easier for programmers to do the right thing and have fully defined faces without having to jump through all the hoops. I would agree that it is a better solution than using inheritance with semantically unrelated parents as it does appear to provide a solution that does not compromise the strict form of preferred inheritance and a way to improve the quality of default face values. I would suggest that in addition to such enhancements to defface, we need to provide guidelines in the manual on how to use inheritance and copy and would go further and argue that for semantically related faces, inheritance *should* be used to help enhance consistency and allow users to customize a semantic 'class' in one go. Tim [-- Attachment #2: Type: text/html, Size: 7964 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-07 1:30 ` Tim Cross @ 2011-02-07 14:09 ` Drew Adams 2011-02-07 21:14 ` Tim Cross 0 siblings, 1 reply; 43+ messages in thread From: Drew Adams @ 2011-02-07 14:09 UTC (permalink / raw) To: 'Tim Cross'; +Cc: 'Philipp Haselwarter', emacs-devel T> Ignoring implementation issues, your suggestion appears to T> meet the main objective i.e. making it easier for programmers T> to do the right thing and have fully defined faces without T> having to jump through all the hoops. I would agree that it is T> a better solution than using inheritance with semantically T> unrelated parents as it does appear to provide a solution that T> does not compromise the strict form of preferred inheritance T> and a way to improve the quality of default face values. T> T> I would suggest that in addition to such enhancements to defface, T> we need to provide guidelines in the manual on how to use T> inheritance and copy and would go further and argue that for T> semantically related faces, inheritance *should* be used to help T> enhance consistency and allow users to customize a semantic T> 'class' in one go. Yes to guidelines in the manual and yes to encouraging inheritance among faces with similar meaning/use. As I said: d> We would encourage programmers to use `:inherit' when the d> new face (its use/meaning/purpose) is related to the d> referenced face - that is, when they want a change in the d> latter to be reflected in the former. d> We would encourage them to use `:copy-default' when the d> referenced face is unrelated and all they want to do is d> reuse its default-attributes spec. We would encourage them to use one or the other, to get full face definitions able to handle different backgrounds etc. And we would explain when it can be good to use one vs the other. We would also say why full definitions are important, and perhaps use an example to point out characteristics of a full definition. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-07 14:09 ` Drew Adams @ 2011-02-07 21:14 ` Tim Cross 2011-02-07 22:12 ` Drew Adams 0 siblings, 1 reply; 43+ messages in thread From: Tim Cross @ 2011-02-07 21:14 UTC (permalink / raw) To: Drew Adams; +Cc: Philipp Haselwarter, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3245 bytes --] On Tue, Feb 8, 2011 at 1:09 AM, Drew Adams <drew.adams@oracle.com> wrote: > T> Ignoring implementation issues, your suggestion appears to > T> meet the main objective i.e. making it easier for programmers > T> to do the right thing and have fully defined faces without > T> having to jump through all the hoops. I would agree that it is > T> a better solution than using inheritance with semantically > T> unrelated parents as it does appear to provide a solution that > T> does not compromise the strict form of preferred inheritance > T> and a way to improve the quality of default face values. > T> > T> I would suggest that in addition to such enhancements to defface, > T> we need to provide guidelines in the manual on how to use > T> inheritance and copy and would go further and argue that for > T> semantically related faces, inheritance *should* be used to help > T> enhance consistency and allow users to customize a semantic > T> 'class' in one go. > > Yes to guidelines in the manual and yes to encouraging inheritance among > faces > with similar meaning/use. As I said: > > d> We would encourage programmers to use `:inherit' when the > d> new face (its use/meaning/purpose) is related to the > d> referenced face - that is, when they want a change in the > d> latter to be reflected in the former. > > d> We would encourage them to use `:copy-default' when the > d> referenced face is unrelated and all they want to do is > d> reuse its default-attributes spec. > > We would encourage them to use one or the other, to get full face > definitions > able to handle different backgrounds etc. And we would explain when it can > be > good to use one vs the other. > > We would also say why full definitions are important, and perhaps use an > example > to point out characteristics of a full definition. > > There is an example in the maual that shows using the different classes to handle tty, dark/light etc. Of course, this doesn't mean it couldn't be extended/improved. I do see some possible implementation issues with the copy concept though. One problem could be determining when to do the copy. If I have face x and then define face y using your proposed copy semantics, how would you control when that copy occurs. For example, if I customize face x, how will face y know the next time emacs is started to use the old values of face x and not the new customized values? Somehow the defface would need to know to only copy the values from face x the first time it is defined/used i.e. from the first session that the face is used and to then keep those values for future sessions. Without this, you would simply have a form of delayed inheritance, which is likely going to be even more confusing that using normal inheritance as the change would be session dependent and time delayed. This seems like a non-trivial modification to the defface mechanism as it introduces a new state/time dimension i.e. copy face x attributes unless face y attributes have already been copied in a previous session. Maybe defface could have some type of 'initform' exstension that is used to configure the face if it has no custom setting. The result would need to be written to the custom-faces section so that it is only run once. Tim [-- Attachment #2: Type: text/html, Size: 3742 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-07 21:14 ` Tim Cross @ 2011-02-07 22:12 ` Drew Adams 2011-02-08 3:51 ` Tim Cross 0 siblings, 1 reply; 43+ messages in thread From: Drew Adams @ 2011-02-07 22:12 UTC (permalink / raw) To: 'Tim Cross'; +Cc: 'Philipp Haselwarter', emacs-devel T> I do see some possible implementation issues with T> the copy concept though. One problem could be T> determining when to do the copy. If I have face x T> and then define face y using your proposed copy T> semantics, how would you control when that copy occurs. I have not thought about implementation, nor will I really try to. ;-) I leave that to others more knowledgable. I did say what I thought was called for wrt copy time, however: copy when the `defface' with the `:copy-default' gets eval'd. Normally, that's at load time. And I did mention that only the default-attributes spec would be copied from the reference face - not the current values of its attributes: d> Why not introduce a new `defface' keyword `:copy-default'? d> It would define the new face with the same default d> attribute values as another face. A copy of those values d> (actually, of the attributes spec) would be made at d> `defface' time. d> Only the _default_ attribute values would be used; the d> current values of the reference face would have no effect d> at any time. IOW, this is a relation between two face _definitions_ (two `defface's), not between a `defface' and another face's current attribute values. Yes, this would likely require saving the referenced face spec in some form in the byte-compiled reference file, if that is not done already. And it would require copying that spec to the receiver at its `defface' eval time. [Another possibility is to allow copying when the receiver `defface' is byte-compiled, not just when it is eval'd. Dunno whether that would be a good idea or whether it could introduce differences (eval vs compile time).] No, I haven't tried to think this through, and especially not in terms of implementation. Just throwing the idea out there as food for thought by others more qualified. T> For example, if I customize face x, how will face y T> know the next time emacs is started to use the old T> values of face x and not the new customized values? See above. It would always look to face x's _definition_ (`defface'), not to its current attribute values. Customization of face x should have no effect. T> Somehow the defface would need to know to only copy T> the values from face x the first time it is defined/used T> i.e. from the first session that the face is used and T> to then keep those values for future sessions. Not sure I follow you. It would _never_ copy the current values. It would copy only the attributes spec from the reference face, that is, the part of the definition that is called for being copied. But yes, that spec would need to be available, in the source reference file (no problem) and in the byte-compiled reference file. A copy chain could presumably handled: if C copies from B which copies from A, then B's defface would be eval'd before C's defface. There might be some problems to work out, but I don't imagine they would be insurmountable. (But I know nothing about face implementation or byte-compilation.) T> Without this, you would simply have a form of delayed T> inheritance, which is likely going to be even more T> confusing that using normal inheritance as the change T> would be session dependent and time delayed. I don't follow. Again, it is only the default-attributes spec that would be copied, not the current attribute values. Access to that spec is all that is needed, I think. And it should be possible to provide that access through the byte-compiled reference file (as well as through the source reference file) - that is, the file whose `defface' is copied from. But again, I might well be missing a thing or two (or three...). T> This seems like a non-trivial modification to the T> defface mechanism as it introduces a new state/time T> dimension i.e. copy face x attributes unless face y T> attributes have already been copied in a previous session. The current attribute values would never be copied. Only the default-attributes spec would be copied - that is, the part of the reference face's definition (its `defface') that we specified to be copied. T> Maybe defface could have some type of 'initform' T> exstension that is used to configure the face if it T> has no custom setting. The result would need to be T> written to the custom-faces section so that it is T> only run once. I don't follow. But maybe you just misunderstood and thought I meant that the current attribute values would be copied? ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-07 22:12 ` Drew Adams @ 2011-02-08 3:51 ` Tim Cross 2011-02-08 15:26 ` Drew Adams 0 siblings, 1 reply; 43+ messages in thread From: Tim Cross @ 2011-02-08 3:51 UTC (permalink / raw) To: Drew Adams; +Cc: Philipp Haselwarter, emacs-devel [-- Attachment #1: Type: text/plain, Size: 7111 bytes --] On Tue, Feb 8, 2011 at 9:12 AM, Drew Adams <drew.adams@oracle.com> wrote: > T> I do see some possible implementation issues with > T> the copy concept though. One problem could be > T> determining when to do the copy. If I have face x > T> and then define face y using your proposed copy > T> semantics, how would you control when that copy occurs. > > I have not thought about implementation, nor will I really try to. ;-) I > leave > that to others more knowledgable. > > I did say what I thought was called for wrt copy time, however: copy when > the > `defface' with the `:copy-default' gets eval'd. Normally, that's at load > time. > > And I did mention that only the default-attributes spec would be copied > from the > reference face - not the current values of its attributes: > > d> Why not introduce a new `defface' keyword `:copy-default'? > d> It would define the new face with the same default > d> attribute values as another face. A copy of those values > d> (actually, of the attributes spec) would be made at > d> `defface' time. > > d> Only the _default_ attribute values would be used; the > d> current values of the reference face would have no effect > d> at any time. > > IOW, this is a relation between two face _definitions_ (two `defface's), > not > between a `defface' and another face's current attribute values. > > Yes, this would likely require saving the referenced face spec in some form > in > the byte-compiled reference file, if that is not done already. And it > would > require copying that spec to the receiver at its `defface' eval time. > > [Another possibility is to allow copying when the receiver `defface' is > byte-compiled, not just when it is eval'd. Dunno whether that would be a > good > idea or whether it could introduce differences (eval vs compile time).] > > No, I haven't tried to think this through, and especially not in terms of > implementation. Just throwing the idea out there as food for thought by > others > more qualified. > > T> For example, if I customize face x, how will face y > T> know the next time emacs is started to use the old > T> values of face x and not the new customized values? > > See above. It would always look to face x's _definition_ (`defface'), not > to > its current attribute values. Customization of face x should have no > effect. > > T> Somehow the defface would need to know to only copy > T> the values from face x the first time it is defined/used > T> i.e. from the first session that the face is used and > T> to then keep those values for future sessions. > > Not sure I follow you. It would _never_ copy the current values. It would > copy > only the attributes spec from the reference face, that is, the part of the > definition that is called for being copied. > > But yes, that spec would need to be available, in the source reference file > (no > problem) and in the byte-compiled reference file. A copy chain could > presumably > handled: if C copies from B which copies from A, then B's defface would be > eval'd before C's defface. > > There might be some problems to work out, but I don't imagine they would be > insurmountable. (But I know nothing about face implementation or > byte-compilation.) > > T> Without this, you would simply have a form of delayed > T> inheritance, which is likely going to be even more > T> confusing that using normal inheritance as the change > T> would be session dependent and time delayed. > > I don't follow. Again, it is only the default-attributes spec that would > be > copied, not the current attribute values. Access to that spec is all that > is > needed, I think. And it should be possible to provide that access through > the > byte-compiled reference file (as well as through the source reference file) > - > that is, the file whose `defface' is copied from. > > But again, I might well be missing a thing or two (or three...). > > T> This seems like a non-trivial modification to the > T> defface mechanism as it introduces a new state/time > T> dimension i.e. copy face x attributes unless face y > T> attributes have already been copied in a previous session. > > The current attribute values would never be copied. Only the > default-attributes > spec would be copied - that is, the part of the reference face's definition > (its > `defface') that we specified to be copied. > > T> Maybe defface could have some type of 'initform' > T> exstension that is used to configure the face if it > T> has no custom setting. The result would need to be > T> written to the custom-faces section so that it is > T> only run once. > > I don't follow. But maybe you just misunderstood and thought I meant that > the > current attribute values would be copied? > > Like you say, it probably needs to be looked at by someone with more knowledge. My thoughts were that since defface is a macro, we can only get at its specification at load time. However, can we get to that specification before emacs has loaded the custom faces section or user init files that would/could modify that specification? If we can't, then I guess it would be necessary to somehow parse the original source or byte-codes, which begins to make the whole thing a lot more complex - I'm not even sure how you would identify the appropriate file that contains the defface spec. Complex doesn't mean it cannot be done, but it does mean it will be far less likely that anyone would want to implement it. If nobody is willing to implement it, then it all becomes academic and nothing happens. Thats why I think it is important to also consider implementation implications, even if we don't plan to actually do the implementation ourselves. At worst, it does no harm, at best, it might provide the seed for implementation or a better idea. I also suspect 'ideas' which don't attempt to examine implementation implications are unlikely to be taken vary seriously or gain any traction. I think its necessary to have a clear grasp of emacs' initialization process/order to really know what options there are to implement a 'copy' facility. I'm beginning to think that a better alternative would be to add a simple command for developers that would just, given a face name, put its current definition into the kill ring/register/buffer in a format appropriate for using in a defface definition. Essentially, this would be a convenience wrapper around find-face-definition that extracts the definition from the source file. This seems less complicated and may still provide an easy way for developers to copy an existing full face definition without having to manually locate the sources, cut and then paste. Could mean less reason to not provide a fully defined face definition. The disadvantage is that once set, it would not reflect any changes in the default definition of the face it is copied from, which would be the main advantage of your suggestion. However, I suspect the defface definitoin of most faces rarely changes, especially for some of the older base faces that have been around for a while and have probably already been tweaked to be as good as they can be. Tim [-- Attachment #2: Type: text/html, Size: 7968 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-08 3:51 ` Tim Cross @ 2011-02-08 15:26 ` Drew Adams 2011-02-08 19:10 ` Philipp Haselwarter 0 siblings, 1 reply; 43+ messages in thread From: Drew Adams @ 2011-02-08 15:26 UTC (permalink / raw) To: 'Tim Cross'; +Cc: 'Philipp Haselwarter', emacs-devel T> Like you say, it probably needs to be looked at by T> someone with more knowledge. Yes. My recollection of the thread a few years back around Richard's changes to setting face attributes informs me that those who are familiar with face implementation (e.g. Yidong) are much better placed to think about how these things might be done. I remember it seeming to be fairly complex. It is also they who would decide _whether_ such things should be done. T> My thoughts were that since defface is a macro, we T> can only get at its specification at load time. I don't think so, but I could be wrong. AFAIK, you can do this at any time to get the default spec: (get SOME-FACE 'face-defface-spec). (I thought there was also a way for a user to restore that default in Customize, but it seems I was mistaken about that. You can `Show Lisp Expression', but that just shows the current value, not the default expression from the `defface'.) T> However, can we get to that specification before emacs T> has loaded the custom faces section or user init files T> that would/could modify that specification? I don't think we need to - see above. But again, I'm not going to try to get involved with implementing this. If those who are face-implementation knowledgable are interested they will get involved. If not, so be it. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-08 15:26 ` Drew Adams @ 2011-02-08 19:10 ` Philipp Haselwarter 0 siblings, 0 replies; 43+ messages in thread From: Philipp Haselwarter @ 2011-02-08 19:10 UTC (permalink / raw) To: emacs-devel please stop cc'ing me.. -- Philipp Haselwarter ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-07 0:59 ` Drew Adams 2011-02-07 1:30 ` Tim Cross @ 2011-02-08 13:58 ` Davis Herring 2011-02-08 14:33 ` Drew Adams 1 sibling, 1 reply; 43+ messages in thread From: Davis Herring @ 2011-02-08 13:58 UTC (permalink / raw) To: Drew Adams Cc: 'Tim Cross', emacs-devel, 'Philipp Haselwarter' > Sure - just use a copy instead of a pointer. Having D copy from B is equivalent to having them both inherit from a new face A with B's previous definition. With the inheritance, the user does have the option to change both of them at once if desired. And we already have inheritance. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-08 13:58 ` Davis Herring @ 2011-02-08 14:33 ` Drew Adams 2011-02-08 15:34 ` Davis Herring 0 siblings, 1 reply; 43+ messages in thread From: Drew Adams @ 2011-02-08 14:33 UTC (permalink / raw) To: herring; +Cc: 'Tim Cross', emacs-devel, 'Philipp Haselwarter' > > Sure - just use a copy instead of a pointer. > > Having D copy from B is equivalent to having them both > inherit from a new face A with B's previous definition. It is certainly not equivalent. Just customize A to see the difference. > With the inheritance, the user does have the option > to change both of them at once if desired. Precisely why they are not equivalent. Read the thread, if you have not already, for why inheritance is not the be-all and end-all. > And we already have inheritance. Hammer...nail. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-08 14:33 ` Drew Adams @ 2011-02-08 15:34 ` Davis Herring 2011-02-08 16:16 ` Drew Adams 0 siblings, 1 reply; 43+ messages in thread From: Davis Herring @ 2011-02-08 15:34 UTC (permalink / raw) To: Drew Adams Cc: 'Tim Cross', emacs-devel, 'Philipp Haselwarter' >> Having D copy from B is equivalent to having them both >> inherit from a new face A with B's previous definition. > > It is certainly not equivalent. > Just customize A to see the difference. But A didn't exist before, so that's a new feature, not a difference per se. If we wanted, we could prevent the user from even knowing about A (have `customize-face' not support it), and they would be equivalent. So surely this is better...? >> With the inheritance, the user does have the option >> to change both of them at once if desired. > > Precisely why they are not equivalent. Read the thread, if you have not > already, for why inheritance is not the be-all and end-all. I'm quite surprised that you didn't leap at this idea. Since when is offering the user a choice a bad thing? If they don't want to customize A, they won't, and they'll then have exactly the same set of options that the copying idea would give them. Now, I must say that I've realized an imperfection in my idea: if Emacs defines D but not B (and thus no one bothers to make A), an external package that defines B must either inherit from D or copy-paste its definition. But faces in Emacs that seem worthy of inheritance by anyone may be mechanically transformed into D-A pairs to avoid the problem. >> And we already have inheritance. > > Hammer...nail. David J. Wheeler might disagree. (And you were talking about how it might be non-trivial to implement the copying idea.) Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-08 15:34 ` Davis Herring @ 2011-02-08 16:16 ` Drew Adams 2011-02-08 17:40 ` Lennart Borgman 2011-02-08 19:10 ` Davis Herring 0 siblings, 2 replies; 43+ messages in thread From: Drew Adams @ 2011-02-08 16:16 UTC (permalink / raw) To: herring; +Cc: 'Tim Cross', emacs-devel, 'Philipp Haselwarter' > >> Having D copy from B is equivalent to having them both > >> inherit from a new face A with B's previous definition. > > > > It is certainly not equivalent. > > Just customize A to see the difference. > > But A didn't exist before, so that's a new feature, not a > difference per se. If we wanted, we could prevent the user > from even knowing about A (have `customize-face' not support > it), and they would be equivalent. That comes back to my earlier suggestion of "inheriting" from constant (uncustomizable) "faces". > So surely this is better...? I don't think so. But it is a possibility. I think it is better to make clear the difference: inheriting from a customizable face and either "inheriting" from an uncustomizable "face" or copying the default spec from an ordinary (customizable) face. With `:copy-default' vs `:inherit' it is clear what is going on. With just `:inherit' it is less obvious what's happening. I prefer my later suggestion to my earlier one (which you are repeating). > >> With the inheritance, the user does have the option > >> to change both of them at once if desired. > > > > Precisely why they are not equivalent. Read the thread, if > > you have not already, for why inheritance is not the be-all > > and end-all. > > If they don't want to customize A, they won't, and they'll > then have exactly the same set of options that the copying > idea would give them. And if they do customize A then they end up with changes down the line to other (inheriting) faces. They cannot customize A without causing those side effects. That's the point. Users must take all of that into consideration when deciding whether they want to customize A. Which means that they also need to be aware (become aware) of the inheritance relations - the fact that fiddling with A will in fact affect faces B, D,...Z. A user might well want to customize A, but without having repercussions elsewhere. S?he cannot do that, and that fact will affect whether s?he ultimately "wants" to customize A. After becoming fully aware of the inheritance relations, that is. ;-) Inheritance couples faces together. That's both its strength and its weakness (of course). If a user can customize face A, then any face that inherits from it (directly or indirectly) is affected. It's as simple as that. A pointer is not a copy. Both pointers and copies are useful. If the aim is to get a full face definition without the trouble of coding it explicitly, then you can either point to (inherit) an existing definition or copy one. Note BTW (e.g. Tim) that inheritance does _not_ in fact point to an existing face definition. It points to a _current value_. And just because face A might have a nice, full default-attributes definition, covering light and dark backgrounds, tty's, etc., that does not mean that the _current_ value of A is a full definition. Nothing prevents a user from customizing A to change it's nice, full definition to simply a `Red' foreground in all cases. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-08 16:16 ` Drew Adams @ 2011-02-08 17:40 ` Lennart Borgman 2011-02-08 19:10 ` Davis Herring 1 sibling, 0 replies; 43+ messages in thread From: Lennart Borgman @ 2011-02-08 17:40 UTC (permalink / raw) To: Drew Adams; +Cc: Philipp Haselwarter, Tim Cross, emacs-devel On Tue, Feb 8, 2011 at 5:16 PM, Drew Adams <drew.adams@oracle.com> wrote: > > That comes back to my earlier suggestion of "inheriting" from constant > (uncustomizable) "faces". That is totally out of the question for me. Take for example a vision impaired person who want to customize a face to make it more readable. Then inheritance is very important. Without it s/he would have an enormous job to customize all relevant faces. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-08 16:16 ` Drew Adams 2011-02-08 17:40 ` Lennart Borgman @ 2011-02-08 19:10 ` Davis Herring 1 sibling, 0 replies; 43+ messages in thread From: Davis Herring @ 2011-02-08 19:10 UTC (permalink / raw) To: Drew Adams Cc: 'Tim Cross', emacs-devel, 'Philipp Haselwarter' > That comes back to my earlier suggestion of "inheriting" from constant > (uncustomizable) "faces". I don't see the point in having anything be uncustomizable, though -- just give it a name `function-name-base' and perhaps a docstring that says "customize only if you want a global effect; otherwise customize the inheritors". More on this idea below. > A user might well want to customize A, but without having repercussions > elsewhere. S?he cannot do that, and that fact will affect whether s?he > ultimately "wants" to customize A. After becoming fully aware of the > inheritance relations, that is. ;-) No, they can't want that (barring simple confusion). The important bit is that no code uses A directly for anything, ever. The code uses D (and B) and thus uses A's attributes, but it never uses A. If the user wants just D to be different, they customize it (to override some/all of what it inherits from A, or to inherit from something else entirely). If they choose to customize A it is _because_ they want everything changed along with it; they are preferring "consistency" to "specificity". As for becoming aware, that's why the convention of "this face exists solely for inheritance" must be specified. But that's not hard for the user to notice, so I don't consider it a problem. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-05 22:11 ` Drew Adams 2011-02-07 0:59 ` Drew Adams @ 2011-02-07 1:08 ` Tim Cross 1 sibling, 0 replies; 43+ messages in thread From: Tim Cross @ 2011-02-07 1:08 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel, Philipp Haselwarter [-- Attachment #1: Type: text/plain, Size: 32998 bytes --] On Sun, Feb 6, 2011 at 9:11 AM, Drew Adams <drew.adams@oracle.com> wrote: > T> One thing I would recommend doing, if possible, would be to > T> spend some time running emacs with a dark background and on a > T> tty. This would likely reveal how bad some default face > T> definitions are and let you see how tedious it is having to > T> customize lots of individual face definitions just to get ones > T> that work. > > I'm not sure what your disagreements are with what I said. I > agree that poorly defined default face definitions are a real > problem. I even suggested that they are likely _the_ real > problem here. > > I think our point of disagreement is small - it is really a matter of degrees. Your position is one I would characterise as representing a pure or strict view of inheritance and one I see as having a strong ideological and theoretical base. Mine is possibly chracterised as being more pragmatic and less pure or strict, possibly characterised as being more liberal. There are also a number of assumptions and conclusions you ahve made regarding some of my points, which are incorrect. I will try to make my position with these clearer. Given reasonable face defaults that work out of the box on > both dark and light backgrounds, I think many if not most > (perhaps all?) of the problems you cited go away. With faces > that just work by default, regardless of the background, there > is no need to "customize lots of individual face definitions > just to get ones that work". > > Agreed. If all faces were well defined there would be no problem. However, the reality is that frequently they are not. My suggestions are based on the belief that this is because defining good default face settings is not easy, takes more effort than some developers want to expend, is difficult to do right as developers don't necessarily have access to all the environments involved and it may be unreasonable to expect all developers have the necessary knowledge and experience to know/identify a good default face setting. Therefore, my focus is on what we can do to make it easier for developers to do the right thing. One solution which I think would work towards this would be to develop a set of guidelines on how to identify and select appropriate faces to inherit from and pitfalls to avoid combined with requiring that faces are either fully defined or inherit from a core/base face which is fully defined. I'm not arguing that faces with similar appearance should be linked via inheritance and I'm not arguing that existing fully defined faces should be converted to use inheritance. The main point of disagreement concerns determining appropriate faces to inherit from. Your position is that inheritance should only be used to inherit from a face with the same/similar semantics/meaning as the child face. My argument is less restrictive. If a core face exists that has the same semantic meaning as the child face, then of course that is the obvious choice. However, if there are no core faces with the same semantic meaning I would rather have the face inherit from a fully defined face with a different semantic meaning, provided that does not cause confusion within the mode used by the child face, rather than have a face that is not fully defined. I would go further and suggest that while you accept the use of inheritance provided the inheritance chain follows the same semantic meaning, you would prefer in general not to use inheritance even if a good candidate with the same semantic meaning does exist in the core set of fully defined faces. While I would never argue that developers should be forced to use inheritance, I would suggest this is the wrong approach. I believe inheritance should definitely be used when there is clear semantic equivalents within the core set because this will help ensure consistency in representation of semantically related items. For example, I currently have numerous definitions for 'hyperlink' type objects as well as clickable buttons. I would like objects of these types to have the same appearance in all modes. However, I like hyperlinks to be a specific colour, with underlining, bold and italic fonts. To achieve this (possibly unusual) appearance in a consistent manner, I have to customize multiple faces. However, if inheritance was used, I would only have to do this once. If I understand your position regarding inheritance, you disagree with the concept of a child face inheriting from a semantically unrelated face because you feel doing so will lead to confusion and unexpected results because it 'muddies' the semantics of the inheritance and will cause unexpected/unwanted side effects when a core face definition is changed. I don't see it as being that straight-forward. I agree that badly chosen inheritance would cause problems - for example, having something that was not a clickable link inherit from the link face. On the other hand, core packages, such as dired, have been using inheritance from sematically unrelated faces for some time and I'm not aware it has caused problems. The dired-directory face inherits from font-lock-function-name-face. There is no 'semantic' link between these two faces, yet having this inheritance apparently works. Yes, if I change the value of font-lock-function-name-face, it will change the appearance of directory names in dired. However, in practice, this is rarely a problem. In fact, if your changing the face to make it fit better with some theme or to work better in your environment, it is likely that this change would fit with your overall objectives anyway. One of the reasons I think this works is because the choice is unrelated and does not confuse contexts within the mode the face is used in. If dired had a face to represent function names, then using font-lock-function-name-face for directory names would be a bad idea. However, dired does not have such a context and therefore does not cause confusion within that mode. Furthermore, I don't believe it would cause confusion with modes that use font-lock-function-name-face for function names. The two modes are distinct enough that it is clear that a face with X attributes in dired is different to a face with the same attributes in completely unrelated modes, such as emacs-lisp-mode. There are some other benefits to using inheritance in this manner. I think it is reasonable to suggest that all users have some underlying 'theme' they want to achieve with face settings. Some themes may seem unusual or even unpleasant, but there is usually some overriding pattern - faces are not selected randomly (I guess there may be some extreme cases where people might do this, but it isn't the 'norm'). Within any theme there is a finite set of usable faces i.e. faces that can be read, fit with the theme and are aesthetically acceptable. As we increase the number of individual face definitions, we also increase the number of faces with different names/meanings which have the same set of attributes as other unrelated faces. If we assume two basic approaches, your pure inheritance model and my less rigid inheritance approach, we end up with two vary different situations when it comes to the user customizing faces to obtain their desired theme. Under your approach, they will need to customize a larger number of faces to obtain their desired outcome. However, under my approach, which is more likely to make greater use of inheritance because it is not restricted to only using semantically related faces, it is more probable that less faces will need to be defined. Of course, we could probably achieve a better 'middle ground' with a larger, more comprehensive set of core/base faces as this would increase the likelihood that a child face can find a sematically related core/base face definition. I have nothing against this and included it as part of my suggestion on how to improve matters and reduce the number of poorly defined faces. > T> As I see it, we want to achieve four main goals. We want to > T> make it easier for developers to set appropriate defaults, we > T> want to get the best default possible for end users, > T> regardless of platform or light/dark background preferences, > T> we want to make it as easy as possible for end users to > T> customize their environment > > Agree. > > T> and we want to, if possible, avoid a proliferation of > T> different face definitions, especially when the definitions > T> don't really differ in anything other than name as this makes > T> customizing and theme definition more complex than it needs to > T> be. > > Disagree, if by "don't really differ in anything other than > the name" you are referring only to the `defface' default > attribute values. > > I am in favor of there being two faces instead of one, if > their use/meaning is different, even if their definitions > modulo the names are identical. In particular, this > facilitates separate customization. > > I was actually thinking of faces that have the same meaning, different names and different default definitions. This is a growing problem. We end up with inconsistency between modes for faces representing the same type of object. It was not meant to mean faces that happen to have the same attribute sets. For example, I have a number of modes that have the same concept of a clickable 'button'. In some modes they look different to how buttons look in other modes. I want them to all look the same and have to customize them individually. This is what I meant by the proliferation of faces. > It avoids coupling that is not logical and not necessary. > Inheritance (hence coupling) based on physical attributes > (appearance) can perhaps occasionally be appropriate, but in > general it is a no-no. > > Yes, where possible, inheritance should be used to link semantically related faces . However, linking semantically unrelated faces is not as bad in practice as you suggest and could be used to improve the end user expereince without causing the confusion you suggest. Yes, there are dangers, but there are also benefits which I think outweigh the downside of a strict inheritance approach, especially if there are only a few core/base fonts to inherit from. (Names are generally indicative of meaning, but yes, there > could be two faces with different names yet identical meaning. > In that case, yes, the duplication could be eliminated.) > > (There is an orthogonal reason to avoid using too many faces > at the same time: performance. But that is a different story > altogether.) > > T> It was good you pointed out that faces are not just about > T> colour. Sometimes, I think peopoe forget this and only focus > T> on the colour aspect. However, this is understandable as > T> colour is what distinguishes most faces from each other. > T> > T> We need to acknowledge how difficult it is to define good > T> default faces. Many definitions fail to do this. While your > T> suggestion of using colour compliments can help, I'm not > T> convinced it is always that easy. One problem is that > T> different environments have different sets of colours to work > T> with. For example, if you work under the linux console, you > T> don't have compliments for most of the colours available under > T> other environments, such as X or (I presume) Windows/Mac. The > T> problem is further complicated because most developers won't > T> have access to many of these environments, so can't easil test > T> and design appropriate faces even if motivated to do so. > > Agree. I did not mean to raise complementing as any kind of > cure-all - far from it. I was just mentioning that I provided > a quick-and-dirty set of default settings for dark backgrounds > for a particular library by flipping the light-background > defaults to their complements. Obviously, any set of defaults > for either light or dark deserves to be well thought out. And > all of the considerations you mention should be taken into > account. > > The tty thing is a big limitation, in particular. Designing a > set of faces for use on tty only is a different task from > designing a set for use with many colors and other attributes. > > For a library that is intended to work with both tty and > graphic windows, either tradeoffs are called for or > essentially two modes or face schemes are needed: full and > degraded (tty). We have constructs like `(type tty pc)' that > can help with that. > > The tty face values are a little tricky because you have a much smaller set of attributes to work with and the attributes you do have have less options. However, the defface macro has the ability to handle this and while it may be a pain to do, it is doable and should be part of any fully defined face definition. I would suggest there are very few packages which are only designed to run within a GUI environment (e.g. doc-view I guess, can't think of many others). > T> I would not argue that inheritance is an ideal solution to > T> this problem, However, I do think it can be part of the > T> solution. Perhaps something along the lines of > T> > T> * Establish guidelines on how to use inheritance i.e. how to > T> select which face to inherit from > T> * Define a good (not too large) set of base faces. Existing > T> font-lock faces may be sufficient, maybe not. Would need > T> review. > T> * Require all face definitions in core emacs packages to > T> either fully define a face (i.e. definition for dark/light, > T> tty, X mac ms etc) OR inherit from a base face (assuming > T> all base faces are fully defined) > T> * Add a section to the manual encouraging developers to > T> either provide a fully defined face or inherit from a base > T> face, but don't just define a single (usually) light > T> background face > T> > T> The key here is that all faces in core emacs packages would > T> end up with a fully defined face, either explicitly or via > T> inherit. > > Fully-defined, yes - good. The part that I think can be > misguided is basing everything on inheritance from faces that > are not necessarily related in terms of use or meaning. > > Nobody has suggested basing everything on inheritance and it has not been suggested that inheritance should be forced on anyone (though, as outlined above, there could be a strong argument for forcing inheritance for clearly semantically related faces). The suggestion is that if you don't want to fully define a face, then use inheritance RATHER than a partially defined face. > Basing a face on a related face is not bad. Stretching things > to base all faces on some "basic" faces, no matter how > unrelated in terms of meaning or context, is not a great idea. > > Nobody has suggested basing *all* faces on some base set. > Faces, including "basic" faces, are customizable. You don't > want a user who customizes `font-lock-doc-face' to suddenly > find that s?he has also affected a chain of unrelated faces > that inherit from it. Customizing font-lock faces should not > affect Dired or Info or... > > Except they already do! I don't see this as a 'real' problem, but more a theoretical one. Yes, changing face attributes in font-lock-* faces will change the look of dired faces, but does that really matter in practice? Maybe the dired faces should be fully defined and I would not have an issue with that. However, I'm glad they are using inheritance rather than only having partial definitions. . > T> One of the reasons I like the use of inherit for face > T> definitions is mainly from an end user perspective. I would > T> rather have faces that are fully defined via inherit, even if > T> that inheritance seems odd, than have a partially defined face > T> which only works if you have a light background or are running > T> under a full gui environment. > > Those are not the only two alternatives - it's not either-or. > > I am in favor of full face definitions. And I am not against > inheritance. The important thing is for a face to inherit > only from a related face (in terms of use/meaning). > I would argue it is preferable rather than being required. > > The key is whether it will generally make sense for the > inheriting face if the inherited face gets customized. If > not, then inheritance is likely not the best way to go. > > I actually agree, except we would differ on what makes sense. > T> If, when I change the base face definition, it results in > T> unacceptable changes to some face which inherits from it, I > T> can customize it. > > Sure you can, but now you're back to customizing all over the > place - and now across multiple libraries and multiple use > contexts, to boot. The cure is at least as bad as the > disease. > > No, its not as bad. If more faces inherited from fully defined core faces, then the faces I need to customize are only those which I find aesthetically unacceptable and does not include faces that are not fully defined and therefore are not even readable in my environment. Moreover, many of the faces I find aesthetically unacceptable are likely to have the same/similar attributes. I can change the base definition and have my changes propogate through all faces that currently have the unacceptable default. Without the use of inheritance, I have multiple faces to change. When they are not fully defined, many of those changes are needed just to make the face readable i.e. not just an aesthetic change, but a necessary one. Nothing wrong with inheritance. But boiling everything down > to font-lock faces (or similar) is a bad idea. Better for > face inheritance to reflect face usage/meaning: families > (inheritance hierarchies) of related faces, not just > everything inheriting from primordial faces `adam' and `eve'. > > Why do you keep taking the extreme? Nobody has suggested that all faces inherit form some low base. This is not what I've suggested - either fully define or inherit, just don't have partial poorly defined faces that only work in a limited environment, such as a light background. > T> My experience has been that this does sometimes happen, but > T> not that often and it is more preferable to fix up the few > T> faces than to spend much more time configuring lots of > T> individual faces. > > I think you are again thinking of the fact that you are > needing to configure lots of faces because they were defined > incompletely or with poor defaults. Take away that > presupposition and where is the argument? > To take away that presupposition, you need to come up with something that enables developers to do the right thing and not only use partial face definitions as the default. This is the whole point. Yes, theoretically, if all faces were fully defined, most of the problem would go away (though there are then other issues concerning consistency). The reality is that too often, faces are not fully defined. Inheritance would provide a simple way to have a fully defined face when the developer cannot or does not want to fully define the face themselves. > T> In fact, as the number of individual face definitions has > T> increased, I actaully think we have gone the wrong direction. > T> We have too many faces which are mostly the same. > > They are not the same just because they have the same > _appearance_ (by _default_ no less). This is a key element in > the confusion, I think. It sounds like it motivated Yidong's > search for faces to eliminate "duplication" via inheritance. > > I acknowledge that. However, we have instances of faces that do represent the same semantic object, but which have different definitions in different modes i.e. clickable buttons etc. I have three different faces for representing dates (admittedly, these are add-on packages and not core ones), I have different faces for representing links etc. None of these use inheritance and in some cases, have different default values. In these instances, inheritance should be used. I then have the ability to set all like things to the same appearance and if I want, the option to change or augement them per mode. > Faces are not the same as their (attribute) values. Faces > have identity and purpose as well as values. > > Agreed. We may differ on how far that identity reaches. I see dired-directory as having its own identity and its relevance is restricted to within dired mode. It inherits from a font-lock face, but I don't see that as part of its identity as such. You appear to see the face it inherits from as part of its identity as well. I'm not sure this is always so or necessary. This is essentially no different from having multiple user > options (or other variables) that have the same value: 42, > nil, t,... You would not argue that we define a set of > "basic" user options and use inheritance to factor out any > "duplicate" options that have the same default value of 42 or > nil, would you? > > You would not argue that we should have only one primeval user > option with a default value of 42, and inherit from it for > wildly different options with different use cases (meanings), > so that someone who customizes the "basic" option to change > the value 42 to 24 ends up changing lots and lots of > inheriting options. Would you? How are faces different in > this regard? > > Now this is just plain silly and a very poor analogy . Faces have a lot more in common and a much closer relationship than al the user variables. Faces work together to present a theme, they are not independent as you imply. Faces that don't set an attribute inherit the value from the default face. You configure faces based on an overall theme and how they interact with each other and faces all have the same format/attributes. To suggest they are as indpendent from each other as other user variables is nonsense. Ignoring how poor the analogy is, the fact is that NOBODY has suggested that all faces need to inherit form a base set. This was never proposed. T> It seems now that every new package is adding its own face > T> definitions > > Good. That should probably happen more than it does. ;-) > > If reasonable, related faces exist on which to base the new > face definitions, then by all means inheritance might well be > called for. But a new package should _not_ avoid adding its > own face definitions, whether they are defined using > inheritance or not (i.e., pointer or copy). > > Disagree. A package should only define its own face when either there is no existing face which adequately represents the meaining of the face OR there is a strong expectation that the user may want to customize the face independently. There is a definite danger of having too many faces and ending up with a consistency problem. Consider the situation where every programming mode defined its own face to represent comments and did not use inheritance. What benefit does that give us? Very little. What harm - potentially a lot as now you have to configure multiple faces to just get code comments to have a consistent appearance. A mode should NOT create a new face just for the sake of it and if it does create a new face, either fully define the face or inherit from a fully defined face - its that simple. If you want to restrict inheritance to only use faces with the same semantic meaning, fine. I think it is over restrictive, but care less about that than about having a solution that would ensure faces are fully defined and providing a way to achieve this that will facilitate developers doing the right thing. On the contrary. What should be avoided is reusing some face > that makes no sense in the current context. What is the > _practical_ criterion? Whether or not customizing the face > wrt its original context/purpose will have a negative effect > in the new context. If not, then go for it (reuse/inherit). > Agreed - pretty much my position. > > T> and many of them are poorly defined. It now takes much > T> longer for me to establish a consistent set of faces. > > Bad - agreed. But not a necessary consequence of having many > faces. More likely a consequence of poor default definitions > (as you mentioned). > > Yes, but encouraging the addition of new faces without good justification is bad - it is the other extreme. Too often, I use applications that don't have enough faces and I cannot change the appearance of some object that I would like to somehow stand-out. However, the other extreme is a proliferation of unnecessary faces that just make customization and theming more difficult. T> If we required face definitions to either be fully defined or > T> inherited from a base set that are fully defined, we would > T> likely give a much better default experience to end users. > > Full face definitions are good, yes. > That is independent of the question of inheritance. > > Well... indiscrimately imposing inheritance (from fully defined > faces) can ensure full definitions. But it has a cost: it can > also introduce unnecessary and unwanted dependencies with > negative consequences. > > Well, either direction has a cost. There is no avoiding that. My view is to find the point at which we get the best cost/benefit. Inheritance provides a way to reduce the burden on developers to fullly define faces and has the potential to reduce the number of faces that are only partially defined and work only in limited configurations/environments. Whether we have strict or less rigid restrictions on inheritance will affect how easily inheritance can be used in this manner. Strict inheritance will give a consistent semantic meaning in inheritance chains and potentially more predictable resutls when modifying base faces. Less rigid inheritance would allow inheritance to be used instead of fully face definitions in more situations. If badly applied it does have the potential to cause confusion, but this could be mitigated with good guidelines. New faces should only be introduced when there is a demonstrated case and not just as an automatic default action. T> Using inheritance also means that when we find a face > T> definition which is poor for a particular environment, we can > T> refine that base definition rather than having to find all > T> similarly poor definitions and updating them individually. > > Yes and no. "Fixing" it for one environment might do exactly > the wrong thing for another context, e.g. for one of its > descendents. Inheritance needs to be used carefully, based on > intended use/meaning of the faces involved. > > Maybe, though I don't think it is as bad in practice as you assume. Existing modes have been using inheritance in a non-semantic fashion since at least emacs 21 and this doesn't seem to have cause any major issues. T> Using inheritance means that it is easier to make broad > T> changes to face definitions, reducing the time spent in > T> customize and lets you then tweak those specific faces which > T> don't quite work. > T> > T> So, using your example, if someone changed the base face that > T> dired+ uses, either they will find the result in dired+ > T> acceptable or they can then tweak that face further. The > T> alternative is that it would be necessary to customize both > T> faces, even when you are going to set them to the same value. > > Maybe, maybe not. Depends what kind of change you want/need. > > It's true that if you want to change all occurrences of red > foreground to blue then more customization would be involved > without inheritance. Maybe we could find a way to make such > changes easier - I don't have a problem with that. > > Maybe this could be an alternative. Frequently, you do need to change colours 'across the board' - often because the faces are not fully defined and you have a different background to the assumed default and need to make the change to make the face more readable. So, perhaps this would fix the symptom. However, it does not address the basic problem, which is faces that are not fully defined. But we should not be using _inheritance_ for that (in > general). A Dired face should either not inherit or it should > inherit from a related face, not just some face whose _default > appearance_ looks good for Dired. It makes no sense to base a > Dired face on a font-lock face, for instance. > > So you would argue that the existing dired face definitions are wrong. However, they ahve been like that for quite some time and it appears to work. > Just because you might want some Dired face to have a red > foreground by default is no reason to go looking for a face > with a red foreground to inherit from. Look instead for a > face with a related use/meaning. If you find none, then do > not use inheritance here. That's the guideline I'd suggest. > > I emphasize the use/meaning of a given face: what it is for, > what it represents, what it does. I think you are emphasizing > its default appearance - attribute values (color etc.). To > me, a face or a variable `foo' is mainly about its use, not > its value. > > No, I'm not focused on its appearance. The difference is that while I agree you should select the face that has a similar semantic meaning if one exists, I have no issue with using one that does not provided it does not cause confusion within the mode it is used in. I would cite dired as an example where this has been done successfully. > If the opposite were true, then we would name faces and > variables after their default values, not after their uses. > Yes, I've seen some Lisp code with face names like > `underlined-bold-red-foreground-on-gray-background'. > (Mea culpa: I even wrote such code at one point.) > > And there's not necessarily anything wrong with that; for some > contexts it might make sense. But in that case it makes more > sense for the "face" to be a constant, not customizable. It > would be perverse to customize a face named `red-foreground' > to have a green foreground. > (And in general it is more likely for single attributes to be > reuse candidates than it is for combinations of attributes.) > > T> The reality is that there are a limited set of good faces and > T> you will usually end up with the same face definition being > T> used in multiple roles. Frequently, those roles have nothing > T> to do with each other. This doesn't matter as the contexts > T> are completely different. From an end user perspective, it is > T> irrelevant that compiler messages inherit from > T> font-lock-string - all the end user sees is that compiler > T> messages use a default face that is green, which may be > T> exactly the same as strings in their code, but so what. > > I strongly disagree here. > > If the roles/meanings/use are unrelated, then inheritance is > usually inappropriate. It _does_ matter whether a > compiler-messages face inherits from `font-lock-string-face' - > _if_ someone customizes that parent face. > > But does it really matter. I change font-lock-comment-face to orange because that is easier to read or more aesthetic given my default background colour. As a result, compiler-message face also changes to orange. Isn't it just as likely that if pink was not acceptable for comments in code that pink is also unacceptable for messages in compile-mode? Sure, maybe I might decide I'd still like pink for those messages and I can override the inheritance, but in practice, I think in most cases, this would be fine and has been my experience with the mdoes that do use inheritance in such a manner. Of course, if there is a base face with a more closely fitting semantic meaning, it should be used in preference and you would avoid using faces like link or button that have very precise meanings that could cause confusion within the mode - especially if that mode supports links or buttons. If we defined a compiler-messages face to inherit from > `font-lock-string-face' _only_ because we liked the default > foreground choice of `LightSalmon', that would be misguided, > IMO. > > Perhaps, if that was the only motivation. However, if you choose that font-lock face because you want to use inheritance rather than spend time fully defining compiler-message face and if the font-lock face is fully defined, then it may be a valid choice. > If there is no existing face that is related in terms of > use/meaning, then the compiler-messages face should not > inherit; it should just be defined with a default foreground > of `LightSalmon'. That kind of duplication is not a curse but > a blessing. > NO, That would be a partial font definition. If I happen to use a background of LightSalmon, that face is now unreadable. Either fully define the face or inherit. > > Then a user can customize either the compiler-messages face or > `font-lock-string-face' without affecting the other. And that > makes sense because (by hypothesis) the two are unrelated. > > Even if compiler-message face uses inheritance form an unrelated face, you still have the option of customizing it to something different or even removing the inheritance if so desired. Tim [-- Attachment #2: Type: text/html, Size: 39274 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-03 19:10 ` Drew Adams 2011-02-04 0:12 ` Tim Cross @ 2011-02-04 0:18 ` Stephen J. Turnbull 2011-02-04 3:55 ` John Yates ` (2 more replies) 2011-02-04 10:26 ` Julien Danjou 2 siblings, 3 replies; 43+ messages in thread From: Stephen J. Turnbull @ 2011-02-04 0:18 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel, 'Philipp Haselwarter' Drew Adams writes: > 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 - Sure, it's a help with customization, but it does not address the basic problem. > I'd be interested in hearing more arguments in favor of faces inheriting from > faces (e.g. "basic" faces). The basic problem is that faces are not colors. Faces are not fonts. (Where have I heard this before? ;-) A face is a semantic component, intended to express meaning. Common meanings should have a common expression. Thus, for text modes there should be an "emphasis" face, and of course a "bogus whitespace" face for us pedants. In programming modes, "identifier" and "keyword" are common semantics. In compile modes, "info", "file", "position" (usually line number), "function", "error", and "warning" are common semantics. In shell modes, several levels of "prompt". Electric modes may want a "paren flash" face. Search modes a "hit" face and a "secondary hit" face. For many simple modes, such basic faces will be enough, and used as is. However, modes of medium complexity may want to inherit in order to allow customization of that mode without affecting others, especially modes with lots of faces where customization of one face may collide with the basic definition of another, and the user prefers to change the second face in the mode where it collides but not elsewhere. This has happened to me occasionally, though by now most of my customizations are inches thick in moss. It might also be useful to have semantically derived faces, so that "strong emphasis" (introduced to support markup modes like HTML) would derive from "emphasis" (but this is speculative). On the same theme, "keyword" might derive from "identifier". ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-04 0:18 ` Stephen J. Turnbull @ 2011-02-04 3:55 ` John Yates 2011-02-04 4:56 ` Stephen J. Turnbull 2011-02-04 4:57 ` Jambunathan K 2011-02-05 22:09 ` Drew Adams 2 siblings, 1 reply; 43+ messages in thread From: John Yates @ 2011-02-04 3:55 UTC (permalink / raw) To: Stephen J. Turnbull; +Cc: Philipp Haselwarter, Drew Adams, emacs-devel On Thu, Feb 3, 2011 at 7:18 PM, Stephen J. Turnbull <stephen@xemacs.org> wrote: > The basic problem is that faces are not colors. Faces are not fonts. > (Where have I heard this before? ;-) A face is a semantic component, > intended to express meaning. Common meanings should have a common > expression. Your argument assumes that users internalize strong associations from the visuals of a face to very specific semantics. Further you assume that users expect faces to be reused consistently across modes based on conformance to clear semantic models. A corollary is that introduction of a new semantic notion not only requires introduction a new face but also requires that it be visually distinct. Put another way you expect users to be conscious of distinct faces and their detailed semantics. My personal experience contracts that picture. I really have only two criteria on which I asses a set of faces (either out of the box or as I tweak): 1) does the choice of visual (d)emphasis make sense? are fundamental structural elements easy to identify and follow? are points that require my attention appropriately easy to recognize? are less important elements easy to skim/skip? 2) is the overall effect pleasing or jarring? is there unity and consistency in the use of colors and weights? (often when first experimenting with a new mode I feel that once again I am waging my eternal battle against emacs "fruit salad") So my mental association is not with any specific semantics of a particular face but only with the extent to which, within a given theme, it conveys visual emphasis or lack thereof. An important consequence is that I feel no great need to convey every new semantic via a new, visually distinct face. /john ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-04 3:55 ` John Yates @ 2011-02-04 4:56 ` Stephen J. Turnbull 0 siblings, 0 replies; 43+ messages in thread From: Stephen J. Turnbull @ 2011-02-04 4:56 UTC (permalink / raw) To: John Yates; +Cc: emacs-devel, Drew Adams, Philipp Haselwarter John Yates writes: > On Thu, Feb 3, 2011 at 7:18 PM, Stephen J. Turnbull <stephen@xemacs.org> wrote: > > > The basic problem is that faces are not colors. Faces are not fonts. > > (Where have I heard this before? ;-) A face is a semantic component, > > intended to express meaning. Common meanings should have a common > > expression. > > Your argument assumes that users internalize strong associations from > the visuals of a face to very specific semantics. No, it doesn't. It simply assumes enough association will carry over. Use of bold and italic for emphasis in text modes is very common. Use of red for errors is very common. I'm not saying that *all* faces should be derived from some base set, but Drew (and now you) seem to be saying that derivation from a base set is useless. The law of the excluded middle does not apply to all vs. none, you know. > Further you assume that users expect faces to be reused > consistently across modes based on conformance to clear semantic > models. Nope, you're projecting. Of course (Emacs) users *don't* expect that, because Emacs currently *doesn't* do it. > A corollary is that introduction of a new semantic notion not only > requires introduction a new face but also requires that it be > visually distinct. I'm not sure that follows from your assumptions, but in any case I neither accept them nor believe them necessary, so that is not a consequence of advocating a base set of faces. > > Put another way you expect users to be conscious of distinct faces and > their detailed semantics. > My personal experience contracts that picture. Well, of course it does! Emacs is very useful to you, and currently fails to provide consistent faces, so you conclude that consistent faces are unnecessary. No big surprise there! > 2) is the overall effect pleasing or jarring? is there unity and > consistency in the use of colors and weights? (often when first > experimenting with a new mode I feel that once again I am waging my > eternal battle against emacs "fruit salad") Now there's a strong argument for derivation. *If* those faces that can be derived *were* derived, then you could fix up the base faces (even resetting some that you think are stupid to `default' so they don't show up at all or whatever), and use doremi to tone down the rest, perhaps. > theme, it conveys visual emphasis or lack thereof. An important > consequence is that I feel no great need to convey every new semantic > via a new, visually distinct face. Would it really annoy you if Emacs had pleasing faces, but dammit, they're way too consistent? ;-) ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-04 0:18 ` Stephen J. Turnbull 2011-02-04 3:55 ` John Yates @ 2011-02-04 4:57 ` Jambunathan K 2011-02-05 22:09 ` Drew Adams 2 siblings, 0 replies; 43+ messages in thread From: Jambunathan K @ 2011-02-04 4:57 UTC (permalink / raw) To: emacs-devel "Stephen J. Turnbull" <stephen@xemacs.org> writes: > The basic problem is that faces are not colors. Faces are not fonts. > (Where have I heard this before? ;-) A face is a semantic component, > intended to express meaning. Common meanings should have a common > expression. Thus, for text modes there should be an "emphasis" face, > and of course a "bogus whitespace" face for us pedants. In > programming modes, "identifier" and "keyword" are common semantics. > In compile modes, "info", "file", "position" (usually line number), > "function", "error", and "warning" are common semantics. In shell > modes, several levels of "prompt". Electric modes may want a "paren > flash" face. Search modes a "hit" face and a "secondary hit" face. Orgmode has it's own set of semantic elements (may I say, broadly relating to scheduling and task & information management) - todo states, timestamps, tags ... Jambunathan K. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-04 0:18 ` Stephen J. Turnbull 2011-02-04 3:55 ` John Yates 2011-02-04 4:57 ` Jambunathan K @ 2011-02-05 22:09 ` Drew Adams 2011-02-06 7:11 ` Stephen J. Turnbull 2 siblings, 1 reply; 43+ messages in thread From: Drew Adams @ 2011-02-05 22:09 UTC (permalink / raw) To: 'Stephen J. Turnbull'; +Cc: emacs-devel, 'Philipp Haselwarter' S> I'm not saying that *all* faces should be derived from some S> base set, but Drew (and now you) seem to be saying that S> derivation from a base set is useless. The law of the S> excluded middle does not apply to all vs. none, you know. You are not saying *all*. And I am not saying *none* (or all vs none). Please drop the bugaboo strawman, Stephen. As a matter of fact your argument repeats mine; it does not counter it. S> The basic problem is that faces are not colors. Faces are S> not fonts. (Where have I heard this before? ;-) A face is S> a semantic component, intended to express meaning. S> Common meanings should have a common expression. d> Inheritance should be based on similarity (preferably set d> inclusion) of use (usage, use case, purpose), not just on d> similarity of face attributes. You used the word "semantic". Good. I might well have included that word in the parens. We both draw the same distinction between a face as only a combination of appearance attributes (no) and a face as having a purpose/meaning for particular contexts (yes). It is essentialy the same distinction that is made between physical markup and logical markup - between `italic' and `emphasis', for instance. We have both said that inheritance should, in general, be used for logical/usage/semantic entities, and *not* simply for combinations of attributes (physical/appearance). In my words: d> A new face should not inherit from face `region' just because d> its default attributes are the same as the default attributes d> of face `region', for example. The idea that inheritance should be based on similarity of usage/purpose/semantics rather than just similarity of value (e.g. color, size) implies that it is a mistake to have faces that are unrelated to font-locking be based on font-lock faces. A face whose purpose has something to do with comments could be based on `font-lock-comment-face', but a face such as `region' or `minibuffer-prompt' should probably not be based on it - there is too little logical/semantical/usage connection. Why does this matter? Coupling. Unwanted side effects for a descendent when you customize its ancestor. d> IMO, it makes sense for a face B to inherit from another face d> A _only_ when what is wanted is that customization of A d> automatically is reflected in B. When doing this, we should d> _always_ expect and assume that A will be customized by users. d> This is true no matter how "basic" A is. d> d> This is why (IMO) it does _not_ make sense in general for d> [all] faces to inherit from font-lock faces. S> Thus, for text modes there should be an "emphasis" face, and S> of course a "bogus whitespace" face for us pedants. In S> programming modes, "identifier" and "keyword" are common S> semantics. In compile modes, "info", "file", "position" S> (usually line number), "function", "error", and "warning" are S> common semantics. In shell modes, several levels of "prompt". S> Electric modes may want a "paren flash" face. Search modes a S> "hit" face and a "secondary hit" face. Again you support what I said. The important thing here is that you have grouped faces into contexts, groups based on usage/meaning. (Whether or not those particular groups are the best choices is beside the point.) The point is that inheritance makes sense within such a group (e.g., levels of prompt), and it makes a lot less sense (if any) across unrelated groups (e.g. prompt, search hit, and emphasis). How did this discussion start? Yidong seemed to be saying (possible misinterpretation, admittedly) that it would be good to get rid of duplicate face definitions, by which he apparently meant faces that have different names but the same attribute values. That is the issue. I argued that that would be misguided. Such faces typically are *not* duplicates. A face expresses meaning (a usage and context); it is not identical to its appearance. You put it this way: S> A face is a semantic component, intended to express meaning. S> Common meanings should have a common expression. I went a bit further and said that, in general, _only_ common meanings or use patterns should have a common expression. I have nothing against the examples of inheritance that you argued for. They are they same kinds of inheritance that I argued for. What I think is misguided is trying to boil things down across meaning groups (usage contexts) based on only equality of default attribute values. That's the issue. Looking for duplication of face definitions, and thus possible candidates for inheritance (factoring), should not be based on looking at their default attribute values. It should be based on what the faces represent, what they do, what they mean, how they are intended to be used. When duplicates of that kind are found, then yes, we can consider factoring out the duplication by using inheritance. ^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: Eliminating a couple of independent face definitions 2011-02-05 22:09 ` Drew Adams @ 2011-02-06 7:11 ` Stephen J. Turnbull 0 siblings, 0 replies; 43+ messages in thread From: Stephen J. Turnbull @ 2011-02-06 7:11 UTC (permalink / raw) To: Drew Adams; +Cc: 'Philipp Haselwarter', emacs-devel I'm glad we agree about avoiding redundant defintion of semantically similar faces. Drew Adams writes: > How did this discussion start? Yidong seemed to be saying > (possible misinterpretation, admittedly) that it would be good > to get rid of duplicate face definitions, by which he > apparently meant faces that have different names but the same > attribute values. That seems unlikely to me; Emacs developers are generally good about focusing on underlying semantics rather than surface similarities. In this case, if that were his intention he'd most likely have suggested a naming convention that expresses face structure. You might have been well-advised to ask him if that is what he meant. > I have nothing against the examples of inheritance that you > argued for. They are they same kinds of inheritance that I > argued for. You did? I'm sorry, I missed it. The question I responded to didn't make that distinction at all; it simply asked what is the rationale for inheritance. And others (cf. John Yates) do not seem to agree that semantic redundancy is an issue of concern. In a long thread it's easy to become confused about who advocated what, and almost all the arguments (including conflicting ones) become associated with the most verbose posters. If I misrepresented your position, I'm sorry. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-03 19:10 ` Drew Adams 2011-02-04 0:12 ` Tim Cross 2011-02-04 0:18 ` Stephen J. Turnbull @ 2011-02-04 10:26 ` Julien Danjou 2011-02-04 17:57 ` color-complement for defface (was: Eliminating a couple of independent face definitions) Ted Zlatanov 2 siblings, 1 reply; 43+ messages in thread From: Julien Danjou @ 2011-02-04 10:26 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel, 'Philipp Haselwarter' [-- Attachment #1: Type: text/plain, Size: 532 bytes --] On Thu, Feb 03 2011, Drew Adams wrote: > 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. color.el included in Emacs 24 as `color-complement' so you can even use it in your defface directly, I think. -- Julien Danjou ❱ http://julien.danjou.info [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* color-complement for defface (was: Eliminating a couple of independent face definitions) 2011-02-04 10:26 ` Julien Danjou @ 2011-02-04 17:57 ` Ted Zlatanov 2011-02-14 18:11 ` color-complement for defface Ted Zlatanov 0 siblings, 1 reply; 43+ messages in thread From: Ted Zlatanov @ 2011-02-04 17:57 UTC (permalink / raw) To: emacs-devel On Fri, 04 Feb 2011 11:26:49 +0100 Julien Danjou <julien@danjou.info> wrote: JD> On Thu, Feb 03 2011, Drew Adams wrote: >> 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. JD> color.el included in Emacs 24 as `color-complement' so you can even use JD> it in your defface directly, I think. It would be nice if an example of that usage was part of the manual. Even better would be if defining a face could automatically use the complement (e.g. by setting the background to 'complement). Julien, do you want to propose a patch to the manual? Does anyone have comments on a defface modification to let color-complement pick the background automatically if requested? I don't know how hard that would be to write, but I want to know if it's even acceptable. Thanks Ted ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: color-complement for defface 2011-02-04 17:57 ` color-complement for defface (was: Eliminating a couple of independent face definitions) Ted Zlatanov @ 2011-02-14 18:11 ` Ted Zlatanov 2011-02-20 17:44 ` Julien Danjou 0 siblings, 1 reply; 43+ messages in thread From: Ted Zlatanov @ 2011-02-14 18:11 UTC (permalink / raw) To: emacs-devel On Fri, 04 Feb 2011 11:57:30 -0600 Ted Zlatanov <tzz@lifelogs.com> wrote: TZ> On Fri, 04 Feb 2011 11:26:49 +0100 Julien Danjou <julien@danjou.info> wrote: JD> On Thu, Feb 03 2011, Drew Adams wrote: >>> 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. JD> color.el included in Emacs 24 as `color-complement' so you can even use JD> it in your defface directly, I think. TZ> It would be nice if an example of that usage was part of the manual. TZ> Even better would be if defining a face could automatically use the TZ> complement (e.g. by setting the background to 'complement). TZ> Julien, do you want to propose a patch to the manual? I'll take an example, at least, and write the rest. TZ> Does anyone have comments on a defface modification to let TZ> color-complement pick the background automatically if requested? I TZ> don't know how hard that would be to write, but I want to know if it's TZ> even acceptable. Second try. I still think this is a worthy improvement to Emacs. Ted ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: color-complement for defface 2011-02-14 18:11 ` color-complement for defface Ted Zlatanov @ 2011-02-20 17:44 ` Julien Danjou 2011-03-10 19:09 ` Ted Zlatanov 0 siblings, 1 reply; 43+ messages in thread From: Julien Danjou @ 2011-02-20 17:44 UTC (permalink / raw) To: Ted Zlatanov; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 721 bytes --] On Mon, Feb 14 2011, Ted Zlatanov wrote: > TZ> Julien, do you want to propose a patch to the manual? > > I'll take an example, at least, and write the rest. Sorry Ted. I had your mail tagged important, but well… Here's a very simple example on how to use it: #+begin_src: emacs-lisp (defface myface (let ((color "red")) `((((class color) (background light)) (:foreground ,color)) (((class color) (background dark)) (:foreground ,(apply 'color-rgb->hex (color-complement color)))) (t nil))) "My face.") #+end_src Obviously, a new function/macro could be created to automate this use of color-complement. -- Julien Danjou ❱ http://julien.danjou.info [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: color-complement for defface 2011-02-20 17:44 ` Julien Danjou @ 2011-03-10 19:09 ` Ted Zlatanov 2011-03-10 19:11 ` Ted Zlatanov 0 siblings, 1 reply; 43+ messages in thread From: Ted Zlatanov @ 2011-03-10 19:09 UTC (permalink / raw) To: emacs-devel On Sun, 20 Feb 2011 18:44:04 +0100 Julien Danjou <julien@danjou.info> wrote: JD> Here's a very simple example on how to use it: JD> #+begin_src: emacs-lisp JD> (defface myface JD> (let ((color "red")) JD> `((((class color) (background light)) JD> (:foreground ,color)) JD> (((class color) (background dark)) JD> (:foreground ,(apply 'color-rgb->hex (color-complement color)))) JD> (t nil))) JD> "My face.") JD> #+end_src A patch that shows how to do this in lispref/display.texi is attached. I put it under the :foreground property documentation for `defface' but it's right next to the :background property too, so it should be obvious to a reader how to use it to do the opposite, setting the background to a complement. JD> Obviously, a new function/macro could be created to automate this use of JD> color-complement. The :foreground and background properties can only be a string currently, so it may be even simpler to allow them to be the form (complement "color-string"). That should be a clean extension. If not, I guess a function or a macro could do it too. Ted ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: color-complement for defface 2011-03-10 19:09 ` Ted Zlatanov @ 2011-03-10 19:11 ` Ted Zlatanov 0 siblings, 0 replies; 43+ messages in thread From: Ted Zlatanov @ 2011-03-10 19:11 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 48 bytes --] (patches? we don't need no steenkin' patches!) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: doc-defface-color-complement.patch --] [-- Type: text/x-diff, Size: 908 bytes --] === modified file 'doc/lispref/display.texi' --- doc/lispref/display.texi 2011-01-31 23:54:50 +0000 +++ doc/lispref/display.texi 2011-03-10 19:03:48 +0000 @@ -2057,6 +2057,21 @@ black-and-white displays, certain shades of gray are implemented by stipple patterns. +You may want to set the foreground automatically in some cases using +the @code{color-complement} and @code{color-rgb-to-hex} functions from +the @code{color.el} library. Here's an example: + +@example +(defface myface + (let ((color "red")) + `((((class color) (background light)) + (:foreground ,color)) + (((class color) (background dark)) + (:foreground ,(apply 'color-rgb-to-hex (color-complement color)))) + (t nil))) + "My face.") +@end example + @item :background Background color, a string. The value can be a system-defined color name, or a hexadecimal color specification. @xref{Color Names}. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 17:17 ` Chong Yidong 2011-02-02 20:33 ` Philipp Haselwarter @ 2011-02-02 21:24 ` Tim Cross 2011-02-03 16:14 ` Dan Nicolaescu 2 siblings, 0 replies; 43+ messages in thread From: Tim Cross @ 2011-02-02 21:24 UTC (permalink / raw) To: Chong Yidong; +Cc: Lennart Borgman, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3094 bytes --] On Thu, Feb 3, 2011 at 4:17 AM, Chong Yidong <cyd@stupidchicken.com> wrote: > Tim Cross <theophilusx@gmail.com> writes: > > > My only concern is how you define what to inherit from. For example, > > in your suggestion of compiler warnings inheriting form > > font-lock-comment-face I immediately wondered why you would not > > inherit from font-lock-warning face? > > font-lock-warning-face is already used for compilation errors, which are > more serious than warnings. > OK, that makes it clearer. Maybe a different face than font-lock-comment as comments are often coloured so as to be a little less noticeable, while warnings are probably something you want to notice (but not as much as errors!). WRT Drew's comments. Some good points. However, to make my position clear, I would not suggest that packages don't define their own faces, only that they use inherit to define the default value the face has. Individual users then have the option to change that individual face if desired. As someone who has a vision impaired and has somewhat special requirements for font properties and someone who has maintained packages that use a number of faces, I know how hard it can be to select appropriate defaults. I frequently find packages which have poor defaults or defaults which only work for systems with a light/white background. Although faces have the facility to be defined with multiple options depending on the display type or background, it seems not many packages take advantage of this. My main reason for supporting the notion of using inherit is that it could mean we may have a set of well defined core faces that developers could use to provide good defaults, but at the same time, leave the individual user with the ability to modify if necessary. I prefer inherit over just using a variable holding a face name as the user can modify things without having to know what other faces to choose from (and knowing the face they choose is always defined and not just defined at the time they use something like list-display-faces to find an alternative). Stephan has also raised important points. The existing set of 'standard' faces is not extensive enough to meet all needs. Gnus is probably a good example. You could not currently use inherit for all the gnus faces without 'doubling up' and losing some distinction between different faces. However, I don't think the suggestion was to make *all* package faces use inherit - but of course, if its not all, which ones will it be and how is that determined? I still think making more use of inherit is a good idea. Stephan may be right in that we could need a larger set of 'core' font-lock-* faces to make this work and I still think we would need some guidelines/principals to help developers know which would be the most appropriate face to inherit from. Doing this would make it easier to maintain a set of well defined core faces that would work well under all environments and give users a better initial default experience while allowing maximum flexibility in individual configuraiton with minimal knowledge. Tim [-- Attachment #2: Type: text/html, Size: 3620 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 17:17 ` Chong Yidong 2011-02-02 20:33 ` Philipp Haselwarter 2011-02-02 21:24 ` Eliminating a couple of independent face definitions Tim Cross @ 2011-02-03 16:14 ` Dan Nicolaescu 2 siblings, 0 replies; 43+ messages in thread From: Dan Nicolaescu @ 2011-02-03 16:14 UTC (permalink / raw) To: Chong Yidong; +Cc: Tim Cross, Lennart Borgman, emacs-devel Chong Yidong <cyd@stupidchicken.com> writes: > Tim Cross <theophilusx@gmail.com> writes: > >> My only concern is how you define what to inherit from. For example, >> in your suggestion of compiler warnings inheriting form >> font-lock-comment-face I immediately wondered why you would not >> inherit from font-lock-warning face? > > font-lock-warning-face is already used for compilation errors, which are > more serious than warnings. That is an annoyance. It seems that adding a font-lock-error-face and make all the current users of font-lock-warning-face use that one is the right thing to do. How about changing M-x list-faces-display to mark the faces that just inherit from other faces with a special tag? That way when people look to customize their theme it's easy to spot the base faces. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 4:11 ` Lennart Borgman 2011-02-02 5:02 ` Tim Cross @ 2011-02-02 17:16 ` Chong Yidong 1 sibling, 0 replies; 43+ messages in thread From: Chong Yidong @ 2011-02-02 17:16 UTC (permalink / raw) To: Lennart Borgman; +Cc: emacs-devel Lennart Borgman <lennart.borgman@gmail.com> writes: > It is really good to try to merge some faces, but the specific merges > you mentioned seems a bit unfortunate. Yes, the initial suggestion was not that good. I think I was able to sort things out satisfactorily. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 4:05 Eliminating a couple of independent face definitions Chong Yidong 2011-02-02 4:11 ` Lennart Borgman @ 2011-02-02 9:58 ` Štěpán Němec 2011-02-02 17:05 ` Chong Yidong 2011-02-02 10:05 ` Julien Danjou 2 siblings, 1 reply; 43+ messages in thread From: Štěpán Němec @ 2011-02-02 9:58 UTC (permalink / raw) To: Chong Yidong; +Cc: emacs-devel Chong Yidong <cyd@stupidchicken.com> writes: > It would be nice if almost all faces in packaged included with Emacs > inherit from the basic or font-lock faces. Most faces already do this. > This way, users don't have to specify as much when they write a Custom > theme or their own personal face customizations. > > I'd like to inherit-ize most of the remaining faces that don't already > do this. For instance, compilation-warning is currently "Orange", and > compilation-info is "Green3"; I want to make them inherit from > font-lock-doc-face and font-lock comment-face respectively. (The rest > of the compilation-mode already inherit from font-lock faces.) > > There are a few more similar changes here and there. Any objection? Making two faces that were originally orange and green both orange(ish) doesn't sound like a terribly good idea. Similarly to my reaction to your similar proposal on the Gnus list -- I don't think you can use the current very limited set of default font lock faces for all the various faces out there (or "in there" in Emacs core). Maybe you could introduce some more default faces to begin with, from which the others could then more sensibly inherit? Štěpán ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 9:58 ` Štěpán Němec @ 2011-02-02 17:05 ` Chong Yidong 0 siblings, 0 replies; 43+ messages in thread From: Chong Yidong @ 2011-02-02 17:05 UTC (permalink / raw) To: Štěpán Němec; +Cc: emacs-devel Štěpán Němec <stepnem@gmail.com> writes: > Making two faces that were originally orange and green both orange(ish) > doesn't sound like a terribly good idea. Fair enough. So, let's make it font-lock-variable-name-face and font-lock-type-face, which are orange and green by default. > Similarly to my reaction to your similar proposal on the Gnus list -- I > don't think you can use the current very limited set of default font > lock faces for all the various faces out there (or "in there" in Emacs > core). Maybe you could introduce some more default faces to begin with, > from which the others could then more sensibly inherit? The counterargument is that the majority of faces out there already do inherit from font-lock and other basic faces. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: Eliminating a couple of independent face definitions 2011-02-02 4:05 Eliminating a couple of independent face definitions Chong Yidong 2011-02-02 4:11 ` Lennart Borgman 2011-02-02 9:58 ` Štěpán Němec @ 2011-02-02 10:05 ` Julien Danjou 2 siblings, 0 replies; 43+ messages in thread From: Julien Danjou @ 2011-02-02 10:05 UTC (permalink / raw) To: Chong Yidong; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 320 bytes --] On Wed, Feb 02 2011, Chong Yidong wrote: > There are a few more similar changes here and there. Any objection? I totally agree. I spend most of my theme in my Emacs theme file using :inherit to redefine fonts rather than (re)specifying various (new) colors. -- Julien Danjou ❱ http://julien.danjou.info [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2011-03-10 19:11 UTC | newest] Thread overview: 43+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-02-02 4:05 Eliminating a couple of independent face definitions Chong Yidong 2011-02-02 4:11 ` Lennart Borgman 2011-02-02 5:02 ` Tim Cross 2011-02-02 15:15 ` Drew Adams 2011-02-02 17:17 ` Chong Yidong 2011-02-02 20:33 ` Philipp Haselwarter 2011-02-02 23:01 ` Lennart Borgman 2011-02-03 19:10 ` Drew Adams 2011-02-04 0:12 ` Tim Cross 2011-02-05 22:11 ` Drew Adams 2011-02-07 0:59 ` Drew Adams 2011-02-07 1:30 ` Tim Cross 2011-02-07 14:09 ` Drew Adams 2011-02-07 21:14 ` Tim Cross 2011-02-07 22:12 ` Drew Adams 2011-02-08 3:51 ` Tim Cross 2011-02-08 15:26 ` Drew Adams 2011-02-08 19:10 ` Philipp Haselwarter 2011-02-08 13:58 ` Davis Herring 2011-02-08 14:33 ` Drew Adams 2011-02-08 15:34 ` Davis Herring 2011-02-08 16:16 ` Drew Adams 2011-02-08 17:40 ` Lennart Borgman 2011-02-08 19:10 ` Davis Herring 2011-02-07 1:08 ` Tim Cross 2011-02-04 0:18 ` Stephen J. Turnbull 2011-02-04 3:55 ` John Yates 2011-02-04 4:56 ` Stephen J. Turnbull 2011-02-04 4:57 ` Jambunathan K 2011-02-05 22:09 ` Drew Adams 2011-02-06 7:11 ` Stephen J. Turnbull 2011-02-04 10:26 ` Julien Danjou 2011-02-04 17:57 ` color-complement for defface (was: Eliminating a couple of independent face definitions) Ted Zlatanov 2011-02-14 18:11 ` color-complement for defface Ted Zlatanov 2011-02-20 17:44 ` Julien Danjou 2011-03-10 19:09 ` Ted Zlatanov 2011-03-10 19:11 ` Ted Zlatanov 2011-02-02 21:24 ` Eliminating a couple of independent face definitions Tim Cross 2011-02-03 16:14 ` Dan Nicolaescu 2011-02-02 17:16 ` Chong Yidong 2011-02-02 9:58 ` Štěpán Němec 2011-02-02 17:05 ` Chong Yidong 2011-02-02 10:05 ` Julien Danjou
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).