}
}
+static void
+adjust_overlays_for_delete_in_buffer (struct buffer * buf,
+ ptrdiff_t pos, ptrdiff_t length)
+{
+ Lisp_Object hit_list = Qnil;
+ struct itree_node *node;
+
+ /* Ideally, the evaporate check would be done directly within
+ `itree_delete_gap`, but that code isn't supposed to know about overlays,
+ only about `itree_node`s, so it would break an abstraction boundary. */
+ itree_delete_gap (buf->overlays, pos, length);
+
+ /* Delete any zero-sized overlays at position POS, if the `evaporate'
+ property is set. */
+
+ ITREE_FOREACH (node, buf->overlays, pos, pos, ASCENDING)
+ {
+ if (node->end == pos && node->begin == pos
+ && ! NILP (Foverlay_get (node->data, Qevaporate)))
+ hit_list = Fcons (node->data, hit_list);
+ }
+
+ for (; CONSP (hit_list); hit_list = XCDR (hit_list))
+ Fdelete_overlay (XCAR (hit_list));
+}
+
void
adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
{
if (!current_buffer->indirections)
- itree_delete_gap (current_buffer->overlays, pos, length);
+ adjust_overlays_for_delete_in_buffer (current_buffer, pos, length);
else
{
struct buffer *base = current_buffer->base_buffer
? current_buffer->base_buffer
: current_buffer;
Lisp_Object tail, other;
- itree_delete_gap (base->overlays, pos, length);
+ adjust_overlays_for_delete_in_buffer (base, pos, length);
FOR_EACH_LIVE_BUFFER (tail, other)
if (XBUFFER (other)->base_buffer == base)
- itree_delete_gap (XBUFFER (other)->overlays, pos, length);
+ adjust_overlays_for_delete_in_buffer (XBUFFER (other), pos, length);
}
}
}
}
-/* Delete any zero-sized overlays at position POS, if the `evaporate'
- property is set. */
-void
-evaporate_overlays (ptrdiff_t pos)
-{
- Lisp_Object hit_list = Qnil;
- struct itree_node *node;
-
- ITREE_FOREACH (node, current_buffer->overlays, pos, pos, ASCENDING)
- {
- if (node->end == pos
- && ! NILP (Foverlay_get (node->data, Qevaporate)))
- hit_list = Fcons (node->data, hit_list);
- }
-
- for (; CONSP (hit_list); hit_list = XCDR (hit_list))
- Fdelete_overlay (XCAR (hit_list));
-}
-
/***********************************************************************
Allocation with mmap
***********************************************************************/
extern void delete_all_overlays (struct buffer *);
extern void reset_buffer (struct buffer *);
extern void compact_buffer (struct buffer *);
-extern void evaporate_overlays (ptrdiff_t);
extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, ptrdiff_t *);
extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **,
ptrdiff_t *, bool, bool, ptrdiff_t *);
ptrdiff_t diff_bytes = new_bytes - old_bytes;
adjust_suspend_auto_hscroll (from, from + old_chars);
+
+ /* FIXME: When OLD_CHARS is 0, this "replacement" is really just an
+ insertion, but the behavior we provide here in that case is that of
+ `insert-before-markers` rather than that of `insert`.
+ Maybe not a bug, but not a feature either. */
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
{
if (m->bytepos >= prev_to_byte)
check_markers ();
adjust_overlays_for_insert (from + old_chars, new_chars, true);
- adjust_overlays_for_delete (from, old_chars);
+ if (old_chars)
+ adjust_overlays_for_delete (from, old_chars);
}
/* Starting at POS (BYTEPOS), find the byte position corresponding to
check_markers ();
- if (len == 0)
- evaporate_overlays (from);
modiff_incr (&MODIFF, nchars_del + len);
CHARS_MODIFF = MODIFF;
}
(from_byte + outgoing_insbytes
- (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
- if (outgoing_insbytes == 0)
- evaporate_overlays (from);
-
check_markers ();
modiff_incr (&MODIFF, nchars_del + inschars);
adjust_point (inschars - nchars_del, insbytes - nbytes_del);
}
- if (insbytes == 0)
- evaporate_overlays (from);
-
check_markers ();
modiff_incr (&MODIFF, nchars_del + inschars);
check_markers ();
- evaporate_overlays (from);
-
return deletion;
}