From: "Wedler, Christoph" <christoph.wedler@sap.com>
Cc: emacs-devel@gnu.org
Subject: RE: [Feature request] face property `raise'
Date: Tue, 29 Apr 2003 20:19:12 +0200 [thread overview]
Message-ID: <67B8CED503F3D511BB9F0008C75DAD66054855B9@dewdfx17> (raw)
rms@gnu.org writes:
> A. Don't define different groups of different properties: make all
> properties text properties (or group all special = non-user-defined
> text properties together)
> B. Just provide one abstraction mechanism for all special properties
> with the ability to merge the abstract properties (like face
> merging).
> That is an interesting idea. Could you try writing a precise
> spec for what it would look like?
> One complication will be how to extend face customization to handle an
> unbounded set of properties. Right now there is a fixed set of face
> attributes.
OK, below you find some ideas / a draft about this. It lists potential
problems and possible options how to solve them. Comments welcome.
1. the general mechanism: properties, face merging, priorities of
overlay/text properties, null-value problem
2. property names for built-in properties (used by the display engine),
3. backward compatiblity issues (what to do with the current
properties, especially the properties display/face/category?)
4. face customization
5. implementation
1. GENERAL IDEA ----------------------
The general idea is as follows:
* All properties are "direct" text/overlay properties (as opposed to
the current display specs, face attributes etc)
* One special property (`face') specifies a list of faces (i.e.,
symbols naming the faces). A face serves as an abstraction
mechanism, i.e., defines values for some properties.
As opposed to the current behaviour (new in Emacs-21?), you cannot
specify individual properties with the text property `face', because
this is not needed: face attributes are normal "direct" text/overlay
properties.
Questions considered below:
- face/property merging: a property is defined directly and/or in
more than one face -- which one to choose?
- how does the face/property merging relate with properties
specified by overlays?
- can a face specify the face property? => see 4
* One special property (`mouse-face) defines additional
properties to use when the mouse is "near" the characters with the
`mouse-face property.
A value for the same property can be specified directly and indirectly
via faces. For each character, the value can be specified by a text
property and by a property of overlays which apply to that character.
The question is: what is the "final" value for that property?
Before we discuss that, let's look at the 3 kind of values for a
property:
* Absolute values, like :height 120
* Relative values, like :height 1.2
* not specified = "null value". There are three posibilities how this
can be specified:
i. not specified is different to any specified value. In this
case, `get-text-property' and friends must allow to
distinguish this, i.e., this function must have an optional
DEFAULT argument.
ii. nil = not specified. In this case, we must have specific
FALSE values for boolean properties like :underline (and even
some non-booleans like `image'), e.g., :none.
iii. :null (or some other value) = not specified. In this case
`get-text-property' and friends must return that value if a
properties is not specified
Option ii is IMHO the best and most Emacs-like (there are only a few
boolean-like properties), i would also be OK.
The algorithm which determines the "final" property value to apply for a
given character is as follows.
-----------
final_property (charpos, prop) =
let value1 = if mouse_over (charpos)
then mouse_property (charpos, prop)
else <unspecified>,
value2 = specified_prop (charpos, prop),
value3 = face_property ('default, prop),
value4 = built_in_prop_value (prop)
in
value1 * value2 * value3 * value4
mouse_property (charpos, prop) =
let mouse_face = specified_prop (charpos, 'mouse-face)
in
if mouse_face.specified
then face_property (mouse_face, prop)
else <unspecified>
specified_prop (charpos, prop) =
let values = map (lambda (overlay) =>
object_property (overlay, prop),
overlays_in_priority_order_at (charpos));
in
-- overlay props -- text props
reduce ((*), values) * object_property (charpos, prop)
object_property (charpos_or_overlay, prop) =
let values = map (lambda (face) =>
face_property (face, prop),
direct_property (charpos_or_overlay, 'face))
in
direct_property (charpos_or_overlay, prop) *
reduce ((*), values)
direct_property : built_in
face_property : built_in
value1 * value2 = -- combining values
if value1.absolutep then
value1
elseif value1.unspecifiedp then
value2
elseif (value2.unspecifiedp) then
value1
elseif (value2.absolutep) then
combine_to_absolute_value (value1, value2)
else
combine_to_relative_value (value1, value2)
-----------
Example: let's assume the following line in a buffer
FFFTTTOOOOOTTTFFF
All characters in the line have the following text properties:
- mouse-face = highlight which defines background = green
- face = dark which defines background = grey
The characters TTTOOOOOTTT have the following text properties:
- background = orange
There is an overlay over the OOOOO with the properties:
- face = selection which defines background = yellow
Then we'll see the following background colors:
- if the mouse is over the line, the complete line has a green
background,
- otherwise, the OOOOOs have a yellow background, both TTTs have a
orange background, the rest a grey background
This shows:
- the most important distinction is mouse vs not mouse,
- then: overlay (high prio..low prio) vs text property
- then: direct property vs face properties
2. PROPERTY NAMES -----------
There are properties used by the display engine (built-in properties)
and properties not used by the display engine (user properties).
I see two possibilities for a naming convention for built-in properties
(I do not discuss the individual names of the properties in this mail):
a. :prop-name, i.e. a symbol starting with a colon,
b. prop-name, i.e., another symbol
Currently, text/overlay properties use a, face attribute use b, display
properties use a and space properties (grouped in the display spec
`space') use b.
I would suggest to use b:
- Advantage: more backward compatible (see 3 below),
- Advantage: a package-specific property might become a built-in
property in a future release (e.g., fontified)
- Disadvantage: potential naming conflict of future built-in properties
with user properties (this is already the case in Emacs)
3. BACKWARD COMPATIBILITY -----------
Of course, if things change in this area, we have the problem of old
ELisp coding. The individual problems with possible option:
a. The display property. The options:
i. obsolete, ignore it
ii. obsolete, use it (lower prio than the new direct properties,
but higher than indirect properties via faces)
b. direct face attributes in the face property:
i. setting such a value for the face property is not allowed
(signals an error)
ii. obsolete, such list elements in the value of the face property
are ignored.
iii. obsolete, use it (with prio as it is now)
c. category attribute
i. obsolete, ignore it
ii. obsolete, use the symbol as an additional face (with lowest
prio)
d. changed names of properties: if we use naming convention 1b, we
would be more backward compatible
e. ...
The first options are cleaner and will lead to a faster display engine
and probably easier to implement, the latter options are more backward
compatible.
4. FACE CUSTOMIZATION -----------
If faces serve as a general abstraction mechanism, it must be possible
to customize the corresponding face properties:
- built-in properties can have special support like provided now for
all face attributes
- user properties are stored in an alist/plist (symbol |-> sexpr) and
customized like any variable having such an alist/plist as :type.
We could use the face attribute `face' for the face inherit mechanism.
5. IMPLEMENTATION -----------
Sorry, I cannot say anything here, how much of the current coding can be
reused / has to be rewritten...
- Christoph
next reply other threads:[~2003-04-29 18:19 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-04-29 18:19 Wedler, Christoph [this message]
2003-05-13 1:47 ` [Feature request] face property `raise' Richard Stallman
2003-05-13 2:22 ` Miles Bader
2003-05-14 21:05 ` Richard Stallman
2003-05-13 14:13 ` Stefan Monnier
2003-05-14 21:04 ` Richard Stallman
-- strict thread matches above, loose matches on Subject: below --
2003-05-14 17:45 Wedler, Christoph
2003-05-14 20:57 ` Miles Bader
2003-05-15 15:42 ` Richard Stallman
2003-05-13 17:17 Wedler, Christoph
2003-05-13 21:23 ` Miles Bader
2003-05-14 21:04 ` Richard Stallman
2003-04-11 19:34 Wedler, Christoph
2003-04-13 11:22 ` Richard Stallman
2003-04-10 18:48 Wedler, Christoph
2003-04-10 23:14 ` Kevin Rodgers
2003-04-09 18:06 Wedler, Christoph
2003-04-09 18:50 ` Kai Großjohann
2003-04-10 6:23 ` Richard Stallman
2003-04-08 17:52 Wedler, Christoph
2003-04-08 18:54 ` Kai Großjohann
2003-04-07 17:33 Wedler, Christoph
2003-04-08 6:45 ` Richard Stallman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=67B8CED503F3D511BB9F0008C75DAD66054855B9@dewdfx17 \
--to=christoph.wedler@sap.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).