diff options
| author | Stefan Monnier <monnier@iro.umontreal.ca> | 2022-10-09 19:45:26 -0400 |
|---|---|---|
| committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2022-10-09 19:45:26 -0400 |
| commit | 7cbeeabc7e6271948e7bb93020c2e4e50c65f384 (patch) | |
| tree | 777b281d62878ab7cc5a12b7e3fbc8952bf95dbc /src/buffer.c | |
| parent | 4f3f7aebc957732f4fbe5c799da5367f46607680 (diff) | |
Tighten up handling of `otick`
Move args between `build_overlay` and `add_buffer_overlay`,
to try and keep buffer positions together with their buffer.
Be more strict in the `otick` values passed to `interval_tree_insert`.
Move a few things around to try and reduce dependencies through `.h` files.
Fix a thinko bug in `check_tree`.
* src/alloc.c (build_overlay): Remove `begin` and `end` args.
* src/buffer.c (add_buffer_overlay): Move from `buffer.h`.
Add `begin` and `end` args.
(copy_overlays): Adjust accordingly.
(Fmake_overlay): Use BUF_BEG and BUF_Z; adjust call to `build_overlay`
and `add_buffer_overlay`.
(Fmove_overlay): Use BUF_BEG and BUF_Z; Use the new `begin` and `end`
args of `add_buffer_overlay` so we don't need to use
`interval_node_set_region` when moving to a new buffer.
(remove_buffer_overlay, set_overlay_region): Move from `buffer.h`.
* src/buffer.h (set_overlay_region, add_buffer_overlay)
(remove_buffer_overlay): Move to `buffer.c`.
(build_overlay): Move from `lisp.h`.
(maybe_alloc_buffer_overlays): Delete function (inline into its only
caller).
* src/itree.c (interval_tree_insert): Move declaration `from buffer.h`.
(check_tree): Fix initial offset in call to `recurse_check_tree`.
Remove redundant check of the `limit` value.
(interval_node_init): Remove `begin` and `end` args.
(interval_tree_insert): Mark it as static.
Assert that the new node's `otick` should already be uptodate and its
new parent as well.
(itree_insert_node): New function.
(interval_tree_insert_gap): Assert the otick of the removed+added nodes
were uptodate and mark them as uptodate again after adjusting
their positions.
(interval_tree_inherit_offset): Check that the parent is at least as
uptodate as the child.
* src/lisp.h (build_overlay): Move to `buffer.h`.
* src/itree.h (interval_node_init): Adjust accordingly.
(interval_tree_insert): Remove declaration.
(itree_insert_node): New declaration.
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/src/buffer.c b/src/buffer.c index f59fddcbdeb..e1303f2a880 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -638,6 +638,16 @@ even if it is dead. The return value is never nil. */) return buffer; } +static void +add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov, + ptrdiff_t begin, ptrdiff_t end) +{ + eassert (! ov->buffer); + if (! b->overlays) + b->overlays = interval_tree_create (); + ov->buffer = b; + itree_insert_node (b->overlays, ov->interval, begin, end); +} /* Copy overlays of buffer FROM to buffer TO. */ @@ -650,11 +660,10 @@ copy_overlays (struct buffer *from, struct buffer *to) ITREE_FOREACH (node, from->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING) { Lisp_Object ov = node->data; - Lisp_Object copy = build_overlay (node->begin, node->end, - node->front_advance, + Lisp_Object copy = build_overlay (node->front_advance, node->rear_advance, Fcopy_sequence (OVERLAY_PLIST (ov))); - add_buffer_overlay (to, XOVERLAY (copy)); + add_buffer_overlay (to, XOVERLAY (copy), node->begin, node->end); } } @@ -897,6 +906,15 @@ does not run the hooks `kill-buffer-hook', return buf; } +static void +remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov) +{ + eassert (b->overlays); + eassert (ov->buffer == b); + interval_tree_remove (ov->buffer->overlays, ov->interval); + ov->buffer = NULL; +} + /* Mark OV as no longer associated with its buffer. */ static void @@ -3486,12 +3504,11 @@ for the rear of the overlay advance when text is inserted there temp = beg; beg = end; end = temp; } - ptrdiff_t obeg = clip_to_bounds (BEG, XFIXNUM (beg), b->text->z); - ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), b->text->z); - ov = build_overlay (obeg, oend, - ! NILP (front_advance), + ptrdiff_t obeg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b)); + ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), BUF_Z (b)); + ov = build_overlay (! NILP (front_advance), ! NILP (rear_advance), Qnil); - add_buffer_overlay (b, XOVERLAY (ov)); + add_buffer_overlay (b, XOVERLAY (ov), obeg, oend); /* We don't need to redisplay the region covered by the overlay, because the overlay has no properties at the moment. */ @@ -3518,6 +3535,15 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1); } +INLINE void +set_overlay_region (struct Lisp_Overlay *ov, ptrdiff_t begin, ptrdiff_t end) +{ + eassert (ov->buffer); + begin = clip_to_bounds (BEG, begin, ov->buffer->text->z); + end = clip_to_bounds (begin, end, ov->buffer->text->z); + interval_node_set_region (ov->buffer->overlays, ov->interval, begin, end); +} + DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER. If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now. @@ -3528,7 +3554,6 @@ buffer. */) struct buffer *b, *ob = 0; Lisp_Object obuffer; specpdl_ref count = SPECPDL_INDEX (); - ptrdiff_t n_beg, n_end; ptrdiff_t o_beg UNINIT, o_end UNINIT; CHECK_OVERLAY (overlay); @@ -3555,11 +3580,14 @@ buffer. */) temp = beg; beg = end; end = temp; } - specbind (Qinhibit_quit, Qt); + specbind (Qinhibit_quit, Qt); /* FIXME: Why? */ obuffer = Foverlay_buffer (overlay); b = XBUFFER (buffer); + ptrdiff_t n_beg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b)); + ptrdiff_t n_end = clip_to_bounds (n_beg, XFIXNUM (end), BUF_Z (b)); + if (!NILP (obuffer)) { ob = XBUFFER (obuffer); @@ -3572,13 +3600,11 @@ buffer. */) { if (! NILP (obuffer)) remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay)); - add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay)); + add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay), n_beg, n_end); } - /* Set the overlay boundaries, which may clip them. */ - set_overlay_region (XOVERLAY (overlay), XFIXNUM (beg), XFIXNUM (end)); - - n_beg = OVERLAY_START (overlay); - n_end = OVERLAY_END (overlay); + else + interval_node_set_region (b->overlays, XOVERLAY (overlay)->interval, + n_beg, n_end); /* If the overlay has changed buffers, do a thorough redisplay. */ if (!BASE_EQ (buffer, obuffer)) |
