From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: "Wedler, Christoph" Newsgroups: gmane.emacs.devel Subject: RE: [Feature request] face property `raise' Date: Tue, 29 Apr 2003 20:19:12 +0200 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <67B8CED503F3D511BB9F0008C75DAD66054855B9@dewdfx17> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Trace: main.gmane.org 1051640626 15222 80.91.224.249 (29 Apr 2003 18:23:46 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Tue, 29 Apr 2003 18:23:46 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Tue Apr 29 20:23:41 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19AZjR-0003ip-00 for ; Tue, 29 Apr 2003 20:21:33 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 19AZsC-0004MH-00 for ; Tue, 29 Apr 2003 20:30:36 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.10.13) id 19AZji-0007Rh-05 for emacs-devel@quimby.gnus.org; Tue, 29 Apr 2003 14:21:50 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.10.13) id 19AZip-0007M7-00 for emacs-devel@gnu.org; Tue, 29 Apr 2003 14:20:55 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10.13) id 19AZhi-0006Vk-00 for emacs-devel@gnu.org; Tue, 29 Apr 2003 14:19:48 -0400 Original-Received: from smtpde02.sap-ag.de ([155.56.68.170]) by monty-python.gnu.org with esmtp (Exim 4.10.13) id 19AZhM-0006GA-00; Tue, 29 Apr 2003 14:19:24 -0400 Original-Received: from sap-ag.de (smtpde02) by smtpde02.sap-ag.de (out) with ESMTP id UAA11265; Tue, 29 Apr 2003 20:19:37 +0200 (MESZ) Original-To: "'rms@gnu.org'" X-Mailer: Internet Mail Service (5.5.2656.59) X-SAP: out X-SAP: out Original-cc: ihs_4664@yahoo.com X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1b5 Precedence: list List-Id: Emacs development discussions. List-Help: List-Post: List-Subscribe: , List-Archive: List-Unsubscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:13554 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:13554 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 , 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 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