emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: enriched-mode and switching major modes.


From: David Kastrup
Subject: Re: enriched-mode and switching major modes.
Date: Thu, 23 Sep 2004 14:46:10 +0200
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3.50 (gnu/linux)

Stefan <address@hidden> 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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]