Previous
|
Up
|
Next
|
Getting Text from a Buffer |
Primitives and EEL Subroutines |
Narrowing |
Epsilon User's Manual and Reference >
Primitives and EEL Subroutines >
Buffer Primitives >
Spots
spot alloc_spot(?int left_ins)
free_spot(spot sp)
int spot_to_buffer(spot sp)
A place in the buffer is usually recorded and saved for
later use as a count of the characters before that place: this is a
position, as described in Changing Buffer Contents. Sometimes it is
important for the stored location to remain between the same pair of
characters even if many changes are made to other parts of the buffer
(affecting the number of characters before the saved location).
Epsilon provides a type of variable called a spot for
this situation. The declaration
spot sp;
says that sp can refer to a spot. It doesn't create a new
spot itself, though.
The alloc_spot( ) primitive creates a new spot and returns it,
and the free_spot( ) primitive takes a spot and discards it.
The spot that alloc_spot( ) returns is initially set to point,
and is associated with the current buffer. Deleting a buffer frees
all spots associated with it. If you try to free a spot whose buffer
has already been deleted, Epsilon will ignore the request, and will
not signal an error.
The spot_to_buffer( ) primitive takes a spot and returns the
buffer number it was created for, or -1 if the buffer no longer
exists, or -2 if the buffer exists, but that particular spot has
since been deleted.
If the left_ins parameter to alloc_spot( ) is nonzero, a
left-inserting spot is created. If the left_ins parameter is 0 ,
or is omitted, a right-inserting spot is created. The only
difference between the two types of spots is what they do when
characters are inserted right where the spot is. A left-inserting
spot stays after such inserted characters, while a right-inserting
spot stays before them. For example, imagine an empty buffer, with
all spots at 0. After five characters are inserted, any
left-inserting spots will be at the end of the buffer, while
right-inserting spots will remain at the beginning.
A spot as returned by alloc_spot( ) behaves a little like a
pointer to an int, in that you must dereference it by writing
*sp to obtain the position it currently refers to. For example:
fill_all() /* fill paragraphs, leave point alone */
{
spot oldpos = alloc_spot(), oldmark = alloc_spot();
*oldpos = point;
*oldmark = mark; /* save old values */
point = 0; /* make region be whole buffer */
mark = size();
fill_region(); /* fill paragraphs in region */
mark = *oldmark; /* restore values */
point = *oldpos;
free_spot(oldmark); /* free saving places */
free_spot(oldpos);
}
A simpler way to write the above subroutine uses EEL's
save_spot keyword. The save_spot keyword takes care of
allocating spots, saving the original values, and restoring those
values when the subroutine exits. See Save_var Statements for
more on save_spot .
fill_all() /* fill paragraphs, leave point alone */
{ /* uses save_spot */
save_spot point = 0; /* make region be whole buffer */
save_spot mark = size();
fill_region(); /* fill paragraphs in region */
}
Like a pointer, a spot variable can contain zero, and
alloc_spot( ) is guaranteed never to return this value. Epsilon
signals an error if you try to dereference a spot which has been
freed, or whose buffer no longer exists.
buffer spot point_spot;
buffer spot mark_spot;
#define point *point_spot
#define mark *mark_spot
/* These variables are actually defined
differently. See below. */
Each new buffer begins with two spots, point_spot and
mark_spot, set to the beginning of the buffer.
Point_spot is a left-inserting spot, while mark_spot is a
right-inserting spot. These spots are created automatically with
each new buffer, and you cannot free them. You can think of the
built-in variables point and mark as simply macros that
yield *point_spot and *mark_spot , respectively. That's why
you don't need to put a * before each reference to point.
user buffer int point; /* True definitions */
user buffer int mark;
spot get_spot(int which)
#define point_spot get_spot(0)
#define mark_spot get_spot(1)
Actually, while point and mark could be defined as macros,
as above, they're not. Epsilon recognizes them as built-in
primitives for speed. On the other hand, point_spot and
mark_spot actually are macros! They use the get_spot( )
primitive, which has no function other than to return these two
values.
do_set_mark(int val)
The do_set_mark( ) subroutine sets the current buffer's mark to
the specified value. It also records the current virtual column
(which, typically, should match the mark). The rectangle commands
retrieve this, so that in virtual mode you can copy rectangles that
end in virtual space.
set_spot(spot *s, int pos)
The set_spot( ) subroutine sets a spot so it refers to the
position pos in the current buffer. Pass it the address of a spot
variable. If the spot is zero or refers to a different buffer, the
subroutine will create a new right-inserting spot in the current
buffer, freeing the old spot.
Previous
|
Up
|
Next
|
Getting Text from a Buffer |
Primitives and EEL Subroutines |
Narrowing |
Epsilon Programmer's Editor 14.04 manual. Copyright (C) 1984, 2021 by Lugaru Software Ltd. All rights reserved.
|