aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorStefan Monnier2022-10-09 19:45:26 -0400
committerStefan Monnier2022-10-09 19:45:26 -0400
commit7cbeeabc7e6271948e7bb93020c2e4e50c65f384 (patch)
tree777b281d62878ab7cc5a12b7e3fbc8952bf95dbc /src/buffer.c
parent4f3f7aebc957732f4fbe5c799da5367f46607680 (diff)
downloademacs-7cbeeabc7e6271948e7bb93020c2e4e50c65f384.tar.gz
emacs-7cbeeabc7e6271948e7bb93020c2e4e50c65f384.zip
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.c58
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. */)
638 return buffer; 638 return buffer;
639} 639}
640 640
641static void
642add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov,
643 ptrdiff_t begin, ptrdiff_t end)
644{
645 eassert (! ov->buffer);
646 if (! b->overlays)
647 b->overlays = interval_tree_create ();
648 ov->buffer = b;
649 itree_insert_node (b->overlays, ov->interval, begin, end);
650}
641 651
642/* Copy overlays of buffer FROM to buffer TO. */ 652/* Copy overlays of buffer FROM to buffer TO. */
643 653
@@ -650,11 +660,10 @@ copy_overlays (struct buffer *from, struct buffer *to)
650 ITREE_FOREACH (node, from->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING) 660 ITREE_FOREACH (node, from->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
651 { 661 {
652 Lisp_Object ov = node->data; 662 Lisp_Object ov = node->data;
653 Lisp_Object copy = build_overlay (node->begin, node->end, 663 Lisp_Object copy = build_overlay (node->front_advance,
654 node->front_advance,
655 node->rear_advance, 664 node->rear_advance,
656 Fcopy_sequence (OVERLAY_PLIST (ov))); 665 Fcopy_sequence (OVERLAY_PLIST (ov)));
657 add_buffer_overlay (to, XOVERLAY (copy)); 666 add_buffer_overlay (to, XOVERLAY (copy), node->begin, node->end);
658 } 667 }
659} 668}
660 669
@@ -897,6 +906,15 @@ does not run the hooks `kill-buffer-hook',
897 return buf; 906 return buf;
898} 907}
899 908
909static void
910remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov)
911{
912 eassert (b->overlays);
913 eassert (ov->buffer == b);
914 interval_tree_remove (ov->buffer->overlays, ov->interval);
915 ov->buffer = NULL;
916}
917
900/* Mark OV as no longer associated with its buffer. */ 918/* Mark OV as no longer associated with its buffer. */
901 919
902static void 920static void
@@ -3486,12 +3504,11 @@ for the rear of the overlay advance when text is inserted there
3486 temp = beg; beg = end; end = temp; 3504 temp = beg; beg = end; end = temp;
3487 } 3505 }
3488 3506
3489 ptrdiff_t obeg = clip_to_bounds (BEG, XFIXNUM (beg), b->text->z); 3507 ptrdiff_t obeg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3490 ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), b->text->z); 3508 ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), BUF_Z (b));
3491 ov = build_overlay (obeg, oend, 3509 ov = build_overlay (! NILP (front_advance),
3492 ! NILP (front_advance),
3493 ! NILP (rear_advance), Qnil); 3510 ! NILP (rear_advance), Qnil);
3494 add_buffer_overlay (b, XOVERLAY (ov)); 3511 add_buffer_overlay (b, XOVERLAY (ov), obeg, oend);
3495 3512
3496 /* We don't need to redisplay the region covered by the overlay, because 3513 /* We don't need to redisplay the region covered by the overlay, because
3497 the overlay has no properties at the moment. */ 3514 the overlay has no properties at the moment. */
@@ -3518,6 +3535,15 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
3518 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1); 3535 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1);
3519} 3536}
3520 3537
3538INLINE void
3539set_overlay_region (struct Lisp_Overlay *ov, ptrdiff_t begin, ptrdiff_t end)
3540{
3541 eassert (ov->buffer);
3542 begin = clip_to_bounds (BEG, begin, ov->buffer->text->z);
3543 end = clip_to_bounds (begin, end, ov->buffer->text->z);
3544 interval_node_set_region (ov->buffer->overlays, ov->interval, begin, end);
3545}
3546
3521DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, 3547DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
3522 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER. 3548 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
3523If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now. 3549If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
@@ -3528,7 +3554,6 @@ buffer. */)
3528 struct buffer *b, *ob = 0; 3554 struct buffer *b, *ob = 0;
3529 Lisp_Object obuffer; 3555 Lisp_Object obuffer;
3530 specpdl_ref count = SPECPDL_INDEX (); 3556 specpdl_ref count = SPECPDL_INDEX ();
3531 ptrdiff_t n_beg, n_end;
3532 ptrdiff_t o_beg UNINIT, o_end UNINIT; 3557 ptrdiff_t o_beg UNINIT, o_end UNINIT;
3533 3558
3534 CHECK_OVERLAY (overlay); 3559 CHECK_OVERLAY (overlay);
@@ -3555,11 +3580,14 @@ buffer. */)
3555 temp = beg; beg = end; end = temp; 3580 temp = beg; beg = end; end = temp;
3556 } 3581 }
3557 3582
3558 specbind (Qinhibit_quit, Qt); 3583 specbind (Qinhibit_quit, Qt); /* FIXME: Why? */
3559 3584
3560 obuffer = Foverlay_buffer (overlay); 3585 obuffer = Foverlay_buffer (overlay);
3561 b = XBUFFER (buffer); 3586 b = XBUFFER (buffer);
3562 3587
3588 ptrdiff_t n_beg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3589 ptrdiff_t n_end = clip_to_bounds (n_beg, XFIXNUM (end), BUF_Z (b));
3590
3563 if (!NILP (obuffer)) 3591 if (!NILP (obuffer))
3564 { 3592 {
3565 ob = XBUFFER (obuffer); 3593 ob = XBUFFER (obuffer);
@@ -3572,13 +3600,11 @@ buffer. */)
3572 { 3600 {
3573 if (! NILP (obuffer)) 3601 if (! NILP (obuffer))
3574 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay)); 3602 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
3575 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay)); 3603 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay), n_beg, n_end);
3576 } 3604 }
3577 /* Set the overlay boundaries, which may clip them. */ 3605 else
3578 set_overlay_region (XOVERLAY (overlay), XFIXNUM (beg), XFIXNUM (end)); 3606 interval_node_set_region (b->overlays, XOVERLAY (overlay)->interval,
3579 3607 n_beg, n_end);
3580 n_beg = OVERLAY_START (overlay);
3581 n_end = OVERLAY_END (overlay);
3582 3608
3583 /* If the overlay has changed buffers, do a thorough redisplay. */ 3609 /* If the overlay has changed buffers, do a thorough redisplay. */
3584 if (!BASE_EQ (buffer, obuffer)) 3610 if (!BASE_EQ (buffer, obuffer))