* reducing defface redundancy @ 2002-04-20 3:12 Miles Bader 2002-04-20 7:14 ` Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 33+ messages in thread From: Miles Bader @ 2002-04-20 3:12 UTC (permalink / raw) 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. [note that this is one reason why I suggested using face attribute names/values as the argument to `display-capable-p'] 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 Currently the grammar of defface specs is something like this: SPECS ::= (CLAUSE ...) CLAUSE ::= (TESTS ATTRIBUTE...) | (TESTS (ATTRIBUTE ...)) ; old style attribute list ATTRIBUTE ::= ATTR-NAME ATTR-VALUE TESTS ::= t | (TEST ...) TEST ::= (TEST-NAME TEST-ARG...) 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")))) So what'ya think? It shouldn't be hard to implement, given the existance of `display-capable-p', it's backward-compatible, and whizzy as all hell (well, I think so anyway)... Thanks, -Miles -- "Most attacks seem to take place at night, during a rainstorm, uphill, where four map sheets join." -- Anon. British Officer in WW I ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-20 3:12 reducing defface redundancy Miles Bader @ 2002-04-20 7:14 ` Eli Zaretskii 2002-04-20 15:59 ` Per Abrahamsen 2002-04-21 20:02 ` Richard Stallman 2 siblings, 0 replies; 33+ messages in thread From: Eli Zaretskii @ 2002-04-20 7:14 UTC (permalink / raw) Cc: emacs-devel > From: Miles Bader <miles@gnu.org> > Date: 20 Apr 2002 12:12:57 +0900 > > (defface subtle-yet-underlined-mode-line > '(:inherit mode-line > :underline t > (((background light) :background "grey90") > ((background dark) :background "grey10")))) > > So what'ya think? It shouldn't be hard to implement, given the > existance of `display-capable-p', it's backward-compatible, and whizzy > as all hell (well, I think so anyway)... I'm not sure this will make defface's we have less redundant and repetitive, but I think the feature as such can be useful. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-20 3:12 reducing defface redundancy Miles Bader 2002-04-20 7:14 ` Eli Zaretskii @ 2002-04-20 15:59 ` Per Abrahamsen 2002-04-20 17:35 ` Eli Zaretskii ` (2 more replies) 2002-04-21 20:02 ` Richard Stallman 2 siblings, 3 replies; 33+ messages in thread From: Per Abrahamsen @ 2002-04-20 15:59 UTC (permalink / raw) Cc: emacs-devel Miles Bader <miles@gnu.org> writes: > So this is a suggestion on a way to reduce the redundancy of defface > specs. Please, always remember that the usability of the defface UI is far more important than the usability of the defface Lisp interface. defface is really a sibling to defcustom. So when making changes to the defface, please consisder first: 1. How will these changes affect the UI? 2. Will the changes make the already far too complex UI more or less complex? 3. If it make the UI more complex, is the added power really worth the complexity? It is really easy to invent all kinds of smart stuff to the defface spec at the Lisp level. Comming up with good UI is way harder. Actually, I think it would be far more useful to work on the UI, determine what it needs to become simpler or more useful, and then, afterwards, start to think about how to translate these changes to the Lisp interface. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-20 15:59 ` Per Abrahamsen @ 2002-04-20 17:35 ` Eli Zaretskii 2002-04-21 9:12 ` Per Abrahamsen 2002-04-20 17:41 ` Alex Schroeder 2002-04-21 2:00 ` Miles Bader 2 siblings, 1 reply; 33+ messages in thread From: Eli Zaretskii @ 2002-04-20 17:35 UTC (permalink / raw) Cc: miles, emacs-devel > From: Per Abrahamsen <abraham@dina.kvl.dk> > Date: Sat, 20 Apr 2002 17:59:41 +0200 > > It is really easy to invent all kinds of smart stuff to the defface > spec at the Lisp level. Comming up with good UI is way harder. Sorry, I don't understand: what UI? defface is not a user-level feature, it's a programmer feature. Did you mean API, perhaps? If you do mean the API, I believe Miles was trying to make it better, more convenient. The need to repeat the same face attributes over and over is a PITA, IMHO. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-20 17:35 ` Eli Zaretskii @ 2002-04-21 9:12 ` Per Abrahamsen 0 siblings, 0 replies; 33+ messages in thread From: Per Abrahamsen @ 2002-04-21 9:12 UTC (permalink / raw) "Eli Zaretskii" <eliz@is.elta.co.il> writes: >> From: Per Abrahamsen <abraham@dina.kvl.dk> >> Date: Sat, 20 Apr 2002 17:59:41 +0200 >> >> It is really easy to invent all kinds of smart stuff to the defface >> spec at the Lisp level. Comming up with good UI is way harder. > > Sorry, I don't understand: what UI? defface is not a user-level > feature, it's a programmer feature. The primary purpose of defface is to give customize-face something to work on. Just like the primary purpose of defcustom is to give information to customize-variable. Otherwise, we could just as well use the pre-customize facilities for creating faces and variables. > Did you mean API, perhaps? Certainly NOT! There are a zillion convenient things one can do on the API level, that will translate badly or not at all to the UI. Design the UI *first*, then translate it to the API. The UI is the hard part. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-20 15:59 ` Per Abrahamsen 2002-04-20 17:35 ` Eli Zaretskii @ 2002-04-20 17:41 ` Alex Schroeder 2002-04-21 2:00 ` Miles Bader 2 siblings, 0 replies; 33+ messages in thread From: Alex Schroeder @ 2002-04-20 17:41 UTC (permalink / raw) Per Abrahamsen <abraham@dina.kvl.dk> writes: > Actually, I think it would be far more useful to work on the UI, > determine what it needs to become simpler or more useful, and then, > afterwards, start to think about how to translate these changes to the > Lisp interface. I agree with Per. Just remember what happened to custom-theme and friends... There just was no UI to actually handy all that ilisp cleverness. And compare the success of color-theme.el to that. It is much simpler (the elisp is a no-brainer), but the UI works. And is the important thing. Alex. -- http://www.electronicintifada.net/diaries/index.html http://www.us-israel.org/jsource/US-Israel/hr2506c.html ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-20 15:59 ` Per Abrahamsen 2002-04-20 17:35 ` Eli Zaretskii 2002-04-20 17:41 ` Alex Schroeder @ 2002-04-21 2:00 ` Miles Bader 2002-04-21 9:17 ` Per Abrahamsen 2002-04-22 7:47 ` Richard Stallman 2 siblings, 2 replies; 33+ messages in thread From: Miles Bader @ 2002-04-21 2:00 UTC (permalink / raw) Cc: emacs-devel Per Abrahamsen <abraham@dina.kvl.dk> writes: > Please, always remember that the usability of the defface UI is far > more important than the usability of the defface Lisp interface. > defface is really a sibling to defcustom. They have different constraints though: Since the defface spec is used by default, by _all_ users of emacs, it has to be very flexible, and deal with all sorts of possible environments. The changes I described would be very useful for allowing it to do that job better. The face-customization UI on the other hand, is only used by a single user to define his personal faces; since a given user generally uses only a small number of different environments, he usually doesn't need all that flexibility, and is happy with a simpler representation. > So when making changes to the defface, please consisder first: > > 1. How will these changes affect the UI? It need not affect it at all. Remember, by default (unless you select `Show All Display Specs'), the face customization widget basically tosses out all the clauses of the current defface spec except the active one. So, 99% of the time, the user only deals with the _current_ definition of a face, and is happy. So, the question is, what should be done for the advanced user, that really does want to define a complex face using the UI, that works under different display types? If my proposal for defface is adopted, I forsee the UI interface basically `flattening' the defface spec before passing it to the widget. In other words, it would percolate up all conditional and `or' clauses to the top-level so the result looks like a traditional defface spec (in the case of an `or' vector this would result in the vector being translated into conditional clauses, using the `capable' test I suggested). Indeed, this flattening could happen when the defface macro is expanded, if the flattened form is easier for the infrastructure to deal with (certainly it would make implementation easier, since wouldn't have to change any existing functions except defface!). Here are some examples of flattening: 1) My previous example `subtle-yet-underlined-mode-line': (:inherit mode-line :underline t ((((background light)) :background "grey90") (((background dark)) :background "grey10")))) Flattens into: ((((background light)) :inherit mode-line :underline t :background "grey90") (((background dark)) :inherit mode-line :underline t :background "grey10")) 2) My previous example `emph-yellow': (:foreground "yellow" [(:weight bold) (:slant italic) (:underline t)])) Flattens into: ((((capable :weight bold)) :foreground "yellow" :weight bold) (((capable :slant italic)) :foreground "yellow" :slant italic) (t :foreground "yellow" :underline t)) So as you can see, my proposal really is just a way to make defface easier and more convenient. It won't make the UI any less useful, or indeed even change it. And remember, it doesn't just make defface specs less redundant, it also makes it possible to write _simpler_ defface specs, which more closely follow the thinking of the face designer. -Miles -- Next to fried food, the South has suffered most from oratory. -- Walter Hines Page ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-21 2:00 ` Miles Bader @ 2002-04-21 9:17 ` Per Abrahamsen 2002-04-21 9:34 ` Miles Bader 2002-04-22 7:47 ` Richard Stallman 2002-04-22 7:47 ` Richard Stallman 1 sibling, 2 replies; 33+ messages in thread From: Per Abrahamsen @ 2002-04-21 9:17 UTC (permalink / raw) Please do not install any changes to the API until you have the UI working, and have confirmed that UI has not become any worse from the change. defface was invented because there was no way a useful UI could be build from the old, infinitely flexible, way to create faces. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-21 9:17 ` Per Abrahamsen @ 2002-04-21 9:34 ` Miles Bader 2002-04-22 7:47 ` Richard Stallman 1 sibling, 0 replies; 33+ messages in thread From: Miles Bader @ 2002-04-21 9:34 UTC (permalink / raw) Cc: emacs-devel Per Abrahamsen <abraham@dina.kvl.dk> writes: > Please do not install any changes to the API until you have the UI > working, and have confirmed that UI has not become any worse from the > change. Don't worry, I won't. -Miles -- Quidquid latine dictum sit, altum viditur. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-21 9:17 ` Per Abrahamsen 2002-04-21 9:34 ` Miles Bader @ 2002-04-22 7:47 ` Richard Stallman 1 sibling, 0 replies; 33+ messages in thread From: Richard Stallman @ 2002-04-22 7:47 UTC (permalink / raw) Cc: emacs-devel Please do not install any changes to the API until you have the UI working, and have confirmed that UI has not become any worse from the change. I agree. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-21 2:00 ` Miles Bader 2002-04-21 9:17 ` Per Abrahamsen @ 2002-04-22 7:47 ` Richard Stallman 2002-04-22 8:15 ` Miles Bader 1 sibling, 1 reply; 33+ messages in thread From: Richard Stallman @ 2002-04-22 7:47 UTC (permalink / raw) Cc: abraham, emacs-devel Remember, by default (unless you select `Show All Display Specs'), the face customization widget basically tosses out all the clauses of the current defface spec except the active one. So, 99% of the time, the user only deals with the _current_ definition of a face, and is happy. Simple face customization is clean now because it affects just one alternative, and it is easy and well-defined to select just the alternative that applies. With your propose defface change, the attributes actually specified would not come from a single alternative in a simple way. So the customization of the active parts of the defface spec would raise difficult issues. If the user adds a new attribute, where in the structure does it go? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-22 7:47 ` Richard Stallman @ 2002-04-22 8:15 ` Miles Bader 2002-04-23 0:24 ` Richard Stallman 0 siblings, 1 reply; 33+ messages in thread From: Miles Bader @ 2002-04-22 8:15 UTC (permalink / raw) Cc: abraham, emacs-devel Richard Stallman <rms@gnu.org> writes: > Simple face customization is clean now because it affects just one > alternative, and it is easy and well-defined to select just the > alternative that applies. > > With your propose defface change, the attributes actually specified > would not come from a single alternative in a simple way. So the > customization of the active parts of the defface spec would raise > difficult issues. If the user adds a new attribute, where in the > structure does it go? I replied to Per's question about this in some detail, but here's the short version: You can think of the grammar I outlined as merely being a convenient shorthand for the defface user; it's not hard to convert it into exactly the same `simple but redundant' 2-level format that the UI uses now. In fact, this transformation can be done in defface (or rather, in the code the defface macro expands into), before any other part of emacs sees it; this would keep implementation simple. Of course, in order to support the display `capability querying' feature, a new type of test has to be added to the set that the UI and other parts of the face code recognize, but that's an orthogonal issue to the change in the defface grammar (and it's not hard to do either). -Miles -- .Numeric stability is probably not all that important when you're guessing. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-22 8:15 ` Miles Bader @ 2002-04-23 0:24 ` Richard Stallman 2002-04-23 1:36 ` Miles Bader 0 siblings, 1 reply; 33+ messages in thread From: Richard Stallman @ 2002-04-23 0:24 UTC (permalink / raw) Cc: abraham, emacs-devel I replied to Per's question about this in some detail, but here's the short version: You can think of the grammar I outlined as merely being a convenient shorthand for the defface user; it's not hard to convert it into exactly the same `simple but redundant' 2-level format that the UI uses now. I am not convinced that is a good solution to the issue of what Custom should do. Suppose I give a face one unconditional attribute, and suppose the user customizes that attribute with Custom. Should his customization always be recorded only for the one kind of screen he is actually using? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-23 0:24 ` Richard Stallman @ 2002-04-23 1:36 ` Miles Bader 2002-04-24 17:54 ` Richard Stallman 0 siblings, 1 reply; 33+ messages in thread From: Miles Bader @ 2002-04-23 1:36 UTC (permalink / raw) Cc: abraham, emacs-devel Richard Stallman <rms@gnu.org> writes: > You can think of the grammar I outlined as merely being a > convenient shorthand for the defface user; it's not hard to convert it > into exactly the same `simple but redundant' 2-level format that the UI > uses now. > > I am not convinced that is a good solution to the issue of what > Custom should do. Suppose I give a face one unconditional attribute, > and suppose the user customizes that attribute with Custom. > Should his customization always be recorded only for the one kind > of screen he is actually using? Well, there are two interfaces used by the (current) custom face UI: * The current-display-type-only interface, which is the default. This displays the face used by the current display, and if the user changes something in the face and saves it, the current face attributes become unconditional for all display types (trashing any display-type-conditionalization that was defined by the defface specification for that face). * The many-display-types interface, which the user has to explicitly enable. This displays all the various conditional faces that defface defined, and allows the user to change any of them. This doesn't trash any information. My suggestion of flattening the grammar, and using the current UI, wouldn't change any of this. If the user choose the 2nd (many-display-types) UI, and there's a `common' attribute in the defface spec, he will see that common attribute replicated in each face displayed by the face UI. Having to tweak it for each displayed face might be a little annoying, but it seems to make sense from a UI point of view (a more complex UI that actually mirrored the defface grammar could solve this, perhaps, but the additional complexity could make the situation much more confusing). However, for the 1st UI (current-display-type-only), it might be a useful try and detect changes to `common' attributes and preserve a modified version of the original defface spec, instead of just trashing it as the UI does now. Anyway, my point is that the new grammar won't make anything worse, and may provide some additional leeway for improvement. However, I don't think clever handling of common attributes in the UI is necessarily a requirement for an initial implementation (given that there doesn't seem to be any complaint about the current UI trashing things). -Miles -- o The existentialist, not having a pillow, goes everywhere with the book by Sullivan, _I am going to spit on your graves_. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-23 1:36 ` Miles Bader @ 2002-04-24 17:54 ` Richard Stallman 2002-04-24 20:06 ` Miles Bader 2002-07-03 6:38 ` Miles Bader 0 siblings, 2 replies; 33+ messages in thread From: Richard Stallman @ 2002-04-24 17:54 UTC (permalink / raw) Cc: abraham, emacs-devel Well, there are two interfaces used by the (current) custom face UI: * The current-display-type-only interface, which is the default. This is the hard case. Yes you can flatten the nested spec and have custom operate on that, but the hard part is how to alter the nested spec based on the user's customizations. However, for the 1st UI (current-display-type-only), it might be a useful try and detect changes to `common' attributes and preserve a modified version of the original defface spec, instead of just trashing it as the UI does now. Getting this right is the hard part. Anyway, my point is that the new grammar won't make anything worse, and may provide some additional leeway for improvement. Yes it makes something worse. It makes the effect of cutsomizing the face problematical. At present that is not so. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-24 17:54 ` Richard Stallman @ 2002-04-24 20:06 ` Miles Bader 2002-04-25 9:52 ` Per Abrahamsen 2002-07-03 6:38 ` Miles Bader 1 sibling, 1 reply; 33+ messages in thread From: Miles Bader @ 2002-04-24 20:06 UTC (permalink / raw) Cc: abraham, emacs-devel Richard Stallman <rms@gnu.org> writes: > Anyway, my point is that the new grammar won't make anything worse, and > may provide some additional leeway for improvement. > > Yes it makes something worse. It makes the effect of cutsomizing > the face problematical. At present that is not so. Huh? Customizing a face now _throws away_ information (that is, every thing defined by the defface spec except that for the current display), unless the user selects the more complicated interface. That seems pretty problematical to me... Throwing away this information is bad, I think -- but that's a property of the (current) UI. I'm mystified as to how you think that things would be _worse_. -Miles -- I'm beginning to think that life is just one long Yoko Ono album; no rhyme or reason, just a lot of incoherent shrieks and then it's over. --Ian Wolff ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-24 20:06 ` Miles Bader @ 2002-04-25 9:52 ` Per Abrahamsen 2002-04-26 3:18 ` Richard Stallman 0 siblings, 1 reply; 33+ messages in thread From: Per Abrahamsen @ 2002-04-25 9:52 UTC (permalink / raw) Cc: rms, emacs-devel Miles Bader <miles@gnu.org> writes: > Richard Stallman <rms@gnu.org> writes: >> Anyway, my point is that the new grammar won't make anything worse, and >> may provide some additional leeway for improvement. >> >> Yes it makes something worse. It makes the effect of cutsomizing >> the face problematical. At present that is not so. > > Huh? Customizing a face now _throws away_ information (that is, every > thing defined by the defface spec except that for the current display), > unless the user selects the more complicated interface. That seems > pretty problematical to me... It is a bug somewhere deep down in the code. It is _supposed_ to only affect the "current" display spec, and leave all others as they were. I was surpised when I learned of this bug, but couldn't figure out how to fix it. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-25 9:52 ` Per Abrahamsen @ 2002-04-26 3:18 ` Richard Stallman 0 siblings, 0 replies; 33+ messages in thread From: Richard Stallman @ 2002-04-26 3:18 UTC (permalink / raw) Cc: miles, emacs-devel It is a bug somewhere deep down in the code. It is _supposed_ to only affect the "current" display spec, and leave all others as they were. I was surpised when I learned of this bug, but couldn't figure out how to fix it. Did you at least figure out how the bug happens? With that starting point, maybe someone else can design a good fix. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-24 17:54 ` Richard Stallman 2002-04-24 20:06 ` Miles Bader @ 2002-07-03 6:38 ` Miles Bader 2002-07-03 9:31 ` Kai Großjohann ` (2 more replies) 1 sibling, 3 replies; 33+ messages in thread From: Miles Bader @ 2002-07-03 6:38 UTC (permalink / raw) Cc: abraham, emacs-devel 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 ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-03 6:38 ` Miles Bader @ 2002-07-03 9:31 ` Kai Großjohann 2002-07-03 14:50 ` Kim F. Storm 2002-07-08 18:20 ` Richard Stallman 2 siblings, 0 replies; 33+ messages in thread From: Kai Großjohann @ 2002-07-03 9:31 UTC (permalink / raw) Cc: rms, abraham, emacs-devel Miles Bader <miles@lsi.nec.co.jp> writes: > 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. I like this idea. It is simple and easy to grok for the user. At a later time, people can think about enhancing Custom such that more complicated things can be done, eg. using Emacs running on a light background to change the color for dark backgrounds. kai -- A large number of young women don't trust men with beards. (BFBS Radio) ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-03 6:38 ` Miles Bader 2002-07-03 9:31 ` Kai Großjohann @ 2002-07-03 14:50 ` Kim F. Storm 2002-07-08 18:20 ` Richard Stallman 2 siblings, 0 replies; 33+ messages in thread From: Kim F. Storm @ 2002-07-03 14:50 UTC (permalink / raw) Cc: rms, abraham, emacs-devel Miles Bader <miles@lsi.nec.co.jp> writes: > 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. > > What do you think of this suggestion? Sounds fine. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-03 6:38 ` Miles Bader 2002-07-03 9:31 ` Kai Großjohann 2002-07-03 14:50 ` Kim F. Storm @ 2002-07-08 18:20 ` Richard Stallman 2002-07-09 1:25 ` Miles Bader 2 siblings, 1 reply; 33+ messages in thread From: Richard Stallman @ 2002-07-08 18:20 UTC (permalink / raw) Cc: abraham, emacs-devel 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? I think users will find this surprising and inconsistent. In addition, we want to have buffer-local face definitions, and that will make this issue even more complex. This is an instance of the general conflict between WYSIWYG editing and conditional formatting commands. That suggests we should completely separate the WYSIWYG layer from the conditional command later. Here's a proposal. You can customize a face for the current display, for the current session, looking at a simple list of attributes, but you cannot save this. Or you can customize the conditional commands that define the face, by looking at the whole structure of them. That kind of customization you can save if you wish. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-08 18:20 ` Richard Stallman @ 2002-07-09 1:25 ` Miles Bader 2002-07-09 18:51 ` Richard Stallman 2002-07-09 18:51 ` Richard Stallman 0 siblings, 2 replies; 33+ messages in thread From: Miles Bader @ 2002-07-09 1:25 UTC (permalink / raw) Cc: abraham, emacs-devel Richard Stallman <rms@gnu.org> writes: > So basically the rewritten face spec will look like the original > face-spec except with the user's changes integrated. > > I think users will find this surprising and inconsistent. Can you say why you think this? I think it gets about as close as we can to `doing the intuitive thing' when a someone uses the simple face customization -- it's really impossible to always do things correctly, since we'd have to read the user's mind. Remember that the way I suggest integrating the user's changes follows the structure set up by the face creator, and possible user customizations are one thing to think about when creating the face. > In addition, we want to have buffer-local face definitions, and that > will make this issue even more complex. It depends on how buffer-local face definitions are implemented. My feeling is that there _shouldn't_ be real buffer-specific faces, but rather a way of remapping faces within a buffer. For instance foo-mode could make the `foo-default' be used as the default face within its buffers; if the user want's to change it, they'd have customize `foo-default', not `default' (though the customization widget could notice that there's a buffer-local remapping, and ask the user `do you want to edit the global `default' face, or the `foo-default' face being used in this buffer'). > You can customize a face for the current display, for the current > session, looking at a simple list of attributes, but you cannot save > this. Or you can customize the conditional commands that define the > face, by looking at the whole structure of them. That kind of > customization you can save if you wish. Well that would certainly get rid of the ambiguity, but I suspect that most users would absolutely hate it (I certainly would) -- it attempts to solve a fairly rare problem (face customizations that have surprising results on other display types) by making the _normal case_ more inconvenient and confusing! I think this is a case where it's possible to do a good job automatically most of the time. Since the problems that might arise are fairly minor (the face looks a bit funny), I think they're well justified by the extra convenience and utility for users in the common case from doing things automatically. -Miles -- The secret to creativity is knowing how to hide your sources. --Albert Einstein ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-09 1:25 ` Miles Bader @ 2002-07-09 18:51 ` Richard Stallman 2002-07-09 18:51 ` Richard Stallman 1 sibling, 0 replies; 33+ messages in thread From: Richard Stallman @ 2002-07-09 18:51 UTC (permalink / raw) Cc: abraham, emacs-devel Can you say why you think this? I think it gets about as close as we can to `doing the intuitive thing' when a someone uses the simple face customization -- it's really impossible to always do things correctly, since we'd have to read the user's mind. The user who operates at that level won't be shown, and may not know, at which level the various attributes were specified. If person changes two attributes, and one change affects all terminals while the other does not, that will be a surprise. Here is an idea. Let's eliminate the concept of nested or "common" attribute specs, and make the list look like a simple cond. However, the face to inherit from should be unconditional. Thus, when you want common attributes for face A in various conditions, you put them in another face B and make A inherit from B. This way, either all the attributes specified directly in face A are general or all are specific to a particular kind of terminal. Thus, customizing A is a simple matter, and its behavior is clear. In terms of the actual features of defface, this is almost a return to the way it was a year ago. However, using the inheritance we can get the effect of nesting of specifications. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-09 1:25 ` Miles Bader 2002-07-09 18:51 ` Richard Stallman @ 2002-07-09 18:51 ` Richard Stallman 2002-07-09 20:52 ` Stefan Monnier 1 sibling, 1 reply; 33+ messages in thread From: Richard Stallman @ 2002-07-09 18:51 UTC (permalink / raw) Cc: abraham, emacs-devel It depends on how buffer-local face definitions are implemented. My feeling is that there _shouldn't_ be real buffer-specific faces, but rather a way of remapping faces within a buffer. Face remapping sounds like a convenient interface for this job. It also should be easy to implement. Meanwhile, what do we really want in regard to frame-specific attributes? We want to have faces look different on different kinds of terminals. The method we use to specify this is the specs in defface. That feature should remain. But is there any use for functions to set face attributes per frame? I see none. Maybe we should eliminate that feature. If we ever want to provide such a feature in the future, we could provide per-frame face remapping like the per-buffer face remapping. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-09 18:51 ` Richard Stallman @ 2002-07-09 20:52 ` Stefan Monnier 2002-07-10 19:20 ` Richard Stallman 0 siblings, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2002-07-09 20:52 UTC (permalink / raw) Cc: miles, abraham, emacs-devel > defface. That feature should remain. But is there any use for > functions to set face attributes per frame? I actually realized yesterday that I use this feature for my minibuffer-frame by setting its font and background differently (which in turns sets the frame-local value of the `default' face). (setq minibuffer-frame-alist '((minibuffer . only) (top . -1) (left . 0) (user-position . t) (height . 1) (width . 256) (user-size . t) (vertical-scroll-bars . nil) (menu-bar-lines . 0) (tool-bar-lines . 0) (font . "-misc-fixed-bold-r-normal-*-*-100-100-100-*-*-*-*") (background-color . "grey75") (name . "emacs-minibuffer"))) I wouldn't care too much about losing this feature (although I like the grey background for it). Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-09 20:52 ` Stefan Monnier @ 2002-07-10 19:20 ` Richard Stallman 2002-07-11 17:01 ` Stefan Monnier 0 siblings, 1 reply; 33+ messages in thread From: Richard Stallman @ 2002-07-10 19:20 UTC (permalink / raw) Cc: miles, abraham, emacs-devel If we have buffer-specific face attributes, or buffer-specific face redirections, you could use them to give the minibuffer different faces. Do you ever create a minibuffer window that is part of a larger frame? If you do, would you be unhappy if the special face definitions that you use for the minibuffer were effective there too? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-10 19:20 ` Richard Stallman @ 2002-07-11 17:01 ` Stefan Monnier 2002-07-12 1:28 ` Miles Bader 2002-07-12 17:37 ` Richard Stallman 0 siblings, 2 replies; 33+ messages in thread From: Stefan Monnier @ 2002-07-11 17:01 UTC (permalink / raw) Cc: monnier+gnu/emacs, miles, abraham, emacs-devel > If we have buffer-specific face attributes, or buffer-specific face > redirections, you could use them to give the minibuffer different faces. How would we do that ? As part of the creation of the " *minibuffer-N*" buffers ? What about the echo area ? > Do you ever create a minibuffer window that is part of a larger frame? No. > If you do, would you be unhappy if the special face > definitions that you use for the minibuffer were effective there too? No. Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-11 17:01 ` Stefan Monnier @ 2002-07-12 1:28 ` Miles Bader 2002-07-12 17:37 ` Richard Stallman 1 sibling, 0 replies; 33+ messages in thread From: Miles Bader @ 2002-07-12 1:28 UTC (permalink / raw) Cc: Richard Stallman, abraham, emacs-devel "Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes: > > If we have buffer-specific face attributes, or buffer-specific face > > redirections, you could use them to give the minibuffer different faces. > > How would we do that ? As part of the creation of the " *minibuffer-N*" > buffers ? What about the echo area ? In my scheme, which uses a variable (call it `face-mappings') to do face remappings in buffers, there could be a special variable `echo-area-face-mappings' to handle the echo area. Perhaps minibuffers should inherit the contents of that variable as the initial value for their `face-mappings' variable, which would make the keep the appearance of the echo-area/minibuffer consistent, or maybe their should be an independent `minibuffer-face-mappings' variable. In any case, more specific customizations can be done using `minibuffer-setup-hook'. -Miles -- P.S. All information contained in the above letter is false, for reasons of military security. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-07-11 17:01 ` Stefan Monnier 2002-07-12 1:28 ` Miles Bader @ 2002-07-12 17:37 ` Richard Stallman 1 sibling, 0 replies; 33+ messages in thread From: Richard Stallman @ 2002-07-12 17:37 UTC (permalink / raw) Cc: monnier+gnu/emacs, miles, abraham, emacs-devel How would we do that ? As part of the creation of the " *minibuffer-N*" buffers ? We could say that each new minibuffer copies the face redirections of the first minibuffer. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-20 3:12 reducing defface redundancy Miles Bader 2002-04-20 7:14 ` Eli Zaretskii 2002-04-20 15:59 ` Per Abrahamsen @ 2002-04-21 20:02 ` Richard Stallman 2002-04-22 0:28 ` Miles Bader 2 siblings, 1 reply; 33+ messages in thread From: Richard Stallman @ 2002-04-21 20:02 UTC (permalink / raw) Cc: emacs-devel The basic idea is to allow using a lisp vector ([...]) as a kind of `or' expression in the attribute part of a defface clause. Your proposal makes a number of other changes; is this the best way to do all of them? I don't see how an "or" construct would be a kind of clause: CLAUSE ::= ATTRIBUTE | (TESTS CLAUSE...) ; traditional top-level style | [SPECS ...] ; `or' vector style Shouldn't it be a kind of TEST instead? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-21 20:02 ` Richard Stallman @ 2002-04-22 0:28 ` Miles Bader 2002-04-22 22:37 ` Richard Stallman 0 siblings, 1 reply; 33+ messages in thread From: Miles Bader @ 2002-04-22 0:28 UTC (permalink / raw) Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > The basic idea is to allow using a lisp vector ([...]) as a kind of `or' > expression in the attribute part of a defface clause. > > Your proposal makes a number of other changes; > is this the best way to do all of them? > > I don't see how an "or" construct would be a kind of clause: > > CLAUSE ::= ATTRIBUTE > | (TESTS CLAUSE...) ; traditional top-level style > | [SPECS ...] ; `or' vector style > > Shouldn't it be a kind of TEST instead? Well, it's not really an `or' in the exact same sense as a typical or function used in lisp, say. It's more like the alternatives used for a prolog rule or something, it tries each element in order until it finds out that is `supportable'. So a user can just write: [ALTERNATIVE1 ALTERNATIVE2 ... DEFAULT] and the lisp code will effectively say `does the display support all the attributes ALTERNATIVE1? If so, lets use that. If not, does the display support all the attributes in ALTERNATIVE2? ...' etc. I think this often _exactly_ what people are actually _thinking_ when they design a defface spec (they want a certain effect for the face, and can think of several physical appearances that might convey it). [Note that the I've suggested adding the `capability testing' as a traditional TEST as well, in case someone wants to use that instead.] I do think, BTW, that the ability to write non-conditional defface specs with this grammar is a benefit, since I always get annoyed that I've got to stick in the ((t ...)) crap even when I know I don't need any tests... :-) -Miles -- Would you like fries with that? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: reducing defface redundancy 2002-04-22 0:28 ` Miles Bader @ 2002-04-22 22:37 ` Richard Stallman 0 siblings, 0 replies; 33+ messages in thread From: Richard Stallman @ 2002-04-22 22:37 UTC (permalink / raw) Cc: emacs-devel So a user can just write: [ALTERNATIVE1 ALTERNATIVE2 ... DEFAULT] and the lisp code will effectively say `does the display support all the attributes ALTERNATIVE1? If so, lets use that. If not, does the display support all the attributes in ALTERNATIVE2? ...' etc. I see. This is certainly a convenient thing to do in Lisp terms. And this, by itself, would not pose a problem for Custom. What does pose a problem for Custom is the nesting of constructs that you also propose to add. ^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2002-07-12 17:37 UTC | newest] Thread overview: 33+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2002-04-20 3:12 reducing defface redundancy Miles Bader 2002-04-20 7:14 ` Eli Zaretskii 2002-04-20 15:59 ` Per Abrahamsen 2002-04-20 17:35 ` Eli Zaretskii 2002-04-21 9:12 ` Per Abrahamsen 2002-04-20 17:41 ` Alex Schroeder 2002-04-21 2:00 ` Miles Bader 2002-04-21 9:17 ` Per Abrahamsen 2002-04-21 9:34 ` Miles Bader 2002-04-22 7:47 ` Richard Stallman 2002-04-22 7:47 ` Richard Stallman 2002-04-22 8:15 ` Miles Bader 2002-04-23 0:24 ` Richard Stallman 2002-04-23 1:36 ` Miles Bader 2002-04-24 17:54 ` Richard Stallman 2002-04-24 20:06 ` Miles Bader 2002-04-25 9:52 ` Per Abrahamsen 2002-04-26 3:18 ` Richard Stallman 2002-07-03 6:38 ` Miles Bader 2002-07-03 9:31 ` Kai Großjohann 2002-07-03 14:50 ` Kim F. Storm 2002-07-08 18:20 ` Richard Stallman 2002-07-09 1:25 ` Miles Bader 2002-07-09 18:51 ` Richard Stallman 2002-07-09 18:51 ` Richard Stallman 2002-07-09 20:52 ` Stefan Monnier 2002-07-10 19:20 ` Richard Stallman 2002-07-11 17:01 ` Stefan Monnier 2002-07-12 1:28 ` Miles Bader 2002-07-12 17:37 ` Richard Stallman 2002-04-21 20:02 ` Richard Stallman 2002-04-22 0:28 ` Miles Bader 2002-04-22 22:37 ` Richard Stallman
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).