| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An extent is a region of text (a start position and an end position) that is displayed in a particular face and can have certain other properties such as being read-only. Extents can overlap each other. XEmacs efficiently handles buffers with large numbers of extents in them.
t if object is an extent.
| 47.1 Introduction to Extents | Extents are regions over a buffer or string. | |
| 47.2 Creating and Modifying Extents | Basic extent functions. | |
| 47.3 Extent Endpoints | Accessing and setting the bounds of an extent. | |
| 47.4 Finding Extents | Determining which extents are in an object. | |
| 47.5 Mapping Over Extents | More sophisticated functions for extent scanning. | |
| 47.6 Properties of Extents | Extents have built-in and user-definable properties. | |
| 47.7 Detached Extents | Extents that are not in a buffer. | |
| 47.8 Extent Parents | Inheriting properties from another extent. | |
| 47.9 Duplicable Extents | Extents can be marked to be copied into strings. | |
| 47.10 Interaction of Extents with Keyboard and Mouse Events | Extents can interact with the keyboard and mouse. | |
| 47.11 Atomic Extents | Treating a block of text as a single entity. |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An extent is a region of text within a buffer or string that has certain properties associated with it. The properties of an extent primarily affect the way the text contained in the extent is displayed. Extents can freely overlap each other in a buffer or string. Extents are invisible to functions that merely examine the text of a buffer or string.
Please note: An alternative way to add properties to a buffer or string is to use text properties. See section 43.18 Text Properties.
An extent is logically a Lisp object consisting of a start position,
an end position, a buffer or string to which these positions refer, and
a property list. As text is inserted into a buffer, the start and end
positions of the extent are automatically adjusted as necessary to keep
the extent referring to the same text in the buffer. If text is
inserted at the boundary of an extent, the extent's start-open
and end-open properties control whether the text is included as
part of the extent. If the text bounded by an extent is deleted, the
extent becomes detached; its start and end positions are no longer
meaningful, but it maintains all its other properties and can later be
reinserted into a buffer. (None of these considerations apply to strings,
because text cannot be inserted into or deleted from a string.)
Each extent has a face or list of faces associated with it, which
controls the way in which the text bounded by the extent is displayed.
If an extent's face is nil or its properties are partially
undefined, the corresponding properties from the default face for the
frame is used. If two or more extents overlap, or if a list of more
than one face is specified for a particular extent, the corresponding
faces are merged to determine the text's displayed properties. Every
extent has a priority that determines which face takes precedence
if the faces conflict. (If two extents have the same priority, the one
that comes later in the display order takes precedence. See section display order.) Higher-numbered priority values correspond
to a higher priority, and priority values can be negative. Every extent
is created with a priority of 0, but this can be changed with
set-extent-priority. Within a single extent with a list of faces,
faces earlier in the list have a higher priority than faces later in
the list.
Extents can be set to respond specially to key and mouse events within
the extent. An extent's keymap property controls the effect of
key and mouse strokes within the extent's text, and the mouse-face
property controls whether the extent is highlighted when the mouse moves
over it. See section 47.10 Interaction of Extents with Keyboard and Mouse Events.
An extent can optionally have a begin-glyph or end-glyph associated with it. A begin-glyph or end-glyph is a pixmap or string that will be displayed either at the start or end of an extent or in the margin of the line that the start or end of the extent lies in, depending on the extent's layout policy. Begin-glyphs and end-glyphs are used to implement annotations, and you should use the annotation API functions in preference to the lower-level extent functions. For more information, See section 51. Annotations.
If an extent has its detachable property set, it will become
detached (i.e. no longer in the buffer) when all its text is
deleted. Otherwise, it will simply shrink down to zero-length and
sit in the same place in the buffer. By default, the detachable
property is set on newly-created extents. See section 47.7 Detached Extents.
If an extent has its duplicable property set, it will be
remembered when a string is created from text bounded by the extent.
When the string is re-inserted into a buffer, the extent will also
be re-inserted. This mechanism is used in the kill, yank, and undo
commands. See section 47.9 Duplicable Extents.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
nil, and in this case
buffer-or-string defaults to nil, meaning the extent is in
no buffer or string (see section 47.7 Detached Extents).
detach-extent.
See section 47.7 Detached Extents.
nil, this means that the extent is detached;
however, a detached extent will not necessarily return a value of
nil.
t if object is an extent that has not
been deleted, and nil otherwise.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Every extent has a start position and an end position, and logically
affects the characters between those positions. Normally the start and
end positions must both be valid positions in the extent's buffer or
string. However, both endpoints can be nil, meaning the extent
is detached. See section 47.7 Detached Extents.
Whether the extent overlaps its endpoints is governed by its
start-open and end-open properties. Insertion of a
character at a closed endpoint will expand the extent to include that
character; insertion at an open endpoint will not. Similarly, functions
such as extent-at that scan over all extents overlapping a
particular position will include extents with a closed endpoint at that
position, but not extents with an open endpoint.
Note that the start-closed and end-closed properties are
equivalent to start-open and end-open with the opposite
sense.
Both endpoints can be equal, in which case the extent includes no
characters but still exists in the buffer or string. Zero-length
extents are used to represent annotations (see section 51. Annotations) and can
be used as a more powerful form of a marker. Deletion of all the
characters in an extent may or may not result in a zero-length extent;
this depends on the detachable property (see section 47.7 Detached Extents). Insertion at the position of a zero-length extent expands
the extent if both endpoints are closed; goes before the extent if it
has the start-open property; and goes after the extent if it has
the end-open property. Zero-length extents with both the
start-open and end-open properties are treated as if their
starting point were closed. Deletion of a character on a side of a
zero-length extent whose corresponding endpoint is closed causes the
extent to be detached if its detachable property is set; if the
corresponding endpoint is open, the extent remains in the buffer, moving
as necessary.
Extents are ordered within a buffer or string by increasing start position, and then by decreasing end position (this is called the display order).
0. If the extent is not
detached, this is equivalent to
(- (extent-end-position extent) (extent-start-position extent)) |
nil, this is equivalent
to detach-extent.
buffer-or-string specifies the new buffer or string that the
extent should be in, and defaults to extent's buffer or
string. (If nil, and extent is in no buffer and no string,
it defaults to the current buffer.)
See documentation on detach-extent for a discussion of undo
recording.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following functions provide a simple way of determining the extents in a buffer or string. A number of more sophisticated primitives for mapping over the extents in a range of a buffer or string are also provided (see section 47.5 Mapping Over Extents). When reading through this section, keep in mind the way that extents are ordered (see section 47.3 Extent Endpoints).
More specifically, if a range is specified using from and to, only extents that overlap the range (i.e. begin or end inside of the range) are included in the list. from and to default to the beginning and end of buffer-or-string, respectively.
flags controls how end cases are treated. For a discussion of
this, and exactly what "overlap" means, see map-extents.
The optional arguments property and value can be used to
further restrict which extents are returned. They have the same meaning
as for map-extents.
If you want to map a function over the extents in a buffer or string,
consider using map-extents or mapcar-extents instead.
See also the function extents-at.
Functions that create extents must be prepared for the possibility that there are other extents in the same area, created by other functions. To deal with this, functions typically mark their own extents by setting a particular property on them. The following function makes it easier to locate those extents.
nil, meaning that
any extent will do. Returns nil if there is no matching extent
at pos. If the fourth argument before is not nil, it
must be an extent; any returned extent will precede that extent. This
feature allows extent-at to be used by a loop over extents.
at-flag controls how end cases are handled (i.e. what "at" really means), and should be one of:
nil
after
before
at
Note that in all cases, the start-openness and end-openness of the
extents considered is ignored. If you want to pay attention to those
properties, you should use map-extents, which gives you more
control.
The following low-level functions are provided for explicitly
traversing the extents in a buffer according to the display order.
These functions are mostly intended for debugging--in normal
operation, you should probably use mapcar-extents or
map-extents, or loop using the before argument to
extent-at, rather than creating a loop using next-extent.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The most basic and general function for mapping over extents is called
map-extents. You should read through the definition of this
function to familiarize yourself with the concepts and optional
arguments involved. However, in practice you may find it more
convenient to use the function mapcar-extents or to create a loop
using the before argument to extent-at (see section 47.4 Finding Extents).
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
start-open
all-extents-closed
all-extents-open
all-extents-closed-open
all-extents-open-closed
start-in-region
end-in-region
start-and-end-in-region
start-or-end-in-region
negate-in-region
*-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.
If you want to map over extents and accumulate a list of results,
the following function may be more convenient than map-extents.
map-extents.
map-extents, but differs in that:
Thus, this function may be used to walk a tree of extents in a buffer:
(defun walk-extents (buffer &optional ignore) (map-extent-children 'walk-extents buffer)) |
t if map-extents would visit
extent if called with the given arguments.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each extent has a property list associating property names with
values. Some property names have predefined meanings, and can usually
only assume particular values. Assigning other values to such a
property either cause the value to be converted into a legal value
(e.g., assigning anything but nil to a Boolean property will
cause the value of t to be assigned to the property) or will
cause an error. Property names without predefined meanings can be
assigned any value. An undefined property is equivalent to a property
with a value of nil, or with a particular default value in the
case of properties with predefined meanings. Note that, when an extent
is created, the end-open and detachable properties are set
on it.
If an extent has a parent, all of its properties actually derive from that parent (or from the root ancestor if the parent in turn has a parent), and setting a property of the extent actually sets that property on the parent. See section 47.8 Extent Parents.
nil (or the default value, for properties
with predefined meanings).
The following table lists the properties with predefined meanings, along with their allowable values.
detached
detach-extent. See section 47.7 Detached Extents.
destroyed
delete-extent.
priority
set-extent-priority and accessed with extent-priority.
start-open
start-closed
start-open but with the opposite sense. Setting
this property clears start-open and vice-versa.
end-open
t by default.
See section 47.3 Extent Endpoints.
end-closed
end-open but with the opposite sense. Setting
this property clears end-open and vice-versa.
read-only
face
nil) The face
in which to display the extent's text. This property can also be set
with set-extent-face and accessed with extent-face.
Note that if a list of faces is specified, the faces are merged together,
with faces earlier in the list having priority over faces later in the
list.
mouse-face
nil) The face
used to display the extent when the mouse moves over it. This property
can also be set with set-extent-mouse-face and accessed with
extent-mouse-face. Note that if a list of faces is specified,
the faces are merged together, with faces earlier in the list having
priority over faces later in the list. See section 47.10 Interaction of Extents with Keyboard and Mouse Events.
pointer
text-pointer-glyph
and nontext-pointer-glyph variables. If for any reason this
glyph is an invalid pointer, the standard glyphs will be used as
fallbacks. See section 50.3.5 External Glyphs.
detachable
t by default. See section 47.7 Detached Extents.
duplicable
unique
duplicable.
When this is set, there may be only one instance of
this extent attached at a time. See section 47.9 Duplicable Extents.
invisible
t, text under this extent will not be displayed --
it will look as if the text and the begin-glyph is not there at all.
The end-glyph will still be displayed.
keymap
nil) This keymap is consulted for mouse clicks on this
extent or keypresses made while point is within the extent.
See section 47.10 Interaction of Extents with Keyboard and Mouse Events.
copy-function
paste-function
begin-glyph
nil) This extent's begin glyph.
See section 51. Annotations.
end-glyph
nil) This extent's end glyph.
See section 51. Annotations.
begin-glyph-layout
text, whitespace, inside-margin, or
outside-margin) The layout policy for this extent's begin glyph.
Defaults to text. See section 51. Annotations.
end-glyph-layout
text, whitespace, inside-margin, or
outside-margin) The layout policy for this extent's end glyph.
Defaults to text. See section 51. Annotations.
initial-redisplay-function
This is used by lazy-shot to implement lazy font-locking. The
functionality is still experimental, and may change without further
notice.
The following convenience functions are provided for accessing particular properties of an extent.
face property of extent. This
might also return a list of face names. Do not modify this list
directly! Instead, use set-extent-face.
Note that you can use eq to compare lists of faces as returned
by extent-face. In other words, if you set the face of two
different extents to two lists that are equal but not eq,
then the return value of extent-face on the two extents will
return the identical list.
mouse-face property of extent.
This might also return a list of face names. Do not modify this list
directly! Instead, use set-extent-mouse-face.
Note that you can use eq to compare lists of faces as returned
by extent-mouse-face, just like for extent-face.
priority property of extent.
keymap property of extent.
begin-glyph-layout property of
extent, i.e. the layout policy associated with the extent's
begin glyph.
end-glyph-layout property of
extent, i.e. the layout policy associated with the extent's
end glyph.
begin-glyph property of extent,
i.e. the glyph object displayed at the beginning of extent. If
there is none, nil is returned.
end-glyph property of extent,
i.e. the glyph object displayed at the end of extent. If
there is none, nil is returned.
The following convenience functions are provided for setting particular properties of an extent.
priority property of extent to
priority.
face property of extent to
face.
mouse-face property of extent to
face.
keymap property of extent to
keymap. keymap must be either a keymap object, or
nil.
begin-glyph-layout property of
extent to layout.
end-glyph-layout property of
extent to layout.
begin-glyph and glyph-layout
properties of extent to begin-glyph and layout,
respectively. (layout defaults to text if not specified.)
end-glyph and glyph-layout
properties of extent to end-glyph and layout,
respectively. (layout defaults to text if not specified.)
initial-redisplay-function property of the
extent to function.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A detached extent is an extent that is not attached to a buffer or
string but can be re-inserted. Detached extents have a start position
and end position of nil. Extents can be explicitly detached
using detach-extent. An extent is also detached when all of its
characters are all killed by a deletion, if its detachable
property is set; if this property is not set, the extent becomes a
zero-length extent. (Zero-length extents with the detachable
property set behave specially. See section zero-length extents.)
duplicable property, its detachment is
tracked by the undo mechanism. See section 47.9 Duplicable Extents.
nil if extent is detached, and
t otherwise.
nil).
copy-extent. This function operates the same as if insert
were called on a string whose extent data calls for extent to be
inserted, except that if no-hooks is non-nil,
extent's paste-function will not be invoked.
See section 47.9 Duplicable Extents.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An extent can have a parent extent set for it. If this is the case, the extent derives all its properties from that extent and has no properties of its own. The only "properties" that the extent keeps are the buffer or string it refers to and the start and end points. (More correctly, the extent's own properties are shadowed. If you later change the extent to have no parent, its own properties will become visible again.)
It is possible for an extent's parent to itself have a parent, and so on. Through this, a whole tree of extents can be created, all deriving their properties from one root extent. Note, however, that you cannot create an inheritance loop--this is explicitly disallowed.
Parent extents are used to implement the extents over the modeline.
nil, the extent is set to have no parent.
nil.
extent-children
to any children of extent, until no more children can be found.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If an extent has the duplicable property, it will be copied into
strings, so that kill, yank, and undo commands will restore or copy it.
Specifically:
buffer-substring or
buffer-string, any duplicable extents in the region corresponding
to the string will be copied into the string (see section 43.2 Examining Buffer Contents). When the string is inserted into a buffer using
insert, insert-before-markers, insert-buffer or
insert-buffer-substring, the extents in the string will be copied
back into the buffer (see section 43.4 Inserting Text). The extents in a string can,
of course, be retrieved explicitly using the standard extent primitives
over the string.
concat is called on strings, the extents in the strings are
copied into the resulting string.
subseq (or its alias, substring) is called on a
string, the relevant extents are copied into the resulting string.
detach-extent or string
deletion, or inserted by insert-extent or string insertion, the
action is recorded by the undo mechanism so that it can be undone later.
Note that if an extent gets detached and then a later undo causes the
extent to get reinserted, the new extent will not be `eq' to the original
extent.
make-extent are
not recorded by the undo mechanism. This means that extent changes
which are to be undo-able must be performed by character editing, or by
insertion and detachment of duplicable extents.
copy-function property, if non-nil,
should be a function, and will be run when a duplicable extent is about
to be copied from a buffer to a string (or the kill ring). It is called
with three arguments: the extent and the buffer positions within it
which are being copied. If this function returns nil, then the
extent will not be copied; otherwise it will.
paste-function property, if non-nil,
should be a function, and will be run when a duplicable extent is about
to be copied from a string (or the kill ring) into a buffer. It is
called with three arguments: the original extent and the buffer
positions which the copied extent will occupy. (This hook is run after
the corresponding text has already been inserted into the buffer.) Note
that the extent argument may be detached when this function is run. If
this function returns nil, no extent will be inserted.
Otherwise, there will be an extent covering the range in question.
Note: if the extent to be copied is already attached to the buffer and
overlaps the new range, the extent will simply be extended and the
paste-function will not be called.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If an extent has the mouse-face property set, it will be
highlighted when the mouse passes over it. This includes the
begin-glyph, but not the end-glyph. Highlighting is accomplished by
merging the extent's face with the face or faces specified by the
mouse-face property. The effect is as if a pseudo-extent with
the mouse-face face were inserted after the extent in the display
order (see section 47.3 Extent Endpoints, display order).
You can also explicitly cause an extent to be highlighted. Only one extent at a time can be highlighted in this fashion, and any other highlighted extent will be de-highlighted.
nil) or
de-highlights (if highlight-p is nil) extent, if
extent has the mouse-face property. (Nothing happens if
extent does not have the mouse-face property.)
highlight-extent but highlights
or de-highlights the extent regardless of whether it has the
mouse-face property.
If an extent has a keymap property, this keymap will be
consulted for mouse clicks on the extent and keypresses made while
point is within the extent. The behavior of mouse clicks and
keystrokes not defined in the keymap is as normal for the buffer.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If the Lisp file `atomic-extents' is loaded, then the atomic
extent facility is available. An atomic extent is an extent for
which point cannot be positioned anywhere within it. This
ensures that when selecting text, either all or none of the extent is
selected.
To make an extent atomic, set its atomic property.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |