\f
void
-adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
+adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length, bool before_markers)
{
if (!current_buffer->indirections)
- itree_insert_gap (current_buffer->overlays, pos, length);
+ itree_insert_gap (current_buffer->overlays, pos, length, before_markers);
else
{
struct buffer *base = current_buffer->base_buffer
? current_buffer->base_buffer
: current_buffer;
Lisp_Object tail, other;
- itree_insert_gap (base->overlays, pos, length);
+ itree_insert_gap (base->overlays, pos, length, before_markers);
FOR_EACH_LIVE_BUFFER (tail, other)
if (XBUFFER (other)->base_buffer == base)
- itree_insert_gap (XBUFFER (other)->overlays, pos, length);
+ itree_insert_gap (XBUFFER (other)->overlays, pos, length, before_markers);
}
}
m->bytepos = from_byte;
}
}
+ adjust_overlays_for_delete (from, to - from);
}
\f
m->charpos += nchars;
}
}
+ adjust_overlays_for_insert (from, to - from, before_markers);
}
/* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
}
check_markers ();
+
+ adjust_overlays_for_insert (from + old_chars, new_chars, true);
+ adjust_overlays_for_delete (from, old_chars);
}
/* Starting at POS (BYTEPOS), find the byte position corresponding to
if (Z - GPT < END_UNCHANGED)
END_UNCHANGED = Z - GPT;
- adjust_overlays_for_insert (PT, nchars);
adjust_markers_for_insert (PT, PT_BYTE,
PT + nchars, PT_BYTE + nbytes,
before_markers);
if (Z - GPT < END_UNCHANGED)
END_UNCHANGED = Z - GPT;
- adjust_overlays_for_insert (PT, nchars);
adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
PT_BYTE + outgoing_nbytes,
before_markers);
insert_from_gap_1 (nchars, nbytes, text_at_gap_tail);
- adjust_overlays_for_insert (ins_charpos, nchars);
adjust_markers_for_insert (ins_charpos, ins_bytepos,
- ins_charpos + nchars, ins_bytepos + nbytes, 0);
+ ins_charpos + nchars, ins_bytepos + nbytes, false);
if (buffer_intervals (current_buffer))
{
if (Z - GPT < END_UNCHANGED)
END_UNCHANGED = Z - GPT;
- adjust_overlays_for_insert (PT, nchars);
adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
PT_BYTE + outgoing_nbytes,
- 0);
+ false);
offset_intervals (current_buffer, PT, nchars);
len, len_byte);
else
adjust_markers_for_insert (from, from_byte,
- from + len, from_byte + len_byte, 0);
+ from + len, from_byte + len_byte, false);
if (nchars_del > 0)
record_delete (from, prev_text, false);
record_insert (from, len);
- if (len > nchars_del)
- adjust_overlays_for_insert (from, len - nchars_del);
- else if (len < nchars_del)
- adjust_overlays_for_delete (from, nchars_del - len);
-
offset_intervals (current_buffer, from, len - nchars_del);
if (from < PT)
which make the original byte positions of the markers
invalid. */
adjust_markers_bytepos (from, from_byte, from + inschars,
- from_byte + outgoing_insbytes, 1);
+ from_byte + outgoing_insbytes, true);
}
- /* Adjust the overlay center as needed. This must be done after
- adjusting the markers that bound the overlays. */
- adjust_overlays_for_delete (from, nchars_del);
- adjust_overlays_for_insert (from, inschars);
-
offset_intervals (current_buffer, from, inschars - nchars_del);
/* Get the intervals for the part of the string we are inserting--
sequences which make the original byte positions of the
markers invalid. */
adjust_markers_bytepos (from, from_byte, from + inschars,
- from_byte + insbytes, 1);
+ from_byte + insbytes, true);
}
}
- /* Adjust the overlay center as needed. This must be done after
- adjusting the markers that bound the overlays. */
- if (nchars_del != inschars)
- {
- adjust_overlays_for_insert (from, inschars);
- adjust_overlays_for_delete (from + inschars, nchars_del);
- }
-
offset_intervals (current_buffer, from, inschars - nchars_del);
/* Relocate point as if it were a marker. */
offset_intervals (current_buffer, from, - nchars_del);
- /* Adjust the overlay center as needed. This must be done after
- adjusting the markers that bound the overlays. */
- adjust_overlays_for_delete (from, nchars_del);
-
GAP_SIZE += nbytes_del;
ZV_BYTE -= nbytes_del;
Z_BYTE -= nbytes_del;
void
itree_insert_gap (struct itree_tree *tree,
- ptrdiff_t pos, ptrdiff_t length)
+ ptrdiff_t pos, ptrdiff_t length, bool before_markers)
{
if (!tree || length <= 0 || tree->root == NULL)
return;
/* FIXME: Don't allocate iterator/stack anew every time. */
/* Nodes with front_advance starting at pos may mess up the tree
- order, so we need to remove them first. */
+ order, so we need to remove them first. This doesn't apply for
+ `before_markers` since in that case, all positions move identically
+ regardless of `front_advance` or `rear_advance`. */
struct interval_stack *saved = interval_stack_create (0);
struct itree_node *node = NULL;
- ITREE_FOREACH (node, tree, pos, pos + 1, PRE_ORDER)
+ if (!before_markers)
{
- if (node->begin == pos && node->front_advance
- && (node->begin != node->end || node->rear_advance))
- interval_stack_push (saved, node);
+ ITREE_FOREACH (node, tree, pos, pos + 1, PRE_ORDER)
+ {
+ if (node->begin == pos && node->front_advance
+ && (node->begin != node->end || node->rear_advance))
+ interval_stack_push (saved, node);
+ }
}
for (size_t i = 0; i < saved->length; ++i)
itree_remove (tree, nav_nodeptr (saved->nodes[i]));
&& pos <= node->left->limit + node->left->offset)
interval_stack_push (stack, node->left);
- /* node->begin == pos implies no front-advance. */
- if (node->begin > pos)
+ if (before_markers
+ ? node->begin >= pos
+ : node->begin > pos) /* node->begin == pos => !front-advance */
node->begin += length;
- if (node->end > pos || (node->end == pos && node->rear_advance))
+ if (node->end > pos
+ || (node->end == pos && (before_markers || node->rear_advance)))
{
node->end += length;
eassert (node != NULL);
ptrdiff_t, ptrdiff_t);
extern struct itree_node *itree_remove (struct itree_tree *,
struct itree_node *);
-extern void itree_insert_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t);
+extern void itree_insert_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t, bool);
extern void itree_delete_gap (struct itree_tree *, ptrdiff_t, ptrdiff_t);
/* Iteration functions. Almost all code should use ITREE_FOREACH
extern bool mouse_face_overlay_overlaps (Lisp_Object);
extern Lisp_Object disable_line_numbers_overlay_at_eob (void);
extern AVOID nsberror (Lisp_Object);
-extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t);
+extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t, bool);
extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t);
extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t);
extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool,
(deftest-overlay-start/end-1 L (1 0) (1 1))
(deftest-overlay-start/end-1 M (0 0) (1 1))
+(ert-deftest test-overlay-insert-before-markers-empty ()
+ (with-temp-buffer
+ (insert "1234")
+ (goto-char (1+ (point-min)))
+ (let ((overlay (make-overlay (point) (point))))
+ (insert-before-markers "x")
+ (should (equal (point) (overlay-end overlay)))
+ (should (equal (point) (overlay-start overlay))))))
+
+(ert-deftest test-overlay-insert-before-markers-non-empty ()
+ (with-temp-buffer
+ (insert "1234")
+ (goto-char (+ 2 (point)))
+ (let ((overlay (make-overlay (1- (point)) (point))))
+ (insert-before-markers "x")
+ (should (equal (point) (overlay-end overlay)))
+ (should (equal (- (point) 2) (overlay-start overlay)))
+ (forward-char -2)
+ (insert-before-markers "y")
+ (should (equal (+ 2 (point)) (overlay-end overlay)))
+ (should (equal (point) (overlay-start overlay))))))
+
(ert-deftest test-overlay-start/end-2 ()
(should-not (overlay-start (with-temp-buffer (make-overlay 1 1))))
(should-not (overlay-end (with-temp-buffer (make-overlay 1 1)))))