[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
reducing defface redundancy
From: |
Miles Bader |
Subject: |
reducing defface redundancy |
Date: |
20 Apr 2002 12:12:57 +0900 |
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
- reducing defface redundancy,
Miles Bader <=