From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Drew Adams" Newsgroups: gmane.emacs.devel Subject: RE: Eliminating a couple of independent face definitions Date: Sat, 5 Feb 2011 14:11:44 -0800 Message-ID: <1A6A06363E5F4274B2A00E2CA8A242D1@us.oracle.com> References: <87oc6vm67v.fsf@stupidchicken.com><87vd12z77n.fsf@stupidchicken.com><87ipx289cu.fsf@nzebook.haselwarter.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1296943939 7383 80.91.229.12 (5 Feb 2011 22:12:19 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 5 Feb 2011 22:12:19 +0000 (UTC) Cc: emacs-devel@gnu.org, 'Philipp Haselwarter' To: "'Tim Cross'" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Feb 05 23:12:14 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PlqMR-0005Ot-QG for ged-emacs-devel@m.gmane.org; Sat, 05 Feb 2011 23:12:14 +0100 Original-Received: from localhost ([127.0.0.1]:47785 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PlqMQ-0007mc-6c for ged-emacs-devel@m.gmane.org; Sat, 05 Feb 2011 17:12:06 -0500 Original-Received: from [140.186.70.92] (port=36687 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PlqML-0007mC-0q for emacs-devel@gnu.org; Sat, 05 Feb 2011 17:12:02 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PlqMI-00078S-O9 for emacs-devel@gnu.org; Sat, 05 Feb 2011 17:12:00 -0500 Original-Received: from rcsinet10.oracle.com ([148.87.113.121]:56904) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PlqMI-00078M-Ci for emacs-devel@gnu.org; Sat, 05 Feb 2011 17:11:58 -0500 Original-Received: from rcsinet13.oracle.com (rcsinet13.oracle.com [148.87.113.125]) by rcsinet10.oracle.com (Switch-3.4.2/Switch-3.4.2) with ESMTP id p15MBq4n020430 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 5 Feb 2011 22:11:53 GMT Original-Received: from acsmt355.oracle.com (acsmt355.oracle.com [141.146.40.155]) by rcsinet13.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id p15MBp7k001482; Sat, 5 Feb 2011 22:11:51 GMT Original-Received: from abhmt002.oracle.com by acsmt355.oracle.com with ESMTP id 1026728651296943904; Sat, 05 Feb 2011 14:11:44 -0800 Original-Received: from dradamslap1 (/10.159.50.79) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sat, 05 Feb 2011 14:11:43 -0800 X-Mailer: Microsoft Office Outlook 11 In-Reply-To: Thread-Index: AcvEADd6GcHxcmvVR8+lgO8nrDVs6wACQO1g X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5994 X-Source-IP: acsmt355.oracle.com [141.146.40.155] X-Auth-Type: Internal IP X-CT-RefId: str=0001.0A090204.4D4DCB28.003F:SCFMA4539814,ss=1,fgs=0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 148.87.113.121 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:135623 Archived-At: 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.