From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Miles Bader Newsgroups: gmane.emacs.devel Subject: Re: reducing defface redundancy Date: 03 Jul 2002 15:38:43 +0900 Sender: emacs-devel-admin@gnu.org Message-ID: References: <877kn3qczq.fsf@tc-1-100.kawasaki.gol.ne.jp> <871yd9q09b.fsf@tc-1-100.kawasaki.gol.ne.jp> <200204220747.g3M7lo301995@aztec.santafe.edu> <200204230024.g3N0OH702333@aztec.santafe.edu> <200204241754.g3OHsIm03235@aztec.santafe.edu> Reply-To: Miles Bader NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1025678327 10766 127.0.0.1 (3 Jul 2002 06:38:47 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Wed, 3 Jul 2002 06:38:47 +0000 (UTC) Cc: abraham@dina.kvl.dk, emacs-devel@gnu.org Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 17Pdmp-0002nW-00 for ; Wed, 03 Jul 2002 08:38:47 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 17PdsD-0000vz-00 for ; Wed, 03 Jul 2002 08:44:21 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 17Pdn7-0007Js-00; Wed, 03 Jul 2002 02:39:05 -0400 Original-Received: from tyo202.gate.nec.co.jp ([210.143.35.52]) by fencepost.gnu.org with smtp (Exim 3.34 #1 (Debian)) id 17Pdmu-0007IS-00; Wed, 03 Jul 2002 02:38:52 -0400 Original-Received: from mailgate4.nec.co.jp ([10.7.69.193]) by TYO202.gate.nec.co.jp (8.11.6/3.7W01080315) with ESMTP id g636cne18198; Wed, 3 Jul 2002 15:38:49 +0900 (JST) Original-Received: from mailsv4.nec.co.jp (mailgate51.nec.co.jp [10.7.69.190]) by mailgate4.nec.co.jp (8.11.6/3.7W-MAILGATE-NEC) with ESMTP id g636cmr13896; Wed, 3 Jul 2002 15:38:48 +0900 (JST) Original-Received: from mcsss2.ucom.lsi.nec.co.jp ([10.30.114.133]) by mailsv4.nec.co.jp (8.11.6/3.7W-MAILSV4-NEC) with ESMTP id g636ciN00084; Wed, 3 Jul 2002 15:38:45 +0900 (JST) Original-Received: from mcspd15.ucom.lsi.nec.co.jp (mcspd15 [10.30.114.174]) by mcsss2.ucom.lsi.nec.co.jp (8.10.2+Sun/3.7Wlsi_mx_6.0) with ESMTP id g636ciK18720; Wed, 3 Jul 2002 15:38:44 +0900 (JST) Original-Received: by mcspd15.ucom.lsi.nec.co.jp (Postfix, from userid 31295) id E622A37DC; Wed, 3 Jul 2002 15:38:43 +0900 (JST) Original-To: rms@gnu.org System-Type: i686-pc-linux-gnu Blat: Foop In-Reply-To: <200204241754.g3OHsIm03235@aztec.santafe.edu> Original-Lines: 117 Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.11 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:5389 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:5389 This email is about my suggestion a while ago for adding a more convenient grammar for defface; I've appended some of the original message to the end of this one for reference. If you recall, the main objection to this was that it might not interact well with the customize-face UI, in particular with the default mode where customize-face only presents the current face attributes (as opposed to the optional `display all face specs' mode, where it presents the whole conditional face definition, with all the various possibilities broken out). After that discussion, my thought was that the proper way to deal with this is actually simple: when the user changes some attribute, find out at what `level' in the defface specification the changed attribute came from, and apply the user's change there; for any attributes _not_ in the original defface spec, just apply them at the `top' (root) level. I think this would be very natural (probably more so than the current behavior, and certainly no worse). I also think it would be simple to implement. So for instance consider the following example: (defface subtle-yet-underlined-mode-line '(:inherit mode-line :underline t (((background light) :background "grey90") ((background dark) :background "grey10")))) If the user customizes this face, he'll be presented with the _current_ list of face attributes; if he's on a dark-background display, that will be (:inherit mode-line :underline t :background "grey10"). With the suggested algorithm, if he changes `:inherit mode-line', `:underline t', or adds a previously unused attribute, that change will apply to all environments. However, if he changes `:background ...', the change will only apply to the relevant branch of the `conditional' in the defface spec. So basically the rewritten face spec will look like the original face-spec except with the user's changes integrated. What do you think of this suggestion? -Miles Excerpt from original message: In order to be optimal on disparate display types, many defface clauses end up having a bunch of clauses with almost the same contents, but varying one or two attributes. With the ability to query individual features, this might become even worse. So this is a suggestion on a way to reduce the redundancy of defface specs. The basic idea is to allow using a lisp vector ([...]) as a kind of `or' expression in the attribute part of a defface clause. Each element of vector is an attribute list, and the first one that is entirely `supportable' (that is, `display-capable-p' returns true for all of its attributes) is used. This way, in many cases common attributes could be factored out, and the variant parts would become just a vector of possibilities with emacs choosing the first one that works. I think this style is very natural, and might even result in better faces because it would be easier to write good face specifications (currently, you have to duplicate a lot of stuff, and it can get tedious to keep everything updated). Here's one possibility for a more flexible specification that uses the `or' vector idea above, and I think should be backward compatible: SPECS ::= (CLAUSE ...) CLAUSE ::= ATTRIBUTE | (TESTS CLAUSE...) ; traditional top-level style | [SPECS ...] ; `or' vector style | (TESTS (ATTRIBUTE ...)) ; old style attribute list ATTRIBUTE ::= ATTR-NAME ATTR-VALUE TESTS ::= t | (TEST ...) TEST ::= (TEST-NAME TEST-ARG...) In addition to adding the `or' vectors, this makes defface specs recursive in a way that allows omitting the traditional clause list when it's not necessary (e.g., when currently you just have `t' as the list of tests). Thus _very_ simple defface specs are possible: (defface annoying '(:foreground "red" :background "yellow")) which seems very natural. The `italic' example from my earlier message can become: (defface italic [(:slant italic) (:underline t)]) And if someone wants a face that's both `emphasized' and yellow, he can do: (defface emph-yellow '(:foreground "yellow" [(:bold t) (:slant italic) (:underline t)])) which will make either a bold, italic, or underlined yellow face, depending on what the display is capable of. Since the new specification is recursive, it's possible to put normal defface clauses at sub-levels, if that's desirable for factoring out common attributes; for instance, this is often : (defface subtle-yet-underlined-mode-line '(:inherit mode-line :underline t (((background light) :background "grey90") ((background dark) :background "grey10")))) -- "Most attacks seem to take place at night, during a rainstorm, uphill, where four map sheets join." -- Anon. British Officer in WW I