if (XTYPE (parent) == Lisp_Buffer)
{
- new->total_length = BUF_Z (XBUFFER (parent)) - 1;
+ new->total_length = (BUF_Z (XBUFFER (parent))
+ - BUF_BEG (XBUFFER (parent)));
XBUFFER (parent)->intervals = new;
}
else if (XTYPE (parent) == Lisp_String)
/* i0 and i1 both have sym, but it has different values in each */
i0_cdr = Fcdr (i0_cdr);
- if (! Fequal (i1_val, Fcar (i0_cdr)))
+ if (! EQ (i1_val, Fcar (i0_cdr)))
return 0;
i0_cdr = Fcdr (i0_cdr);
return B;
}
\f
-/* Split INTERVAL into two pieces, starting the second piece at character
- position OFFSET (counting from 1), relative to INTERVAL. The right-hand
- piece (second, lexicographically) is returned.
+/* Split INTERVAL into two pieces, starting the second piece at
+ character position OFFSET (counting from 0), relative to INTERVAL.
+ INTERVAL becomes the left-hand piece, and the right-hand piece
+ (second, lexicographically) is returned.
The size and position fields of the two intervals are set based upon
those of the original interval. The property list of the new interval
{
INTERVAL new = make_interval ();
int position = interval->position;
- int new_length = LENGTH (interval) - offset + 1;
+ int new_length = LENGTH (interval) - offset;
- new->position = position + offset - 1;
+ new->position = position + offset;
new->parent = interval;
if (LEAF_INTERVAL_P (interval) || NULL_RIGHT_CHILD (interval))
return new;
}
-/* Split INTERVAL into two pieces, starting the second piece at character
- position OFFSET (counting from 1), relative to INTERVAL. The left-hand
- piece (first, lexicographically) is returned.
+/* Split INTERVAL into two pieces, starting the second piece at
+ character position OFFSET (counting from 0), relative to INTERVAL.
+ INTERVAL becomes the right-hand piece, and the left-hand piece
+ (first, lexicographically) is returned.
The size and position fields of the two intervals are set based upon
those of the original interval. The property list of the new interval
{
INTERVAL new = make_interval ();
int position = interval->position;
- int new_length = offset - 1;
+ int new_length = offset;
new->position = interval->position;
- interval->position = interval->position + offset - 1;
+ interval->position = interval->position + offset;
new->parent = interval;
if (NULL_LEFT_CHILD (interval))
}
\f
/* Find the interval containing text position POSITION in the text
- represented by the interval tree TREE. POSITION is relative to
- the beginning of that text.
+ represented by the interval tree TREE. POSITION is a buffer
+ position; the earliest position is 1. If POSITION is at the end of
+ the buffer, return the interval containing the last character.
The `position' field, which is a cache of an interval's position,
is updated in the interval found. Other functions (e.g., next_interval)
register INTERVAL tree;
register int position;
{
- register int relative_position = position;
+ /* The distance from the left edge of the subtree at TREE
+ to POSITION. */
+ register int relative_position = position - BEG;
if (NULL_INTERVAL_P (tree))
return NULL_INTERVAL;
- if (position > TOTAL_LENGTH (tree))
+ if (relative_position > TOTAL_LENGTH (tree))
abort (); /* Paranoia */
-#if 0
- position = TOTAL_LENGTH (tree);
-#endif
while (1)
{
- if (relative_position <= LEFT_TOTAL_LENGTH (tree))
+ if (relative_position < LEFT_TOTAL_LENGTH (tree))
{
tree = tree->left;
}
- else if (relative_position > (TOTAL_LENGTH (tree)
- - RIGHT_TOTAL_LENGTH (tree)))
+ else if (! NULL_RIGHT_CHILD (tree)
+ && relative_position >= (TOTAL_LENGTH (tree)
+ - RIGHT_TOTAL_LENGTH (tree)))
{
relative_position -= (TOTAL_LENGTH (tree)
- RIGHT_TOTAL_LENGTH (tree));
}
else
{
- tree->position = LEFT_TOTAL_LENGTH (tree)
- + position - relative_position + 1;
+ tree->position =
+ (position - relative_position /* the left edge of *tree */
+ + LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */
+
return tree;
}
}
if (TOTAL_LENGTH (tree) == 0) /* Paranoia */
abort ();
- /* If inserting at point-max of a buffer, that position
- will be out of range. */
- if (position > TOTAL_LENGTH (tree))
- position = TOTAL_LENGTH (tree);
+ /* If inserting at point-max of a buffer, that position will be out
+ of range. Remember that buffer positions are 1-based. */
+ if (position > BEG + TOTAL_LENGTH (tree))
+ position = BEG + TOTAL_LENGTH (tree);
i = find_interval (tree, position);
/* If we are positioned between intervals, check the stickiness of
both of them. */
if (position == i->position
- && position != 1)
+ && position != BEG)
{
register INTERVAL prev = previous_interval (i);
}
}
\f
-/* Find the interval in TREE corresponding to the character position FROM
- and delete as much as possible of AMOUNT from that interval, starting
- after the relative position of FROM within it. Return the amount
- actually deleted, and if the interval was zeroed-out, delete that
- interval node from the tree.
+/* Find the interval in TREE corresponding to the relative position
+ FROM and delete as much as possible of AMOUNT from that interval.
+ Return the amount actually deleted, and if the interval was
+ zeroed-out, delete that interval node from the tree.
+
+ Note that FROM is actually origin zero, aka relative to the
+ leftmost edge of tree. This is appropriate since we call ourselves
+ recursively on subtrees.
Do this by recursing down TREE to the interval in question, and
deleting the appropriate amount of text. */
return 0;
/* Left branch */
- if (relative_position <= LEFT_TOTAL_LENGTH (tree))
+ if (relative_position < LEFT_TOTAL_LENGTH (tree))
{
int subtract = interval_deletion_adjustment (tree->left,
relative_position,
return subtract;
}
/* Right branch */
- else if (relative_position > (TOTAL_LENGTH (tree)
- - RIGHT_TOTAL_LENGTH (tree)))
+ else if (relative_position >= (TOTAL_LENGTH (tree)
+ - RIGHT_TOTAL_LENGTH (tree)))
{
int subtract;
/* Here -- this node */
else
{
- /* If this is a zero-length, marker interval, then
- we must skip it. */
-
- if (relative_position == LEFT_TOTAL_LENGTH (tree) + 1)
- {
- /* This means we're deleting from the beginning of this interval. */
- register int my_amount = LENGTH (tree);
-
- if (amount < my_amount)
- {
- tree->total_length -= amount;
- return amount;
- }
- else
- {
- tree->total_length -= my_amount;
- if (LENGTH (tree) != 0)
- abort (); /* Paranoia */
-
- delete_interval (tree);
- return my_amount;
- }
- }
- else /* Deleting starting in the middle. */
- {
- register int my_amount = ((tree->total_length
- - RIGHT_TOTAL_LENGTH (tree))
- - relative_position + 1);
-
- if (amount <= my_amount)
- {
- tree->total_length -= amount;
- return amount;
- }
- else
- {
- tree->total_length -= my_amount;
- return my_amount;
- }
- }
+ /* How much can we delete from this interval? */
+ int my_amount = ((tree->total_length
+ - RIGHT_TOTAL_LENGTH (tree))
+ - relative_position);
+
+ if (amount > my_amount)
+ amount = my_amount;
+
+ tree->total_length -= amount;
+ if (LENGTH (tree) == 0)
+ delete_interval (tree);
+
+ return amount;
}
/* Never reach here */
}
-/* Effect the adjustments necessary to the interval tree of BUFFER
- to correspond to the deletion of LENGTH characters from that buffer
- text. The deletion is effected at position START (relative to the
- buffer). */
+/* Effect the adjustments necessary to the interval tree of BUFFER to
+ correspond to the deletion of LENGTH characters from that buffer
+ text. The deletion is effected at position START (which is a
+ buffer position, i.e. origin 1). */
static void
adjust_intervals_for_deletion (buffer, start, length)
if (NULL_INTERVAL_P (tree))
return;
+ if (start > BEG + TOTAL_LENGTH (tree)
+ || start + length > BEG + TOTAL_LENGTH (tree))
+ abort ();
+
if (length == TOTAL_LENGTH (tree))
{
buffer->intervals = NULL_INTERVAL;
return;
}
- if (start > TOTAL_LENGTH (tree))
- start = TOTAL_LENGTH (tree);
+ if (start > BEG + TOTAL_LENGTH (tree))
+ start = BEG + TOTAL_LENGTH (tree);
while (left_to_delete > 0)
{
- left_to_delete -= interval_deletion_adjustment (tree, start,
+ left_to_delete -= interval_deletion_adjustment (tree, start - 1,
left_to_delete);
tree = buffer->intervals;
if (left_to_delete == tree->total_length)
return t;
}
+#if 0
+/* Nobody calls this. Perhaps it's a vestige of an earlier design. */
+
/* Make a new interval of length LENGTH starting at START in the
group of intervals INTERVALS, which is actually an interval tree.
Returns the new interval.
if (slot->position == start)
{
/* New right node. */
- split_interval_right (slot, length + 1);
+ split_interval_right (slot, length);
return slot;
}
if (slot->position + LENGTH (slot) == start + length)
{
/* New left node. */
- split_interval_left (slot, LENGTH (slot) - length + 1);
+ split_interval_left (slot, LENGTH (slot) - length);
return slot;
}
/* Convert interval SLOT into three intervals. */
- split_interval_left (slot, start - slot->position + 1);
- split_interval_right (slot, length + 1);
+ split_interval_left (slot, start - slot->position);
+ split_interval_right (slot, length);
return slot;
}
+#endif
\f
/* Insert the intervals of SOURCE into BUFFER at POSITION.
- This is used in insdel.c when inserting Lisp_Strings into
- the buffer. The text corresponding to SOURCE is already in
- the buffer when this is called. The intervals of new tree are
- those belonging to the string being inserted; a copy is not made.
+ This is used in insdel.c when inserting Lisp_Strings into the
+ buffer. The text corresponding to SOURCE is already in the buffer
+ when this is called. The intervals of new tree are a copy of those
+ belonging to the string being inserted; intervals are never
+ shared.
If the inserted text had no intervals associated, this function
simply returns -- offset_intervals should handle placing the
{
/* The inserted text constitutes the whole buffer, so
simply copy over the interval structure. */
- if (BUF_Z (buffer) == TOTAL_LENGTH (source))
+ if ((BUF_Z (buffer) - BUF_BEG (buffer)) == TOTAL_LENGTH (source))
{
buffer->intervals = reproduce_tree (source, tree->parent);
/* Explicitly free the old tree here. */
if (position > under->position)
{
INTERVAL end_unchanged
- = split_interval_left (this, position - under->position + 1);
+ = split_interval_left (this, position - under->position);
copy_properties (under, end_unchanged);
under->position = position;
prev = 0;
which means it gets those properties. */
while (! NULL_INTERVAL_P (over))
{
- position = LENGTH (over) + 1;
- if (position < LENGTH (under))
- this = split_interval_left (under, position);
+ if (LENGTH (over) + 1 < LENGTH (under))
+ this = split_interval_left (under, LENGTH (over));
else
this = under;
copy_properties (over, this);
register struct buffer *buffer;
{
register INTERVAL to, from, toprev, fromprev, target;
- register int iposition = position;
int buffer_point;
register Lisp_Object obj;
int backwards = (position < BUF_PT (buffer)) ? 1 : 0;
return;
}
- /* Position Z is really one past the last char in the buffer. */
- if (position == BUF_ZV (buffer))
- iposition = position - 1;
-
/* Set TO to the interval containing the char after POSITION,
and TOPREV to the interval containing the char before POSITION.
Either one may be null. They may be equal. */
- to = find_interval (buffer->intervals, iposition);
+ to = find_interval (buffer->intervals, position);
if (position == BUF_BEGV (buffer))
toprev = 0;
else if (to->position == position)
toprev = previous_interval (to);
- else if (iposition != position)
- toprev = to, to = 0;
else
toprev = to;
if (position > BUF_Z (buffer) || position < BUF_BEG (buffer))
abort ();
- /* Position Z is really one past the last char in the buffer. */
- if (position == BUF_ZV (buffer))
- return current_buffer->keymap;
-
interval = find_interval (buffer->intervals, position);
prop = textget (interval->plist, Qlocal_map);
if (NILP (prop))
/* Set I to the interval containing the char after START,
and PREV to the interval containing the char before START.
Either one may be null. They may be equal. */
- i = find_interval (intervals,
- (start == BUF_ZV (buf) ? start - 1 : start));
+ i = find_interval (intervals, start);
if (start == BUF_BEGV (buf))
prev = 0;
error ("Attempt to insert within read-only text");
}
- /* Run both mod hooks (just once if they're the same). */
+ /* Run both insert hooks (just once if they're the same). */
if (!NULL_INTERVAL_P (prev))
- prev_mod_hooks = textget (prev->plist, Qmodification_hooks);
+ prev_mod_hooks = textget (prev->plist, Qinsert_behind_hooks);
if (!NULL_INTERVAL_P (i))
- mod_hooks = textget (i->plist, Qmodification_hooks);
+ mod_hooks = textget (i->plist, Qinsert_in_front_hooks);
GCPRO1 (mod_hooks);
if (! NILP (prev_mod_hooks))
call_mod_hooks (prev_mod_hooks, make_number (start),
while (got < length)
{
i = next_interval (i);
- t = split_interval_right (t, prevlen + 1);
+ t = split_interval_right (t, prevlen);
copy_properties (i, t);
prevlen = LENGTH (i);
got += prevlen;