aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c119
1 files changed, 68 insertions, 51 deletions
diff --git a/src/buffer.c b/src/buffer.c
index b67b989326e..d948aaa2662 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -937,19 +937,16 @@ delete_all_overlays (struct buffer *b)
937 if (! b->overlays) 937 if (! b->overlays)
938 return; 938 return;
939 939
940 /* FIXME: This loop sets the overlays' `buffer` field to NULL but 940 /* The general rule is that the tree cannot be modified from within
941 doesn't set the itree_nodes' `parent`, `left` and `right` 941 ITREE_FOREACH, but here we bend this rule a little because we know
942 fields accordingly. I believe it's harmless, but a bit untidy since 942 that the POST_ORDER iterator will not need to look at `node` again. */
943 other parts of the code are careful to set those fields to NULL when 943 ITREE_FOREACH (node, b->overlays, PTRDIFF_MIN, PTRDIFF_MAX, POST_ORDER)
944 the overlay is deleted.
945 Of course, we can't set them to NULL from within the iteration
946 because the iterator may need them (tho we could if we added
947 an ITREE_POST_ORDER iteration order). */
948 ITREE_FOREACH (node, b->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
949 { 944 {
950 modify_overlay (b, node->begin, node->end); 945 modify_overlay (b, node->begin, node->end);
951 /* Where are the nodes freed ? --ap */
952 XOVERLAY (node->data)->buffer = NULL; 946 XOVERLAY (node->data)->buffer = NULL;
947 node->parent = NULL;
948 node->left = NULL;
949 node->right = NULL;
953 } 950 }
954 itree_clear (b->overlays); 951 itree_clear (b->overlays);
955} 952}
@@ -982,7 +979,7 @@ set_overlays_multibyte (bool multibyte)
982 struct itree_tree *tree = current_buffer->overlays; 979 struct itree_tree *tree = current_buffer->overlays;
983 const intmax_t size = itree_size (tree); 980 const intmax_t size = itree_size (tree);
984 981
985 /* We can't use `interval_node_set_region` at the same time 982 /* We can't use `itree_node_set_region` at the same time
986 as we iterate over the itree, so we need an auxiliary storage 983 as we iterate over the itree, so we need an auxiliary storage
987 to keep the list of nodes. */ 984 to keep the list of nodes. */
988 USE_SAFE_ALLOCA; 985 USE_SAFE_ALLOCA;
@@ -2985,17 +2982,13 @@ overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
2985 if (node->begin > end) 2982 if (node->begin > end)
2986 { 2983 {
2987 next = min (next, node->begin); 2984 next = min (next, node->begin);
2988 ITREE_FOREACH_ABORT ();
2989 break; 2985 break;
2990 } 2986 }
2991 else if (node->begin == end) 2987 else if (node->begin == end)
2992 { 2988 {
2993 next = node->begin; 2989 next = node->begin;
2994 if ((! empty || end < ZV) && beg < end) 2990 if ((! empty || end < ZV) && beg < end)
2995 { 2991 break;
2996 ITREE_FOREACH_ABORT ();
2997 break;
2998 }
2999 if (empty && node->begin != node->end) 2992 if (empty && node->begin != node->end)
3000 continue; 2993 continue;
3001 } 2994 }
@@ -3050,7 +3043,6 @@ next_overlay_change (ptrdiff_t pos)
3050 of pos, because the search is limited to [pos,next) . */ 3043 of pos, because the search is limited to [pos,next) . */
3051 eassert (node->begin < next); 3044 eassert (node->begin < next);
3052 next = node->begin; 3045 next = node->begin;
3053 ITREE_FOREACH_ABORT ();
3054 break; 3046 break;
3055 } 3047 }
3056 else if (node->begin < node->end && node->end < next) 3048 else if (node->begin < node->end && node->end < next)
@@ -3155,10 +3147,7 @@ overlay_touches_p (ptrdiff_t pos)
3155 pos. */ 3147 pos. */
3156 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING) 3148 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
3157 if (node->begin == pos || node->end == pos) 3149 if (node->begin == pos || node->end == pos)
3158 { 3150 return true;
3159 ITREE_FOREACH_ABORT ();
3160 return true;
3161 }
3162 return false; 3151 return false;
3163} 3152}
3164 3153
@@ -3454,21 +3443,66 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3454 3443
3455 3444
3456void 3445void
3457adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length) 3446adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length, bool before_markers)
3458{ 3447{
3459 /* After an insertion, the lists are still sorted properly, 3448 if (!current_buffer->indirections)
3460 but we may need to update the value of the overlay center. */ 3449 itree_insert_gap (current_buffer->overlays, pos, length, before_markers);
3461 if (! current_buffer->overlays) 3450 else
3462 return; 3451 {
3463 itree_insert_gap (current_buffer->overlays, pos, length); 3452 struct buffer *base = current_buffer->base_buffer
3453 ? current_buffer->base_buffer
3454 : current_buffer;
3455 Lisp_Object tail, other;
3456 itree_insert_gap (base->overlays, pos, length, before_markers);
3457 FOR_EACH_LIVE_BUFFER (tail, other)
3458 if (XBUFFER (other)->base_buffer == base)
3459 itree_insert_gap (XBUFFER (other)->overlays, pos, length,
3460 before_markers);
3461 }
3462}
3463
3464static void
3465adjust_overlays_for_delete_in_buffer (struct buffer * buf,
3466 ptrdiff_t pos, ptrdiff_t length)
3467{
3468 Lisp_Object hit_list = Qnil;
3469 struct itree_node *node;
3470
3471 /* Ideally, the evaporate check would be done directly within
3472 `itree_delete_gap`, but that code isn't supposed to know about overlays,
3473 only about `itree_node`s, so it would break an abstraction boundary. */
3474 itree_delete_gap (buf->overlays, pos, length);
3475
3476 /* Delete any zero-sized overlays at position POS, if the `evaporate'
3477 property is set. */
3478
3479 ITREE_FOREACH (node, buf->overlays, pos, pos, ASCENDING)
3480 {
3481 if (node->end == pos && node->begin == pos
3482 && ! NILP (Foverlay_get (node->data, Qevaporate)))
3483 hit_list = Fcons (node->data, hit_list);
3484 }
3485
3486 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
3487 Fdelete_overlay (XCAR (hit_list));
3464} 3488}
3465 3489
3466void 3490void
3467adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) 3491adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
3468{ 3492{
3469 if (! current_buffer->overlays) 3493 if (!current_buffer->indirections)
3470 return; 3494 adjust_overlays_for_delete_in_buffer (current_buffer, pos, length);
3471 itree_delete_gap (current_buffer->overlays, pos, length); 3495 else
3496 {
3497 struct buffer *base = current_buffer->base_buffer
3498 ? current_buffer->base_buffer
3499 : current_buffer;
3500 Lisp_Object tail, other;
3501 adjust_overlays_for_delete_in_buffer (base, pos, length);
3502 FOR_EACH_LIVE_BUFFER (tail, other)
3503 if (XBUFFER (other)->base_buffer == base)
3504 adjust_overlays_for_delete_in_buffer (XBUFFER (other), pos, length);
3505 }
3472} 3506}
3473 3507
3474 3508
@@ -3601,7 +3635,7 @@ buffer. */)
3601 o_end = OVERLAY_END (overlay); 3635 o_end = OVERLAY_END (overlay);
3602 } 3636 }
3603 3637
3604 if (! EQ (buffer, obuffer)) 3638 if (! BASE_EQ (buffer, obuffer))
3605 { 3639 {
3606 if (! NILP (obuffer)) 3640 if (! NILP (obuffer))
3607 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay)); 3641 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
@@ -3790,7 +3824,9 @@ and also contained within the specified region.
3790 3824
3791Empty overlays are included in the result if they are located at BEG, 3825Empty overlays are included in the result if they are located at BEG,
3792between BEG and END, or at END provided END denotes the position at the 3826between BEG and END, or at END provided END denotes the position at the
3793end of the accessible part of the buffer. */) 3827end of the accessible part of the buffer.
3828
3829The resulting list of overlays is in an arbitrary unpredictable order. */)
3794 (Lisp_Object beg, Lisp_Object end) 3830 (Lisp_Object beg, Lisp_Object end)
3795{ 3831{
3796 ptrdiff_t len, noverlays; 3832 ptrdiff_t len, noverlays;
@@ -4080,25 +4116,6 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after,
4080 } 4116 }
4081} 4117}
4082 4118
4083/* Delete any zero-sized overlays at position POS, if the `evaporate'
4084 property is set. */
4085void
4086evaporate_overlays (ptrdiff_t pos)
4087{
4088 Lisp_Object hit_list = Qnil;
4089 struct itree_node *node;
4090
4091 ITREE_FOREACH (node, current_buffer->overlays, pos, pos, ASCENDING)
4092 {
4093 if (node->end == pos
4094 && ! NILP (Foverlay_get (node->data, Qevaporate)))
4095 hit_list = Fcons (node->data, hit_list);
4096 }
4097
4098 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4099 Fdelete_overlay (XCAR (hit_list));
4100}
4101
4102/*********************************************************************** 4119/***********************************************************************
4103 Allocation with mmap 4120 Allocation with mmap
4104 ***********************************************************************/ 4121 ***********************************************************************/