diff options
| author | Stefan Monnier | 2022-10-09 19:45:26 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2022-10-09 19:45:26 -0400 |
| commit | 7cbeeabc7e6271948e7bb93020c2e4e50c65f384 (patch) | |
| tree | 777b281d62878ab7cc5a12b7e3fbc8952bf95dbc /src/buffer.c | |
| parent | 4f3f7aebc957732f4fbe5c799da5367f46607680 (diff) | |
| download | emacs-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.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. */) | |||
| 638 | return buffer; | 638 | return buffer; |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | static void | ||
| 642 | add_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 | ||
| 909 | static void | ||
| 910 | remove_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 | ||
| 902 | static void | 920 | static 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 | ||
| 3538 | INLINE void | ||
| 3539 | set_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 | |||
| 3521 | DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, | 3547 | DEFUN ("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. |
| 3523 | If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now. | 3549 | If 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)) |