diff options
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 119 |
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 | ||
| 3456 | void | 3445 | void |
| 3457 | adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length) | 3446 | adjust_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 | |||
| 3464 | static void | ||
| 3465 | adjust_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 | ||
| 3466 | void | 3490 | void |
| 3467 | adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) | 3491 | adjust_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 | ||
| 3791 | Empty overlays are included in the result if they are located at BEG, | 3825 | Empty overlays are included in the result if they are located at BEG, |
| 3792 | between BEG and END, or at END provided END denotes the position at the | 3826 | between BEG and END, or at END provided END denotes the position at the |
| 3793 | end of the accessible part of the buffer. */) | 3827 | end of the accessible part of the buffer. |
| 3828 | |||
| 3829 | The 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. */ | ||
| 4085 | void | ||
| 4086 | evaporate_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 | ***********************************************************************/ |