From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: David Kastrup Newsgroups: gmane.emacs.devel Subject: Re: enriched-mode and switching major modes. Date: Thu, 23 Sep 2004 14:46:10 +0200 Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Message-ID: References: <200409042358.i84Nwjt19152@raven.dms.auburn.edu> <01c49c75$Blat.v2.2.2$7a37cb00@zahav.net.il> <01c49d70$Blat.v2.2.2$f7cfb860@zahav.net.il> <01c49da7$Blat.v2.2.2$cd5f7160@zahav.net.il> <01c49dc6$Blat.v2.2.2$3b624d40@zahav.net.il> Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1CASzq-0008QX-00 for ; Thu, 23 Sep 2004 14:46:51 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CAT5s-0003oy-GC for ged-emacs-devel@m.gmane.org; Thu, 23 Sep 2004 08:53:04 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1CAT5e-0003i0-1R for emacs-devel@gnu.org; Thu, 23 Sep 2004 08:52:50 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1CAT5d-0003hg-7U for emacs-devel@gnu.org; Thu, 23 Sep 2004 08:52:49 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CAT5d-0003hW-0q for emacs-devel@gnu.org; Thu, 23 Sep 2004 08:52:49 -0400 Original-Received: from [199.232.76.164] (helo=fencepost.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.34) id 1CASzN-0007tt-2k for emacs-devel@gnu.org; Thu, 23 Sep 2004 08:46:21 -0400 Original-Received: from localhost ([127.0.0.1] helo=lola.goethe.zz) by fencepost.gnu.org with esmtp (Exim 4.34) id 1CASzF-00053R-6h; Thu, 23 Sep 2004 08:46:13 -0400 Original-To: Stefan In-Reply-To: (Stefan's message of "Thu, 23 Sep 2004 07:35:36 -0400") User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3.50 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:27488 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:27488 Stefan writes: >> Without thinking too much about it, I'd say that overlays seem >> to be a better fit: each node is an overlay, the node's >> attributes can be stored in the overlay's properties, the text >> corresponding to a node can be stored directly in the buffer >> and retrieved by (buffer-substring (overlay-start o) >> (overlay-end o)), ... > >> Overlays are no good for this because they will be lost completely >> if you cut and paste. If you copy the text of a buffer to another >> buffer, the overlays won't come along. (That is the purpose of >> overlays.) > >> This information has to be *part of the text*. > > XEmacs's version of overlays (called extents) can be part of the text > (which is a property they call `duplicable'). We could do the same. Extents are actually used for implementing text properties with XEmacs, if I understand their stuff correctly. They are just extents with a few special properties (like duplicable). So in effect, XEmacs does not force you to decide whether you want to use one or the other: every feature that would be different can be chosen separately with an appropriate property. This simplifies implementation in some circumstances. The main problem I see with the XEmacs model is that they have not bothered overly much to add useful abstractions (like overlays and text properties are) on top of the low-level basics. For example, for getting some properties or overlays at point, you basically have to use the map-extents function, for which I'll append at the end of the posting. There are not really convenience functions like "overlays-at" and similar, since you supposedly can do everything with the likes of map-extents. For keeping the number of internal data structures manageable, the idea is probably not bad, but the practice turns out to be a bit of a nuisance for the typical application programmer. Not because raw power would be missing, but because it turns out to be raw: you have to focus on many details in order to get something that does just what you want. The actual amount of C code underlying the implementation of extents could well be less than the combined code for text properties and overlays in Emacs, and maybe can serve more purposes. Still, the sort of do-everything-for-a-reasonably-complicated-set-of-arguments interface is something that could certainly make use of some more abstractions in the form of Lisp functions accessing it. David `map-extents' is a built-in function (map-extents FUNCTION &optional OBJECT FROM TO MAPARG FLAGS PROPERTY VALUE) Documentation: Map FUNCTION over the extents which overlap a region in OBJECT. OBJECT is normally a buffer or string but could be an extent (see below). The region is normally bounded by [FROM, TO) (i.e. the beginning of the region is closed and the end of the region is open), but this can be changed with the FLAGS argument (see below for a complete discussion). FUNCTION is called with the arguments (extent, MAPARG). The arguments OBJECT, FROM, TO, MAPARG, and FLAGS are all optional and default to the current buffer, the beginning of OBJECT, the end of OBJECT, nil, and nil, respectively. `map-extents' returns the first non-nil result produced by FUNCTION, and no more calls to FUNCTION are made after it returns non-nil. If OBJECT is an extent, FROM and TO default to the extent's endpoints, and the mapping omits that extent and its predecessors. This feature supports restarting a loop based on `map-extents'. Note: OBJECT must be attached to a buffer or string, and the mapping is done over that buffer or string. An extent overlaps the region if there is any point in the extent that is also in the region. (For the purpose of overlap, zero-length extents and regions are treated as closed on both ends regardless of their endpoints' specified open/closedness.) Note that the endpoints of an extent or region are considered to be in that extent or region if and only if the corresponding end is closed. For example, the extent [5,7] overlaps the region [2,5] because 5 is in both the extent and the region. However, (5,7] does not overlap [2,5] because 5 is not in the extent, and neither [5,7] nor (5,7] overlaps the region [2,5) because 5 is not in the region. The optional FLAGS can be a symbol or a list of one or more symbols, modifying the behavior of `map-extents'. Allowed symbols are: end-closed The region's end is closed. start-open The region's start is open. all-extents-closed Treat all extents as closed on both ends for the purpose of determining whether they overlap the region, irrespective of their actual open- or closedness. all-extents-open Treat all extents as open on both ends. all-extents-closed-open Treat all extents as start-closed, end-open. all-extents-open-closed Treat all extents as start-open, end-closed. start-in-region In addition to the above conditions for extent overlap, the extent's start position must lie within the specified region. Note that, for this condition, open start positions are treated as if 0.5 was added to the endpoint's value, and open end positions are treated as if 0.5 was subtracted from the endpoint's value. end-in-region The extent's end position must lie within the region. start-and-end-in-region Both the extent's start and end positions must lie within the region. start-or-end-in-region Either the extent's start or end position must lie within the region. negate-in-region The condition specified by a `*-in-region' flag must NOT hold for the extent to be considered. At most one of `all-extents-closed', `all-extents-open', `all-extents-closed-open', and `all-extents-open-closed' may be specified. At most one of `start-in-region', `end-in-region', `start-and-end-in-region', and `start-or-end-in-region' may be specified. If optional arg PROPERTY is non-nil, only extents with that property set on them will be visited. If optional arg VALUE is non-nil, only extents whose value for that property is `eq' to VALUE will be visited.