aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorStefan Monnier2022-10-28 17:44:44 -0400
committerStefan Monnier2022-10-28 17:44:44 -0400
commit71589b101ccbec67fa2741856ee0add5752dea72 (patch)
tree63aeb9f5617c3e7e9b87c04f10bfa938f495736c /src/buffer.c
parent69121c33e4a11805bf6438131c8aec72411a0e5d (diff)
parent9d7ba2b1998afc3664c37d9d1b6f6ca2d68356e9 (diff)
downloademacs-71589b101ccbec67fa2741856ee0add5752dea72.tar.gz
emacs-71589b101ccbec67fa2741856ee0add5752dea72.zip
Merge remote-tracking branch 'origin/feature/noverlay'
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c1505
1 files changed, 465 insertions, 1040 deletions
diff --git a/src/buffer.c b/src/buffer.c
index d4a0c37bed5..b67b989326e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1,7 +1,6 @@
1/* Buffer manipulation primitives for GNU Emacs. 1/* Buffer manipulation primitives for GNU Emacs.
2 2
3Copyright (C) 1985-1989, 1993-1995, 1997-2022 Free Software Foundation, 3Copyright (C) 1985-2022 Free Software Foundation, Inc.
4Inc.
5 4
6This file is part of GNU Emacs. 5This file is part of GNU Emacs.
7 6
@@ -44,6 +43,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
44#include "keymap.h" 43#include "keymap.h"
45#include "frame.h" 44#include "frame.h"
46#include "xwidget.h" 45#include "xwidget.h"
46#include "itree.h"
47#include "pdumper.h" 47#include "pdumper.h"
48 48
49#ifdef WINDOWSNT 49#ifdef WINDOWSNT
@@ -116,7 +116,7 @@ static Lisp_Object QSFundamental; /* A string "Fundamental". */
116 116
117static void alloc_buffer_text (struct buffer *, ptrdiff_t); 117static void alloc_buffer_text (struct buffer *, ptrdiff_t);
118static void free_buffer_text (struct buffer *b); 118static void free_buffer_text (struct buffer *b);
119static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *); 119static void copy_overlays (struct buffer *, struct buffer *);
120static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t); 120static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
121static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool); 121static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool);
122static Lisp_Object buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym); 122static Lisp_Object buffer_local_variables_1 (struct buffer *buf, int offset, Lisp_Object sym);
@@ -638,52 +638,33 @@ even if it is dead. The return value is never nil. */)
638 return buffer; 638 return buffer;
639} 639}
640 640
641 641static void
642/* Return a list of overlays which is a copy of the overlay list 642add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov,
643 LIST, but for buffer B. */ 643 ptrdiff_t begin, ptrdiff_t end)
644
645static struct Lisp_Overlay *
646copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
647{ 644{
648 struct Lisp_Overlay *result = NULL, *tail = NULL; 645 eassert (! ov->buffer);
649 646 if (! b->overlays)
650 for (; list; list = list->next) 647 b->overlays = itree_create ();
651 { 648 ov->buffer = b;
652 Lisp_Object overlay, start, end; 649 itree_insert (b->overlays, ov->interval, begin, end);
653 struct Lisp_Marker *m;
654
655 eassert (MARKERP (list->start));
656 m = XMARKER (list->start);
657 start = build_marker (b, m->charpos, m->bytepos);
658 XMARKER (start)->insertion_type = m->insertion_type;
659
660 eassert (MARKERP (list->end));
661 m = XMARKER (list->end);
662 end = build_marker (b, m->charpos, m->bytepos);
663 XMARKER (end)->insertion_type = m->insertion_type;
664
665 overlay = build_overlay (start, end, Fcopy_sequence (list->plist));
666 if (tail)
667 tail = tail->next = XOVERLAY (overlay);
668 else
669 result = tail = XOVERLAY (overlay);
670 }
671
672 return result;
673} 650}
674 651
675/* Set an appropriate overlay of B. */ 652/* Copy overlays of buffer FROM to buffer TO. */
676 653
677static void 654static void
678set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o) 655copy_overlays (struct buffer *from, struct buffer *to)
679{ 656{
680 b->overlays_before = o; 657 eassert (to && ! to->overlays);
681} 658 struct itree_node *node;
682 659
683static void 660 ITREE_FOREACH (node, from->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
684set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o) 661 {
685{ 662 Lisp_Object ov = node->data;
686 b->overlays_after = o; 663 Lisp_Object copy = build_overlay (node->front_advance,
664 node->rear_advance,
665 Fcopy_sequence (OVERLAY_PLIST (ov)));
666 add_buffer_overlay (to, XOVERLAY (copy), node->begin, node->end);
667 }
687} 668}
688 669
689bool 670bool
@@ -726,8 +707,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to)
726 707
727 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags); 708 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags);
728 709
729 set_buffer_overlays_before (to, copy_overlays (to, from->overlays_before)); 710 copy_overlays (from, to);
730 set_buffer_overlays_after (to, copy_overlays (to, from->overlays_after));
731 711
732 /* Get (a copy of) the alist of Lisp-level local variables of FROM 712 /* Get (a copy of) the alist of Lisp-level local variables of FROM
733 and install that in TO. */ 713 and install that in TO. */
@@ -926,17 +906,25 @@ does not run the hooks `kill-buffer-hook',
926 return buf; 906 return buf;
927} 907}
928 908
929/* Mark OV as no longer associated with B. */ 909static void
910remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov)
911{
912 eassert (b->overlays);
913 eassert (ov->buffer == b);
914 itree_remove (ov->buffer->overlays, ov->interval);
915 ov->buffer = NULL;
916}
917
918/* Mark OV as no longer associated with its buffer. */
930 919
931static void 920static void
932drop_overlay (struct buffer *b, struct Lisp_Overlay *ov) 921drop_overlay (struct Lisp_Overlay *ov)
933{ 922{
934 eassert (b == XBUFFER (Fmarker_buffer (ov->start))); 923 if (! ov->buffer)
935 modify_overlay (b, marker_position (ov->start), 924 return;
936 marker_position (ov->end));
937 unchain_marker (XMARKER (ov->start));
938 unchain_marker (XMARKER (ov->end));
939 925
926 modify_overlay (ov->buffer, overlay_start (ov), overlay_end (ov));
927 remove_buffer_overlay (ov->buffer, ov);
940} 928}
941 929
942/* Delete all overlays of B and reset its overlay lists. */ 930/* Delete all overlays of B and reset its overlay lists. */
@@ -944,26 +932,94 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
944void 932void
945delete_all_overlays (struct buffer *b) 933delete_all_overlays (struct buffer *b)
946{ 934{
947 struct Lisp_Overlay *ov, *next; 935 struct itree_node *node;
936
937 if (! b->overlays)
938 return;
948 939
949 /* FIXME: Since each drop_overlay will scan BUF_MARKERS to unlink its 940 /* FIXME: This loop sets the overlays' `buffer` field to NULL but
950 markers, we have an unneeded O(N^2) behavior here. */ 941 doesn't set the itree_nodes' `parent`, `left` and `right`
951 for (ov = b->overlays_before; ov; ov = next) 942 fields accordingly. I believe it's harmless, but a bit untidy since
943 other parts of the code are careful to set those fields to NULL when
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)
952 { 949 {
953 drop_overlay (b, ov); 950 modify_overlay (b, node->begin, node->end);
954 next = ov->next; 951 /* Where are the nodes freed ? --ap */
955 ov->next = NULL; 952 XOVERLAY (node->data)->buffer = NULL;
956 } 953 }
954 itree_clear (b->overlays);
955}
957 956
958 for (ov = b->overlays_after; ov; ov = next) 957static void
958free_buffer_overlays (struct buffer *b)
959{
960 /* Actually this does not free any overlay, but the tree only. --ap */
961 if (b->overlays)
959 { 962 {
960 drop_overlay (b, ov); 963 itree_destroy (b->overlays);
961 next = ov->next; 964 b->overlays = NULL;
962 ov->next = NULL;
963 } 965 }
966}
964 967
965 set_buffer_overlays_before (b, NULL); 968/* Adjust the position of overlays in the current buffer according to
966 set_buffer_overlays_after (b, NULL); 969 MULTIBYTE.
970
971 Assume that positions currently correspond to byte positions, if
972 MULTIBYTE is true and to character positions if not.
973*/
974
975static void
976set_overlays_multibyte (bool multibyte)
977{
978 if (! current_buffer->overlays || Z == Z_BYTE)
979 return;
980
981 struct itree_node **nodes = NULL;
982 struct itree_tree *tree = current_buffer->overlays;
983 const intmax_t size = itree_size (tree);
984
985 /* We can't use `interval_node_set_region` at the same time
986 as we iterate over the itree, so we need an auxiliary storage
987 to keep the list of nodes. */
988 USE_SAFE_ALLOCA;
989 SAFE_NALLOCA (nodes, 1, size);
990 {
991 struct itree_node *node, **cursor = nodes;
992 ITREE_FOREACH (node, tree, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
993 *(cursor++) = node;
994 }
995
996 for (int i = 0; i < size; ++i, ++nodes)
997 {
998 struct itree_node * const node = *nodes;
999
1000 if (multibyte)
1001 {
1002 ptrdiff_t begin = itree_node_begin (tree, node);
1003 ptrdiff_t end = itree_node_end (tree, node);
1004
1005 /* This models the behavior of markers. (The behavior of
1006 text-intervals differs slightly.) */
1007 while (begin < Z_BYTE
1008 && !CHAR_HEAD_P (FETCH_BYTE (begin)))
1009 begin++;
1010 while (end < Z_BYTE
1011 && !CHAR_HEAD_P (FETCH_BYTE (end)))
1012 end++;
1013 itree_node_set_region (tree, node, BYTE_TO_CHAR (begin),
1014 BYTE_TO_CHAR (end));
1015 }
1016 else
1017 {
1018 itree_node_set_region (tree, node, CHAR_TO_BYTE (node->begin),
1019 CHAR_TO_BYTE (node->end));
1020 }
1021 }
1022 SAFE_FREE ();
967} 1023}
968 1024
969/* Reinitialize everything about a buffer except its name and contents 1025/* Reinitialize everything about a buffer except its name and contents
@@ -993,9 +1049,7 @@ reset_buffer (register struct buffer *b)
993 b->auto_save_failure_time = 0; 1049 b->auto_save_failure_time = 0;
994 bset_auto_save_file_name (b, Qnil); 1050 bset_auto_save_file_name (b, Qnil);
995 bset_read_only (b, Qnil); 1051 bset_read_only (b, Qnil);
996 set_buffer_overlays_before (b, NULL); 1052 b->overlays = NULL;
997 set_buffer_overlays_after (b, NULL);
998 b->overlay_center = BEG;
999 bset_mark_active (b, Qnil); 1053 bset_mark_active (b, Qnil);
1000 bset_point_before_scroll (b, Qnil); 1054 bset_point_before_scroll (b, Qnil);
1001 bset_file_format (b, Qnil); 1055 bset_file_format (b, Qnil);
@@ -1978,10 +2032,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1978 2032
1979 /* Perhaps we should explicitly free the interval tree here... */ 2033 /* Perhaps we should explicitly free the interval tree here... */
1980 } 2034 }
1981 /* Since we've unlinked the markers, the overlays can't be here any more 2035 delete_all_overlays (b);
1982 either. */ 2036 free_buffer_overlays (b);
1983 set_buffer_overlays_before (b, NULL);
1984 set_buffer_overlays_after (b, NULL);
1985 2037
1986 /* Reset the local variables, so that this buffer's local values 2038 /* Reset the local variables, so that this buffer's local values
1987 won't be protected from GC. They would be protected 2039 won't be protected from GC. They would be protected
@@ -2381,6 +2433,23 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
2381 return byte_pos; 2433 return byte_pos;
2382} 2434}
2383 2435
2436static void
2437swap_buffer_overlays (struct buffer *buffer, struct buffer *other)
2438{
2439 struct itree_node *node;
2440
2441 ITREE_FOREACH (node, buffer->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
2442 XOVERLAY (node->data)->buffer = other;
2443
2444 ITREE_FOREACH (node, other->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
2445 XOVERLAY (node->data)->buffer = buffer;
2446
2447 /* Swap the interval trees. */
2448 void *tmp = buffer->overlays;
2449 buffer->overlays = other->overlays;
2450 other->overlays = tmp;
2451}
2452
2384DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, 2453DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2385 1, 1, 0, 2454 1, 1, 0,
2386 doc: /* Swap the text between current buffer and BUFFER. 2455 doc: /* Swap the text between current buffer and BUFFER.
@@ -2452,9 +2521,6 @@ results, see Info node `(elisp)Swapping Text'. */)
2452 current_buffer->prevent_redisplay_optimizations_p = 1; 2521 current_buffer->prevent_redisplay_optimizations_p = 1;
2453 other_buffer->prevent_redisplay_optimizations_p = 1; 2522 other_buffer->prevent_redisplay_optimizations_p = 1;
2454 swapfield (long_line_optimizations_p, bool_bf); 2523 swapfield (long_line_optimizations_p, bool_bf);
2455 swapfield (overlays_before, struct Lisp_Overlay *);
2456 swapfield (overlays_after, struct Lisp_Overlay *);
2457 swapfield (overlay_center, ptrdiff_t);
2458 swapfield_ (undo_list, Lisp_Object); 2524 swapfield_ (undo_list, Lisp_Object);
2459 swapfield_ (mark, Lisp_Object); 2525 swapfield_ (mark, Lisp_Object);
2460 swapfield_ (mark_active, Lisp_Object); /* Belongs with the `mark'. */ 2526 swapfield_ (mark_active, Lisp_Object); /* Belongs with the `mark'. */
@@ -2481,6 +2547,7 @@ results, see Info node `(elisp)Swapping Text'. */)
2481 current_buffer->text->end_unchanged = current_buffer->text->gpt; 2547 current_buffer->text->end_unchanged = current_buffer->text->gpt;
2482 other_buffer->text->beg_unchanged = other_buffer->text->gpt; 2548 other_buffer->text->beg_unchanged = other_buffer->text->gpt;
2483 other_buffer->text->end_unchanged = other_buffer->text->gpt; 2549 other_buffer->text->end_unchanged = other_buffer->text->gpt;
2550 swap_buffer_overlays (current_buffer, other_buffer);
2484 { 2551 {
2485 struct Lisp_Marker *m; 2552 struct Lisp_Marker *m;
2486 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 2553 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
@@ -2597,7 +2664,8 @@ current buffer is cleared. */)
2597 2664
2598 /* Do this first, so it can use CHAR_TO_BYTE 2665 /* Do this first, so it can use CHAR_TO_BYTE
2599 to calculate the old correspondences. */ 2666 to calculate the old correspondences. */
2600 set_intervals_multibyte (0); 2667 set_intervals_multibyte (false);
2668 set_overlays_multibyte (false);
2601 2669
2602 bset_enable_multibyte_characters (current_buffer, Qnil); 2670 bset_enable_multibyte_characters (current_buffer, Qnil);
2603 2671
@@ -2784,7 +2852,8 @@ current buffer is cleared. */)
2784 /* FIXME: Is it worth the trouble, really? Couldn't we just throw 2852 /* FIXME: Is it worth the trouble, really? Couldn't we just throw
2785 away all the text-properties instead of trying to guess how 2853 away all the text-properties instead of trying to guess how
2786 to adjust them? AFAICT the result is not reliable anyway. */ 2854 to adjust them? AFAICT the result is not reliable anyway. */
2787 set_intervals_multibyte (1); 2855 set_intervals_multibyte (true);
2856 set_overlays_multibyte (true);
2788 } 2857 }
2789 2858
2790 if (!EQ (old_undo, Qt)) 2859 if (!EQ (old_undo, Qt))
@@ -2867,272 +2936,159 @@ the normal hook `change-major-mode-hook'. */)
2867} 2936}
2868 2937
2869 2938
2870/* Find all the overlays in the current buffer that contain position POS. 2939/* Find all the overlays in the current buffer that overlap the range
2940 [BEG, END).
2941
2942 If EMPTY is true, include empty overlays in that range and also at
2943 END, provided END denotes the position at the end of the accessible
2944 part of the buffer.
2945
2946 If TRAILING is true, include overlays that begin at END, provided
2947 END denotes the position at the end of the accessible part of the
2948 buffer.
2949
2871 Return the number found, and store them in a vector in *VEC_PTR. 2950 Return the number found, and store them in a vector in *VEC_PTR.
2872 Store in *LEN_PTR the size allocated for the vector. 2951 Store in *LEN_PTR the size allocated for the vector.
2873 Store in *NEXT_PTR the next position after POS where an overlay starts, 2952 Store in *NEXT_PTR the next position after POS where an overlay starts,
2874 or ZV if there are no more overlays between POS and ZV. 2953 or ZV if there are no more overlays.
2875 Store in *PREV_PTR the previous position before POS where an overlay ends, 2954 NEXT_PTR may be 0, meaning don't store that info.
2876 or where an overlay starts which ends at or after POS;
2877 or BEGV if there are no such overlays from BEGV to POS.
2878 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2879 2955
2880 *VEC_PTR and *LEN_PTR should contain a valid vector and size 2956 *VEC_PTR and *LEN_PTR should contain a valid vector and size
2881 when this function is called. 2957 when this function is called.
2882 2958
2883 If EXTEND, make the vector bigger if necessary. 2959 If EXTEND, make the vector bigger if necessary. If not, never
2884 If not, never extend the vector, 2960 extend the vector, and store only as many overlays as will fit.
2885 and store only as many overlays as will fit.
2886 But still return the total number of overlays. 2961 But still return the total number of overlays.
2887 2962*/
2888 If CHANGE_REQ, any position written into *PREV_PTR or
2889 *NEXT_PTR is guaranteed to be not equal to POS, unless it is the
2890 default (BEGV or ZV). */
2891 2963
2892ptrdiff_t 2964ptrdiff_t
2893overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr, 2965overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
2894 ptrdiff_t *len_ptr, 2966 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
2895 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req) 2967 bool empty, bool trailing,
2968 ptrdiff_t *next_ptr)
2896{ 2969{
2897 ptrdiff_t idx = 0; 2970 ptrdiff_t idx = 0;
2898 ptrdiff_t len = *len_ptr; 2971 ptrdiff_t len = *len_ptr;
2899 Lisp_Object *vec = *vec_ptr;
2900 ptrdiff_t next = ZV; 2972 ptrdiff_t next = ZV;
2901 ptrdiff_t prev = BEGV; 2973 Lisp_Object *vec = *vec_ptr;
2902 bool inhibit_storing = 0; 2974 struct itree_node *node;
2903
2904 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
2905 tail; tail = tail->next)
2906 {
2907 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
2908 Lisp_Object start = OVERLAY_START (overlay);
2909 Lisp_Object end = OVERLAY_END (overlay);
2910 ptrdiff_t endpos = OVERLAY_POSITION (end);
2911 if (endpos < pos)
2912 {
2913 if (prev < endpos)
2914 prev = endpos;
2915 break;
2916 }
2917 ptrdiff_t startpos = OVERLAY_POSITION (start);
2918 /* This one ends at or after POS
2919 so its start counts for PREV_PTR if it's before POS. */
2920 if (prev < startpos && startpos < pos)
2921 prev = startpos;
2922 if (endpos == pos)
2923 continue;
2924 if (startpos <= pos)
2925 {
2926 if (idx == len)
2927 {
2928 /* The supplied vector is full.
2929 Either make it bigger, or don't store any more in it. */
2930 if (extend)
2931 {
2932 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2933 sizeof *vec);
2934 *vec_ptr = vec;
2935 len = *len_ptr;
2936 }
2937 else
2938 inhibit_storing = 1;
2939 }
2940 2975
2941 if (!inhibit_storing) 2976 /* Extend the search range if overlays beginning at ZV are
2942 vec[idx] = overlay; 2977 wanted. */
2943 /* Keep counting overlays even if we can't return them all. */ 2978 ptrdiff_t search_end = ZV;
2944 idx++; 2979 if (end >= ZV && (empty || trailing))
2945 } 2980 ++search_end;
2946 else if (startpos < next)
2947 next = startpos;
2948 }
2949 2981
2950 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 2982 ITREE_FOREACH (node, current_buffer->overlays, beg, search_end,
2951 tail; tail = tail->next) 2983 ASCENDING)
2952 { 2984 {
2953 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 2985 if (node->begin > end)
2954 Lisp_Object start = OVERLAY_START (overlay); 2986 {
2955 Lisp_Object end = OVERLAY_END (overlay); 2987 next = min (next, node->begin);
2956 ptrdiff_t startpos = OVERLAY_POSITION (start); 2988 ITREE_FOREACH_ABORT ();
2957 if (pos < startpos) 2989 break;
2958 { 2990 }
2959 if (startpos < next) 2991 else if (node->begin == end)
2960 next = startpos; 2992 {
2961 break; 2993 next = node->begin;
2962 } 2994 if ((! empty || end < ZV) && beg < end)
2963 ptrdiff_t endpos = OVERLAY_POSITION (end); 2995 {
2964 if (pos < endpos) 2996 ITREE_FOREACH_ABORT ();
2965 { 2997 break;
2966 if (idx == len) 2998 }
2967 { 2999 if (empty && node->begin != node->end)
2968 if (extend) 3000 continue;
2969 { 3001 }
2970 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2971 sizeof *vec);
2972 *vec_ptr = vec;
2973 len = *len_ptr;
2974 }
2975 else
2976 inhibit_storing = 1;
2977 }
2978 3002
2979 if (!inhibit_storing) 3003 if (! empty && node->begin == node->end)
2980 vec[idx] = overlay; 3004 continue;
2981 idx++;
2982 3005
2983 if (startpos < pos && startpos > prev) 3006 if (extend && idx == len)
2984 prev = startpos; 3007 {
2985 } 3008 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2986 else if (endpos < pos && endpos > prev) 3009 sizeof *vec);
2987 prev = endpos; 3010 *vec_ptr = vec;
2988 else if (endpos == pos && startpos > prev 3011 len = *len_ptr;
2989 && (!change_req || startpos < pos)) 3012 }
2990 prev = startpos; 3013 if (idx < len)
3014 vec[idx] = node->data;
3015 /* Keep counting overlays even if we can't return them all. */
3016 idx++;
2991 } 3017 }
2992
2993 if (next_ptr) 3018 if (next_ptr)
2994 *next_ptr = next; 3019 *next_ptr = next ? next : ZV;
2995 if (prev_ptr) 3020
2996 *prev_ptr = prev;
2997 return idx; 3021 return idx;
2998} 3022}
2999
3000/* Find all the overlays in the current buffer that overlap the range
3001 BEG-END, or are empty at BEG, or are empty at END provided END
3002 denotes the position at the end of the current buffer.
3003 3023
3004 Return the number found, and store them in a vector in *VEC_PTR. 3024/* Find all non-empty overlays in the current buffer that contain
3005 Store in *LEN_PTR the size allocated for the vector. 3025 position POS.
3006 Store in *NEXT_PTR the next position after POS where an overlay starts,
3007 or ZV if there are no more overlays.
3008 Store in *PREV_PTR the previous position before POS where an overlay ends,
3009 or BEGV if there are no previous overlays.
3010 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
3011 3026
3012 *VEC_PTR and *LEN_PTR should contain a valid vector and size 3027 See overlays_in for the meaning of the arguments.
3013 when this function is called. 3028 */
3014 3029
3015 If EXTEND, make the vector bigger if necessary. 3030ptrdiff_t
3016 If not, never extend the vector, 3031overlays_at (ptrdiff_t pos, bool extend,
3017 and store only as many overlays as will fit. 3032 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
3018 But still return the total number of overlays. */ 3033 ptrdiff_t *next_ptr)
3034{
3035 return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr,
3036 false, true, next_ptr);
3037}
3019 3038
3020static ptrdiff_t 3039ptrdiff_t
3021overlays_in (EMACS_INT beg, EMACS_INT end, bool extend, 3040next_overlay_change (ptrdiff_t pos)
3022 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
3023 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
3024{ 3041{
3025 ptrdiff_t idx = 0;
3026 ptrdiff_t len = *len_ptr;
3027 Lisp_Object *vec = *vec_ptr;
3028 ptrdiff_t next = ZV; 3042 ptrdiff_t next = ZV;
3029 ptrdiff_t prev = BEGV; 3043 struct itree_node *node;
3030 bool inhibit_storing = 0;
3031 bool end_is_Z = end == ZV;
3032 3044
3033 for (struct Lisp_Overlay *tail = current_buffer->overlays_before; 3045 ITREE_FOREACH (node, current_buffer->overlays, pos, next, ASCENDING)
3034 tail; tail = tail->next)
3035 { 3046 {
3036 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 3047 if (node->begin > pos)
3037 Lisp_Object ostart = OVERLAY_START (overlay); 3048 {
3038 Lisp_Object oend = OVERLAY_END (overlay); 3049 /* If we reach this branch, node->begin must be the least upper bound
3039 ptrdiff_t endpos = OVERLAY_POSITION (oend); 3050 of pos, because the search is limited to [pos,next) . */
3040 if (endpos < beg) 3051 eassert (node->begin < next);
3041 { 3052 next = node->begin;
3042 if (prev < endpos) 3053 ITREE_FOREACH_ABORT ();
3043 prev = endpos; 3054 break;
3044 break; 3055 }
3045 } 3056 else if (node->begin < node->end && node->end < next)
3046 ptrdiff_t startpos = OVERLAY_POSITION (ostart); 3057 {
3047 /* Count an interval if it overlaps the range, is empty at the 3058 next = node->end;
3048 start of the range, or is empty at END provided END denotes the 3059 ITREE_FOREACH_NARROW (pos, next);
3049 end of the buffer. */ 3060 }
3050 if ((beg < endpos && startpos < end)
3051 || (startpos == endpos
3052 && (beg == endpos || (end_is_Z && endpos == end))))
3053 {
3054 if (idx == len)
3055 {
3056 /* The supplied vector is full.
3057 Either make it bigger, or don't store any more in it. */
3058 if (extend)
3059 {
3060 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3061 sizeof *vec);
3062 *vec_ptr = vec;
3063 len = *len_ptr;
3064 }
3065 else
3066 inhibit_storing = 1;
3067 }
3068
3069 if (!inhibit_storing)
3070 vec[idx] = overlay;
3071 /* Keep counting overlays even if we can't return them all. */
3072 idx++;
3073 }
3074 else if (startpos < next)
3075 next = startpos;
3076 } 3061 }
3077 3062
3078 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 3063 return next;
3079 tail; tail = tail->next) 3064}
3080 {
3081 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3082 Lisp_Object ostart = OVERLAY_START (overlay);
3083 Lisp_Object oend = OVERLAY_END (overlay);
3084 ptrdiff_t startpos = OVERLAY_POSITION (ostart);
3085 if (end < startpos)
3086 {
3087 if (startpos < next)
3088 next = startpos;
3089 break;
3090 }
3091 ptrdiff_t endpos = OVERLAY_POSITION (oend);
3092 /* Count an interval if it overlaps the range, is empty at the
3093 start of the range, or is empty at END provided END denotes the
3094 end of the buffer. */
3095 if ((beg < endpos && startpos < end)
3096 || (startpos == endpos
3097 && (beg == endpos || (end_is_Z && endpos == end))))
3098 {
3099 if (idx == len)
3100 {
3101 if (extend)
3102 {
3103 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3104 sizeof *vec);
3105 *vec_ptr = vec;
3106 len = *len_ptr;
3107 }
3108 else
3109 inhibit_storing = 1;
3110 }
3111 3065
3112 if (!inhibit_storing) 3066ptrdiff_t
3113 vec[idx] = overlay; 3067previous_overlay_change (ptrdiff_t pos)
3114 idx++; 3068{
3115 } 3069 struct itree_node *node;
3116 else if (endpos < beg && endpos > prev) 3070 ptrdiff_t prev = BEGV;
3117 prev = endpos; 3071
3072 ITREE_FOREACH (node, current_buffer->overlays, prev, pos, DESCENDING)
3073 {
3074 if (node->end < pos)
3075 prev = node->end;
3076 else
3077 prev = max (prev, node->begin);
3078 ITREE_FOREACH_NARROW (prev, pos);
3118 } 3079 }
3119 3080
3120 if (next_ptr) 3081 return prev;
3121 *next_ptr = next;
3122 if (prev_ptr)
3123 *prev_ptr = prev;
3124 return idx;
3125} 3082}
3126 3083
3127
3128/* Return true if there exists an overlay with a non-nil 3084/* Return true if there exists an overlay with a non-nil
3129 `mouse-face' property overlapping OVERLAY. */ 3085 `mouse-face' property overlapping OVERLAY. */
3130 3086
3131bool 3087bool
3132mouse_face_overlay_overlaps (Lisp_Object overlay) 3088mouse_face_overlay_overlaps (Lisp_Object overlay)
3133{ 3089{
3134 ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay)); 3090 ptrdiff_t start = OVERLAY_START (overlay);
3135 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3091 ptrdiff_t end = OVERLAY_END (overlay);
3136 ptrdiff_t n, i, size; 3092 ptrdiff_t n, i, size;
3137 Lisp_Object *v, tem; 3093 Lisp_Object *v, tem;
3138 Lisp_Object vbuf[10]; 3094 Lisp_Object vbuf[10];
@@ -3140,11 +3096,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
3140 3096
3141 size = ARRAYELTS (vbuf); 3097 size = ARRAYELTS (vbuf);
3142 v = vbuf; 3098 v = vbuf;
3143 n = overlays_in (start, end, 0, &v, &size, NULL, NULL); 3099 n = overlays_in (start, end, 0, &v, &size, true, false, NULL);
3144 if (n > size) 3100 if (n > size)
3145 { 3101 {
3146 SAFE_NALLOCA (v, 1, n); 3102 SAFE_NALLOCA (v, 1, n);
3147 overlays_in (start, end, 0, &v, &n, NULL, NULL); 3103 overlays_in (start, end, 0, &v, &n, true, false, NULL);
3148 } 3104 }
3149 3105
3150 for (i = 0; i < n; ++i) 3106 for (i = 0; i < n; ++i)
@@ -3169,11 +3125,11 @@ disable_line_numbers_overlay_at_eob (void)
3169 3125
3170 size = ARRAYELTS (vbuf); 3126 size = ARRAYELTS (vbuf);
3171 v = vbuf; 3127 v = vbuf;
3172 n = overlays_in (ZV, ZV, 0, &v, &size, NULL, NULL); 3128 n = overlays_in (ZV, ZV, 0, &v, &size, false, false, NULL);
3173 if (n > size) 3129 if (n > size)
3174 { 3130 {
3175 SAFE_NALLOCA (v, 1, n); 3131 SAFE_NALLOCA (v, 1, n);
3176 overlays_in (ZV, ZV, 0, &v, &n, NULL, NULL); 3132 overlays_in (ZV, ZV, 0, &v, &n, false, false, NULL);
3177 } 3133 }
3178 3134
3179 for (i = 0; i < n; ++i) 3135 for (i = 0; i < n; ++i)
@@ -3186,47 +3142,28 @@ disable_line_numbers_overlay_at_eob (void)
3186} 3142}
3187 3143
3188 3144
3189/* Fast function to just test if we're at an overlay boundary. */ 3145/* Fast function to just test if we're at an overlay boundary.
3146
3147 Returns true if some overlay starts or ends (or both) at POS,
3148*/
3190bool 3149bool
3191overlay_touches_p (ptrdiff_t pos) 3150overlay_touches_p (ptrdiff_t pos)
3192{ 3151{
3193 for (struct Lisp_Overlay *tail = current_buffer->overlays_before; 3152 struct itree_node *node;
3194 tail; tail = tail->next)
3195 {
3196 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3197 eassert (OVERLAYP (overlay));
3198 3153
3199 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3154 /* We need to find overlays ending in pos, as well as empty ones at
3200 if (endpos < pos) 3155 pos. */
3201 break; 3156 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
3202 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos) 3157 if (node->begin == pos || node->end == pos)
3203 return 1; 3158 {
3204 } 3159 ITREE_FOREACH_ABORT ();
3205 3160 return true;
3206 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 3161 }
3207 tail; tail = tail->next) 3162 return false;
3208 {
3209 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3210 eassert (OVERLAYP (overlay));
3211
3212 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3213 if (pos < startpos)
3214 break;
3215 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
3216 return 1;
3217 }
3218 return 0;
3219} 3163}
3220
3221struct sortvec
3222{
3223 Lisp_Object overlay;
3224 ptrdiff_t beg, end;
3225 EMACS_INT priority;
3226 EMACS_INT spriority; /* Secondary priority. */
3227};
3228 3164
3229static int 3165
3166int
3230compare_overlays (const void *v1, const void *v2) 3167compare_overlays (const void *v1, const void *v2)
3231{ 3168{
3232 const struct sortvec *s1 = v1; 3169 const struct sortvec *s1 = v1;
@@ -3255,6 +3192,33 @@ compare_overlays (const void *v1, const void *v2)
3255 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1; 3192 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3256} 3193}
3257 3194
3195void
3196make_sortvec_item (struct sortvec *item, Lisp_Object overlay)
3197{
3198 Lisp_Object tem;
3199 /* This overlay is good and counts: put it into sortvec. */
3200 item->overlay = overlay;
3201 item->beg = OVERLAY_START (overlay);
3202 item->end = OVERLAY_END (overlay);
3203 tem = Foverlay_get (overlay, Qpriority);
3204 if (NILP (tem))
3205 {
3206 item->priority = 0;
3207 item->spriority = 0;
3208 }
3209 else if (FIXNUMP (tem))
3210 {
3211 item->priority = XFIXNUM (tem);
3212 item->spriority = 0;
3213 }
3214 else if (CONSP (tem))
3215 {
3216 Lisp_Object car = XCAR (tem);
3217 Lisp_Object cdr = XCDR (tem);
3218 item->priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
3219 item->spriority = FIXNUMP (cdr) ? XFIXNUM (cdr) : 0;
3220 }
3221}
3258/* Sort an array of overlays by priority. The array is modified in place. 3222/* Sort an array of overlays by priority. The array is modified in place.
3259 The return value is the new size; this may be smaller than the original 3223 The return value is the new size; this may be smaller than the original
3260 size if some of the overlays were invalid or were window-specific. */ 3224 size if some of the overlays were invalid or were window-specific. */
@@ -3271,47 +3235,18 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
3271 3235
3272 for (i = 0, j = 0; i < noverlays; i++) 3236 for (i = 0, j = 0; i < noverlays; i++)
3273 { 3237 {
3274 Lisp_Object tem;
3275 Lisp_Object overlay; 3238 Lisp_Object overlay;
3276 3239
3277 overlay = overlay_vec[i]; 3240 overlay = overlay_vec[i];
3278 if (OVERLAYP (overlay) 3241 if (OVERLAYP (overlay)
3279 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 3242 && OVERLAY_START (overlay) > 0
3280 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) 3243 && OVERLAY_END (overlay) > 0)
3281 { 3244 {
3282 /* If we're interested in a specific window, then ignore 3245 /* If we're interested in a specific window, then ignore
3283 overlays that are limited to some other window. */ 3246 overlays that are limited to some other window. */
3284 if (w) 3247 if (w && ! overlay_matches_window (w, overlay))
3285 { 3248 continue;
3286 Lisp_Object window; 3249 make_sortvec_item (sortvec + j, overlay);
3287
3288 window = Foverlay_get (overlay, Qwindow);
3289 if (WINDOWP (window) && XWINDOW (window) != w)
3290 continue;
3291 }
3292
3293 /* This overlay is good and counts: put it into sortvec. */
3294 sortvec[j].overlay = overlay;
3295 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3296 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
3297 tem = Foverlay_get (overlay, Qpriority);
3298 if (NILP (tem))
3299 {
3300 sortvec[j].priority = 0;
3301 sortvec[j].spriority = 0;
3302 }
3303 else if (FIXNUMP (tem))
3304 {
3305 sortvec[j].priority = XFIXNUM (tem);
3306 sortvec[j].spriority = 0;
3307 }
3308 else if (CONSP (tem))
3309 {
3310 Lisp_Object car = XCAR (tem);
3311 Lisp_Object cdr = XCDR (tem);
3312 sortvec[j].priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
3313 sortvec[j].spriority = FIXNUMP (cdr) ? XFIXNUM (cdr) : 0;
3314 }
3315 j++; 3250 j++;
3316 } 3251 }
3317 } 3252 }
@@ -3426,25 +3361,27 @@ ptrdiff_t
3426overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) 3361overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3427{ 3362{
3428 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 3363 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
3364 struct itree_node *node;
3429 3365
3430 overlay_heads.used = overlay_heads.bytes = 0; 3366 overlay_heads.used = overlay_heads.bytes = 0;
3431 overlay_tails.used = overlay_tails.bytes = 0; 3367 overlay_tails.used = overlay_tails.bytes = 0;
3432 for (struct Lisp_Overlay *ov = current_buffer->overlays_before; 3368
3433 ov; ov = ov->next) 3369 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
3434 { 3370 {
3435 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike); 3371 Lisp_Object overlay = node->data;
3436 eassert (OVERLAYP (overlay)); 3372 eassert (OVERLAYP (overlay));
3437 3373
3438 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3374 ptrdiff_t startpos = node->begin;
3439 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3375 ptrdiff_t endpos = node->end;
3440 if (endpos < pos) 3376
3441 break;
3442 if (endpos != pos && startpos != pos) 3377 if (endpos != pos && startpos != pos)
3443 continue; 3378 continue;
3444 Lisp_Object window = Foverlay_get (overlay, Qwindow); 3379 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3445 if (WINDOWP (window) && XWINDOW (window) != w) 3380 if (WINDOWP (window) && XWINDOW (window) != w)
3446 continue; 3381 continue;
3447 Lisp_Object str; 3382 Lisp_Object str;
3383 /* FIXME: Are we really sure that `record_overlay_string` can
3384 never cause a non-local exit? */
3448 if (startpos == pos 3385 if (startpos == pos
3449 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3386 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3450 record_overlay_string (&overlay_heads, str, 3387 record_overlay_string (&overlay_heads, str,
@@ -3459,36 +3396,7 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3459 Foverlay_get (overlay, Qpriority), 3396 Foverlay_get (overlay, Qpriority),
3460 endpos - startpos); 3397 endpos - startpos);
3461 } 3398 }
3462 for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
3463 ov; ov = ov->next)
3464 {
3465 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
3466 eassert (OVERLAYP (overlay));
3467 3399
3468 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3469 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3470 if (startpos > pos)
3471 break;
3472 if (endpos != pos && startpos != pos)
3473 continue;
3474 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3475 if (WINDOWP (window) && XWINDOW (window) != w)
3476 continue;
3477 Lisp_Object str;
3478 if (startpos == pos
3479 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3480 record_overlay_string (&overlay_heads, str,
3481 (startpos == endpos
3482 ? Foverlay_get (overlay, Qafter_string)
3483 : Qnil),
3484 Foverlay_get (overlay, Qpriority),
3485 endpos - startpos);
3486 else if (endpos == pos
3487 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3488 record_overlay_string (&overlay_tails, str, Qnil,
3489 Foverlay_get (overlay, Qpriority),
3490 endpos - startpos);
3491 }
3492 if (overlay_tails.used > 1) 3400 if (overlay_tails.used > 1)
3493 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr), 3401 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
3494 cmp_for_strings); 3402 cmp_for_strings);
@@ -3543,384 +3451,26 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3543 } 3451 }
3544 return 0; 3452 return 0;
3545} 3453}
3546
3547/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
3548
3549void
3550recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
3551{
3552 struct Lisp_Overlay *prev, *next;
3553
3554 /* See if anything in overlays_before should move to overlays_after. */
3555
3556 /* We don't strictly need prev in this loop; it should always be nil.
3557 But we use it for symmetry and in case that should cease to be true
3558 with some future change. */
3559 prev = NULL;
3560 for (struct Lisp_Overlay *tail = buf->overlays_before;
3561 tail; prev = tail, tail = next)
3562 {
3563 next = tail->next;
3564 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3565 eassert (OVERLAYP (overlay));
3566
3567 Lisp_Object beg = OVERLAY_START (overlay);
3568 Lisp_Object end = OVERLAY_END (overlay);
3569
3570 if (OVERLAY_POSITION (end) > pos)
3571 {
3572 /* OVERLAY needs to be moved. */
3573 ptrdiff_t where = OVERLAY_POSITION (beg);
3574 struct Lisp_Overlay *other, *other_prev;
3575
3576 /* Splice the cons cell TAIL out of overlays_before. */
3577 if (prev)
3578 prev->next = next;
3579 else
3580 set_buffer_overlays_before (buf, next);
3581
3582 /* Search thru overlays_after for where to put it. */
3583 other_prev = NULL;
3584 for (other = buf->overlays_after; other;
3585 other_prev = other, other = other->next)
3586 {
3587 Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
3588 eassert (OVERLAYP (otheroverlay));
3589
3590 Lisp_Object otherbeg = OVERLAY_START (otheroverlay);
3591 if (OVERLAY_POSITION (otherbeg) >= where)
3592 break;
3593 }
3594
3595 /* Add TAIL to overlays_after before OTHER. */
3596 tail->next = other;
3597 if (other_prev)
3598 other_prev->next = tail;
3599 else
3600 set_buffer_overlays_after (buf, tail);
3601 tail = prev;
3602 }
3603 else
3604 /* We've reached the things that should stay in overlays_before.
3605 All the rest of overlays_before must end even earlier,
3606 so stop now. */
3607 break;
3608 }
3609
3610 /* See if anything in overlays_after should be in overlays_before. */
3611 prev = NULL;
3612 for (struct Lisp_Overlay *tail = buf->overlays_after;
3613 tail; prev = tail, tail = next)
3614 {
3615 next = tail->next;
3616 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3617 eassert (OVERLAYP (overlay));
3618
3619 Lisp_Object beg = OVERLAY_START (overlay);
3620 Lisp_Object end = OVERLAY_END (overlay);
3621
3622 /* Stop looking, when we know that nothing further
3623 can possibly end before POS. */
3624 if (OVERLAY_POSITION (beg) > pos)
3625 break;
3626
3627 if (OVERLAY_POSITION (end) <= pos)
3628 {
3629 /* OVERLAY needs to be moved. */
3630 ptrdiff_t where = OVERLAY_POSITION (end);
3631 struct Lisp_Overlay *other, *other_prev;
3632
3633 /* Splice the cons cell TAIL out of overlays_after. */
3634 if (prev)
3635 prev->next = next;
3636 else
3637 set_buffer_overlays_after (buf, next);
3638
3639 /* Search thru overlays_before for where to put it. */
3640 other_prev = NULL;
3641 for (other = buf->overlays_before; other;
3642 other_prev = other, other = other->next)
3643 {
3644 Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
3645 eassert (OVERLAYP (otheroverlay));
3646
3647 Lisp_Object otherend = OVERLAY_END (otheroverlay);
3648 if (OVERLAY_POSITION (otherend) <= where)
3649 break;
3650 }
3651
3652 /* Add TAIL to overlays_before before OTHER. */
3653 tail->next = other;
3654 if (other_prev)
3655 other_prev->next = tail;
3656 else
3657 set_buffer_overlays_before (buf, tail);
3658 tail = prev;
3659 }
3660 }
3661
3662 buf->overlay_center = pos;
3663}
3664 3454
3455
3665void 3456void
3666adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length) 3457adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
3667{ 3458{
3668 /* After an insertion, the lists are still sorted properly, 3459 /* After an insertion, the lists are still sorted properly,
3669 but we may need to update the value of the overlay center. */ 3460 but we may need to update the value of the overlay center. */
3670 if (current_buffer->overlay_center >= pos) 3461 if (! current_buffer->overlays)
3671 current_buffer->overlay_center += length; 3462 return;
3463 itree_insert_gap (current_buffer->overlays, pos, length);
3672} 3464}
3673 3465
3674void 3466void
3675adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) 3467adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
3676{ 3468{
3677 if (current_buffer->overlay_center < pos) 3469 if (! current_buffer->overlays)
3678 /* The deletion was to our right. No change needed; the before- and
3679 after-lists are still consistent. */
3680 ;
3681 else if (current_buffer->overlay_center - pos > length)
3682 /* The deletion was to our left. We need to adjust the center value
3683 to account for the change in position, but the lists are consistent
3684 given the new value. */
3685 current_buffer->overlay_center -= length;
3686 else
3687 /* We're right in the middle. There might be things on the after-list
3688 that now belong on the before-list. Recentering will move them,
3689 and also update the center point. */
3690 recenter_overlay_lists (current_buffer, pos);
3691}
3692
3693/* Fix up overlays that were garbled as a result of permuting markers
3694 in the range START through END. Any overlay with at least one
3695 endpoint in this range will need to be unlinked from the overlay
3696 list and reinserted in its proper place.
3697 Such an overlay might even have negative size at this point.
3698 If so, we'll make the overlay empty. */
3699void
3700fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3701{
3702 struct Lisp_Overlay *before_list UNINIT;
3703 struct Lisp_Overlay *after_list UNINIT;
3704 /* These are either nil, indicating that before_list or after_list
3705 should be assigned, or the cons cell the cdr of which should be
3706 assigned. */
3707 struct Lisp_Overlay *beforep = NULL, *afterp = NULL;
3708 /* 'Parent', likewise, indicates a cons cell or
3709 current_buffer->overlays_before or overlays_after, depending
3710 which loop we're in. */
3711 struct Lisp_Overlay *parent;
3712
3713 /* This algorithm shifts links around instead of consing and GCing.
3714 The loop invariant is that before_list (resp. after_list) is a
3715 well-formed list except that its last element, the CDR of beforep
3716 (resp. afterp) if beforep (afterp) isn't nil or before_list
3717 (after_list) if it is, is still uninitialized. So it's not a bug
3718 that before_list isn't initialized, although it may look
3719 strange. */
3720 parent = NULL;
3721 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
3722 tail; tail = tail->next)
3723 {
3724 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3725
3726 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3727 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3728
3729 /* If the overlay is backwards, make it empty. */
3730 if (endpos < startpos)
3731 {
3732 startpos = endpos;
3733 Fset_marker (OVERLAY_START (overlay), make_fixnum (startpos),
3734 Qnil);
3735 }
3736
3737 if (endpos < start)
3738 break;
3739
3740 if (endpos < end
3741 || (startpos >= start && startpos < end))
3742 {
3743 /* Add it to the end of the wrong list. Later on,
3744 recenter_overlay_lists will move it to the right place. */
3745 if (endpos < current_buffer->overlay_center)
3746 {
3747 if (!afterp)
3748 after_list = tail;
3749 else
3750 afterp->next = tail;
3751 afterp = tail;
3752 }
3753 else
3754 {
3755 if (!beforep)
3756 before_list = tail;
3757 else
3758 beforep->next = tail;
3759 beforep = tail;
3760 }
3761 if (!parent)
3762 set_buffer_overlays_before (current_buffer, tail->next);
3763 else
3764 parent->next = tail->next;
3765 }
3766 else
3767 parent = tail;
3768 }
3769 parent = NULL;
3770 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
3771 tail; tail = tail->next)
3772 {
3773 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3774
3775 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3776 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3777
3778 /* If the overlay is backwards, make it empty. */
3779 if (endpos < startpos)
3780 {
3781 startpos = endpos;
3782 Fset_marker (OVERLAY_START (overlay), make_fixnum (startpos),
3783 Qnil);
3784 }
3785
3786 if (startpos >= end)
3787 break;
3788
3789 if (startpos >= start
3790 || (endpos >= start && endpos < end))
3791 {
3792 if (endpos < current_buffer->overlay_center)
3793 {
3794 if (!afterp)
3795 after_list = tail;
3796 else
3797 afterp->next = tail;
3798 afterp = tail;
3799 }
3800 else
3801 {
3802 if (!beforep)
3803 before_list = tail;
3804 else
3805 beforep->next = tail;
3806 beforep = tail;
3807 }
3808 if (!parent)
3809 set_buffer_overlays_after (current_buffer, tail->next);
3810 else
3811 parent->next = tail->next;
3812 }
3813 else
3814 parent = tail;
3815 }
3816
3817 /* Splice the constructed (wrong) lists into the buffer's lists,
3818 and let the recenter function make it sane again. */
3819 if (beforep)
3820 {
3821 beforep->next = current_buffer->overlays_before;
3822 set_buffer_overlays_before (current_buffer, before_list);
3823 }
3824
3825 if (afterp)
3826 {
3827 afterp->next = current_buffer->overlays_after;
3828 set_buffer_overlays_after (current_buffer, after_list);
3829 }
3830 recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
3831}
3832
3833/* We have two types of overlay: the one whose ending marker is
3834 after-insertion-marker (this is the usual case) and the one whose
3835 ending marker is before-insertion-marker. When `overlays_before'
3836 contains overlays of the latter type and the former type in this
3837 order and both overlays end at inserting position, inserting a text
3838 increases only the ending marker of the latter type, which results
3839 in incorrect ordering of `overlays_before'.
3840
3841 This function fixes ordering of overlays in the slot
3842 `overlays_before' of the buffer *BP. Before the insertion, `point'
3843 was at PREV, and now is at POS. */
3844
3845void
3846fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
3847{
3848 /* If parent is nil, replace overlays_before; otherwise, parent->next. */
3849 struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
3850 Lisp_Object tem;
3851 ptrdiff_t end UNINIT;
3852
3853 /* After the insertion, the several overlays may be in incorrect
3854 order. The possibility is that, in the list `overlays_before',
3855 an overlay which ends at POS appears after an overlay which ends
3856 at PREV. Since POS is greater than PREV, we must fix the
3857 ordering of these overlays, by moving overlays ends at POS before
3858 the overlays ends at PREV. */
3859
3860 /* At first, find a place where disordered overlays should be linked
3861 in. It is where an overlay which end before POS exists. (i.e. an
3862 overlay whose ending marker is after-insertion-marker if disorder
3863 exists). */
3864 while (tail
3865 && (tem = make_lisp_ptr (tail, Lisp_Vectorlike),
3866 (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
3867 {
3868 parent = tail;
3869 tail = tail->next;
3870 }
3871
3872 /* If we don't find such an overlay,
3873 or the found one ends before PREV,
3874 or the found one is the last one in the list,
3875 we don't have to fix anything. */
3876 if (!tail)
3877 return;
3878 if (end < prev || !tail->next)
3879 return; 3470 return;
3880 3471 itree_delete_gap (current_buffer->overlays, pos, length);
3881 right_pair = parent;
3882 parent = tail;
3883 tail = tail->next;
3884
3885 /* Now, end position of overlays in the list TAIL should be before
3886 or equal to PREV. In the loop, an overlay which ends at POS is
3887 moved ahead to the place indicated by the CDR of RIGHT_PAIR. If
3888 we found an overlay which ends before PREV, the remaining
3889 overlays are in correct order. */
3890 while (tail)
3891 {
3892 tem = make_lisp_ptr (tail, Lisp_Vectorlike);
3893 end = OVERLAY_POSITION (OVERLAY_END (tem));
3894
3895 if (end == pos)
3896 { /* This overlay is disordered. */
3897 struct Lisp_Overlay *found = tail;
3898
3899 /* Unlink the found overlay. */
3900 tail = found->next;
3901 parent->next = tail;
3902 /* Move an overlay at RIGHT_PLACE to the next of the found one,
3903 and link it into the right place. */
3904 if (!right_pair)
3905 {
3906 found->next = bp->overlays_before;
3907 set_buffer_overlays_before (bp, found);
3908 }
3909 else
3910 {
3911 found->next = right_pair->next;
3912 right_pair->next = found;
3913 }
3914 }
3915 else if (end == prev)
3916 {
3917 parent = tail;
3918 tail = tail->next;
3919 }
3920 else /* No more disordered overlay. */
3921 break;
3922 }
3923} 3472}
3473
3924 3474
3925DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0, 3475DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
3926 doc: /* Return t if OBJECT is an overlay. */) 3476 doc: /* Return t if OBJECT is an overlay. */)
@@ -3942,7 +3492,7 @@ for the rear of the overlay advance when text is inserted there
3942 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, 3492 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
3943 Lisp_Object front_advance, Lisp_Object rear_advance) 3493 Lisp_Object front_advance, Lisp_Object rear_advance)
3944{ 3494{
3945 Lisp_Object overlay; 3495 Lisp_Object ov;
3946 struct buffer *b; 3496 struct buffer *b;
3947 3497
3948 if (NILP (buffer)) 3498 if (NILP (buffer))
@@ -3950,6 +3500,10 @@ for the rear of the overlay advance when text is inserted there
3950 else 3500 else
3951 CHECK_BUFFER (buffer); 3501 CHECK_BUFFER (buffer);
3952 3502
3503 b = XBUFFER (buffer);
3504 if (! BUFFER_LIVE_P (b))
3505 error ("Attempt to create overlay in a dead buffer");
3506
3953 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer)) 3507 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
3954 signal_error ("Marker points into wrong buffer", beg); 3508 signal_error ("Marker points into wrong buffer", beg);
3955 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer)) 3509 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
@@ -3964,39 +3518,16 @@ for the rear of the overlay advance when text is inserted there
3964 temp = beg; beg = end; end = temp; 3518 temp = beg; beg = end; end = temp;
3965 } 3519 }
3966 3520
3967 b = XBUFFER (buffer); 3521 ptrdiff_t obeg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3968 3522 ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), BUF_Z (b));
3969 beg = Fset_marker (Fmake_marker (), beg, buffer); 3523 ov = build_overlay (! NILP (front_advance),
3970 end = Fset_marker (Fmake_marker (), end, buffer); 3524 ! NILP (rear_advance), Qnil);
3971 3525 add_buffer_overlay (b, XOVERLAY (ov), obeg, oend);
3972 if (!NILP (front_advance))
3973 XMARKER (beg)->insertion_type = 1;
3974 if (!NILP (rear_advance))
3975 XMARKER (end)->insertion_type = 1;
3976
3977 overlay = build_overlay (beg, end, Qnil);
3978
3979 /* Put the new overlay on the wrong list. */
3980 end = OVERLAY_END (overlay);
3981 if (OVERLAY_POSITION (end) < b->overlay_center)
3982 {
3983 eassert (b->overlays_after || (XOVERLAY (overlay)->next == NULL));
3984 XOVERLAY (overlay)->next = b->overlays_after;
3985 set_buffer_overlays_after (b, XOVERLAY (overlay));
3986 }
3987 else
3988 {
3989 eassert (b->overlays_before || (XOVERLAY (overlay)->next == NULL));
3990 XOVERLAY (overlay)->next = b->overlays_before;
3991 set_buffer_overlays_before (b, XOVERLAY (overlay));
3992 }
3993 /* This puts it in the right list, and in the right order. */
3994 recenter_overlay_lists (b, b->overlay_center);
3995 3526
3996 /* We don't need to redisplay the region covered by the overlay, because 3527 /* We don't need to redisplay the region covered by the overlay, because
3997 the overlay has no properties at the moment. */ 3528 the overlay has no properties at the moment. */
3998 3529
3999 return overlay; 3530 return ov;
4000} 3531}
4001 3532
4002/* Mark a section of BUF as needing redisplay because of overlays changes. */ 3533/* Mark a section of BUF as needing redisplay because of overlays changes. */
@@ -4018,35 +3549,6 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
4018 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1); 3549 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1);
4019} 3550}
4020 3551
4021/* Remove OVERLAY from LIST. */
4022
4023static struct Lisp_Overlay *
4024unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay)
4025{
4026 register struct Lisp_Overlay *tail, **prev = &list;
4027
4028 for (tail = list; tail; prev = &tail->next, tail = *prev)
4029 if (tail == overlay)
4030 {
4031 *prev = overlay->next;
4032 overlay->next = NULL;
4033 break;
4034 }
4035 return list;
4036}
4037
4038/* Remove OVERLAY from both overlay lists of B. */
4039
4040static void
4041unchain_both (struct buffer *b, Lisp_Object overlay)
4042{
4043 struct Lisp_Overlay *ov = XOVERLAY (overlay);
4044
4045 set_buffer_overlays_before (b, unchain_overlay (b->overlays_before, ov));
4046 set_buffer_overlays_after (b, unchain_overlay (b->overlays_after, ov));
4047 eassert (XOVERLAY (overlay)->next == NULL);
4048}
4049
4050DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, 3552DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
4051 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER. 3553 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
4052If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now. 3554If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
@@ -4057,12 +3559,11 @@ buffer. */)
4057 struct buffer *b, *ob = 0; 3559 struct buffer *b, *ob = 0;
4058 Lisp_Object obuffer; 3560 Lisp_Object obuffer;
4059 specpdl_ref count = SPECPDL_INDEX (); 3561 specpdl_ref count = SPECPDL_INDEX ();
4060 ptrdiff_t n_beg, n_end;
4061 ptrdiff_t o_beg UNINIT, o_end UNINIT; 3562 ptrdiff_t o_beg UNINIT, o_end UNINIT;
4062 3563
4063 CHECK_OVERLAY (overlay); 3564 CHECK_OVERLAY (overlay);
4064 if (NILP (buffer)) 3565 if (NILP (buffer))
4065 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3566 buffer = Foverlay_buffer (overlay);
4066 if (NILP (buffer)) 3567 if (NILP (buffer))
4067 XSETBUFFER (buffer, current_buffer); 3568 XSETBUFFER (buffer, current_buffer);
4068 CHECK_BUFFER (buffer); 3569 CHECK_BUFFER (buffer);
@@ -4084,37 +3585,31 @@ buffer. */)
4084 temp = beg; beg = end; end = temp; 3585 temp = beg; beg = end; end = temp;
4085 } 3586 }
4086 3587
4087 specbind (Qinhibit_quit, Qt); 3588 specbind (Qinhibit_quit, Qt); /* FIXME: Why? */
4088 3589
4089 obuffer = Fmarker_buffer (OVERLAY_START (overlay)); 3590 obuffer = Foverlay_buffer (overlay);
4090 b = XBUFFER (buffer); 3591 b = XBUFFER (buffer);
4091 3592
3593 ptrdiff_t n_beg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3594 ptrdiff_t n_end = clip_to_bounds (n_beg, XFIXNUM (end), BUF_Z (b));
3595
4092 if (!NILP (obuffer)) 3596 if (!NILP (obuffer))
4093 { 3597 {
4094 ob = XBUFFER (obuffer); 3598 ob = XBUFFER (obuffer);
4095 3599
4096 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay)); 3600 o_beg = OVERLAY_START (overlay);
4097 o_end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3601 o_end = OVERLAY_END (overlay);
3602 }
4098 3603
4099 unchain_both (ob, overlay); 3604 if (! EQ (buffer, obuffer))
3605 {
3606 if (! NILP (obuffer))
3607 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
3608 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay), n_beg, n_end);
4100 } 3609 }
4101 else 3610 else
4102 /* An overlay not associated with any buffer will normally have its 3611 itree_node_set_region (b->overlays, XOVERLAY (overlay)->interval,
4103 `next' field set to NULL, but not always: when killing a buffer, 3612 n_beg, n_end);
4104 we just set its overlays_after and overlays_before to NULL without
4105 manually setting each overlay's `next' field to NULL.
4106 Let's correct it here, to simplify subsequent assertions.
4107 FIXME: Maybe the better fix is to change `kill-buffer'!? */
4108 XOVERLAY (overlay)->next = NULL;
4109
4110 eassert (XOVERLAY (overlay)->next == NULL);
4111
4112 /* Set the overlay boundaries, which may clip them. */
4113 Fset_marker (OVERLAY_START (overlay), beg, buffer);
4114 Fset_marker (OVERLAY_END (overlay), end, buffer);
4115
4116 n_beg = marker_position (OVERLAY_START (overlay));
4117 n_end = marker_position (OVERLAY_END (overlay));
4118 3613
4119 /* If the overlay has changed buffers, do a thorough redisplay. */ 3614 /* If the overlay has changed buffers, do a thorough redisplay. */
4120 if (!BASE_EQ (buffer, obuffer)) 3615 if (!BASE_EQ (buffer, obuffer))
@@ -4137,8 +3632,6 @@ buffer. */)
4137 modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end)); 3632 modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
4138 } 3633 }
4139 3634
4140 eassert (XOVERLAY (overlay)->next == NULL);
4141
4142 /* Delete the overlay if it is empty after clipping and has the 3635 /* Delete the overlay if it is empty after clipping and has the
4143 evaporate property. */ 3636 evaporate property. */
4144 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate))) 3637 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
@@ -4148,26 +3641,10 @@ buffer. */)
4148 contrary to `Fdelete_overlay's assumptions. 3641 contrary to `Fdelete_overlay's assumptions.
4149 - Most of the work done by Fdelete_overlay has already been done 3642 - Most of the work done by Fdelete_overlay has already been done
4150 here for other reasons. */ 3643 here for other reasons. */
4151 drop_overlay (XBUFFER (buffer), XOVERLAY (overlay)); 3644 drop_overlay (XOVERLAY (overlay));
4152 return unbind_to (count, overlay); 3645 return unbind_to (count, overlay);
4153 } 3646 }
4154 3647
4155 /* Put the overlay into the new buffer's overlay lists, first on the
4156 wrong list. */
4157 if (n_end < b->overlay_center)
4158 {
4159 XOVERLAY (overlay)->next = b->overlays_after;
4160 set_buffer_overlays_after (b, XOVERLAY (overlay));
4161 }
4162 else
4163 {
4164 XOVERLAY (overlay)->next = b->overlays_before;
4165 set_buffer_overlays_before (b, XOVERLAY (overlay));
4166 }
4167
4168 /* This puts it in the right list, and in the right order. */
4169 recenter_overlay_lists (b, b->overlay_center);
4170
4171 return unbind_to (count, overlay); 3648 return unbind_to (count, overlay);
4172} 3649}
4173 3650
@@ -4175,21 +3652,18 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
4175 doc: /* Delete the overlay OVERLAY from its buffer. */) 3652 doc: /* Delete the overlay OVERLAY from its buffer. */)
4176 (Lisp_Object overlay) 3653 (Lisp_Object overlay)
4177{ 3654{
4178 Lisp_Object buffer;
4179 struct buffer *b; 3655 struct buffer *b;
4180 specpdl_ref count = SPECPDL_INDEX (); 3656 specpdl_ref count = SPECPDL_INDEX ();
4181 3657
4182 CHECK_OVERLAY (overlay); 3658 CHECK_OVERLAY (overlay);
4183 3659
4184 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3660 b = OVERLAY_BUFFER (overlay);
4185 if (NILP (buffer)) 3661 if (! b)
4186 return Qnil; 3662 return Qnil;
4187 3663
4188 b = XBUFFER (buffer);
4189 specbind (Qinhibit_quit, Qt); 3664 specbind (Qinhibit_quit, Qt);
4190 3665
4191 unchain_both (b, overlay); 3666 drop_overlay (XOVERLAY (overlay));
4192 drop_overlay (b, XOVERLAY (overlay));
4193 3667
4194 /* When deleting an overlay with before or after strings, turn off 3668 /* When deleting an overlay with before or after strings, turn off
4195 display optimizations for the affected buffer, on the basis that 3669 display optimizations for the affected buffer, on the basis that
@@ -4220,8 +3694,10 @@ DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
4220 (Lisp_Object overlay) 3694 (Lisp_Object overlay)
4221{ 3695{
4222 CHECK_OVERLAY (overlay); 3696 CHECK_OVERLAY (overlay);
3697 if (! OVERLAY_BUFFER (overlay))
3698 return Qnil;
4223 3699
4224 return (Fmarker_position (OVERLAY_START (overlay))); 3700 return make_fixnum (OVERLAY_START (overlay));
4225} 3701}
4226 3702
4227DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0, 3703DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
@@ -4229,8 +3705,10 @@ DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
4229 (Lisp_Object overlay) 3705 (Lisp_Object overlay)
4230{ 3706{
4231 CHECK_OVERLAY (overlay); 3707 CHECK_OVERLAY (overlay);
3708 if (! OVERLAY_BUFFER (overlay))
3709 return Qnil;
4232 3710
4233 return (Fmarker_position (OVERLAY_END (overlay))); 3711 return make_fixnum (OVERLAY_END (overlay));
4234} 3712}
4235 3713
4236DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0, 3714DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
@@ -4238,9 +3716,16 @@ DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
4238Return nil if OVERLAY has been deleted. */) 3716Return nil if OVERLAY has been deleted. */)
4239 (Lisp_Object overlay) 3717 (Lisp_Object overlay)
4240{ 3718{
3719 Lisp_Object buffer;
3720
4241 CHECK_OVERLAY (overlay); 3721 CHECK_OVERLAY (overlay);
4242 3722
4243 return Fmarker_buffer (OVERLAY_START (overlay)); 3723 if (! OVERLAY_BUFFER (overlay))
3724 return Qnil;
3725
3726 XSETBUFFER (buffer, OVERLAY_BUFFER (overlay));
3727
3728 return buffer;
4244} 3729}
4245 3730
4246DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0, 3731DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
@@ -4251,7 +3736,7 @@ OVERLAY. */)
4251{ 3736{
4252 CHECK_OVERLAY (overlay); 3737 CHECK_OVERLAY (overlay);
4253 3738
4254 return Fcopy_sequence (XOVERLAY (overlay)->plist); 3739 return Fcopy_sequence (OVERLAY_PLIST (overlay));
4255} 3740}
4256 3741
4257 3742
@@ -4279,8 +3764,7 @@ interest. */)
4279 3764
4280 /* Put all the overlays we want in a vector in overlay_vec. 3765 /* Put all the overlays we want in a vector in overlay_vec.
4281 Store the length in len. */ 3766 Store the length in len. */
4282 noverlays = overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len, 3767 noverlays = overlays_at (XFIXNUM (pos), true, &overlay_vec, &len, NULL);
4283 NULL, NULL, 0);
4284 3768
4285 if (!NILP (sorted)) 3769 if (!NILP (sorted))
4286 noverlays = sort_overlays (overlay_vec, noverlays, 3770 noverlays = sort_overlays (overlay_vec, noverlays,
@@ -4325,7 +3809,7 @@ end of the accessible part of the buffer. */)
4325 /* Put all the overlays we want in a vector in overlay_vec. 3809 /* Put all the overlays we want in a vector in overlay_vec.
4326 Store the length in len. */ 3810 Store the length in len. */
4327 noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len, 3811 noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len,
4328 NULL, NULL); 3812 true, false, NULL);
4329 3813
4330 /* Make a list of them all. */ 3814 /* Make a list of them all. */
4331 result = Flist (noverlays, overlay_vec); 3815 result = Flist (noverlays, overlay_vec);
@@ -4341,39 +3825,12 @@ If there are no overlay boundaries from POS to (point-max),
4341the value is (point-max). */) 3825the value is (point-max). */)
4342 (Lisp_Object pos) 3826 (Lisp_Object pos)
4343{ 3827{
4344 ptrdiff_t i, len, noverlays;
4345 ptrdiff_t endpos;
4346 Lisp_Object *overlay_vec;
4347
4348 CHECK_FIXNUM_COERCE_MARKER (pos); 3828 CHECK_FIXNUM_COERCE_MARKER (pos);
4349 3829
4350 if (!buffer_has_overlays ()) 3830 if (!buffer_has_overlays ())
4351 return make_fixnum (ZV); 3831 return make_fixnum (ZV);
4352 3832
4353 len = 10; 3833 return make_fixnum (next_overlay_change (XFIXNUM (pos)));
4354 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4355
4356 /* Put all the overlays we want in a vector in overlay_vec.
4357 Store the length in len.
4358 endpos gets the position where the next overlay starts. */
4359 noverlays = overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
4360 &endpos, 0, 1);
4361
4362 /* If any of these overlays ends before endpos,
4363 use its ending point instead. */
4364 for (i = 0; i < noverlays; i++)
4365 {
4366 Lisp_Object oend;
4367 ptrdiff_t oendpos;
4368
4369 oend = OVERLAY_END (overlay_vec[i]);
4370 oendpos = OVERLAY_POSITION (oend);
4371 if (oendpos < endpos)
4372 endpos = oendpos;
4373 }
4374
4375 xfree (overlay_vec);
4376 return make_fixnum (endpos);
4377} 3834}
4378 3835
4379DEFUN ("previous-overlay-change", Fprevious_overlay_change, 3836DEFUN ("previous-overlay-change", Fprevious_overlay_change,
@@ -4383,32 +3840,15 @@ If there are no overlay boundaries from (point-min) to POS,
4383the value is (point-min). */) 3840the value is (point-min). */)
4384 (Lisp_Object pos) 3841 (Lisp_Object pos)
4385{ 3842{
4386 ptrdiff_t prevpos;
4387 Lisp_Object *overlay_vec;
4388 ptrdiff_t len;
4389 3843
4390 CHECK_FIXNUM_COERCE_MARKER (pos); 3844 CHECK_FIXNUM_COERCE_MARKER (pos);
4391 3845
4392 if (!buffer_has_overlays ()) 3846 if (!buffer_has_overlays ())
4393 return make_fixnum (BEGV); 3847 return make_fixnum (BEGV);
4394 3848
4395 /* At beginning of buffer, we know the answer; 3849 return make_fixnum (previous_overlay_change (XFIXNUM (pos)));
4396 avoid bug subtracting 1 below. */
4397 if (XFIXNUM (pos) == BEGV)
4398 return pos;
4399
4400 len = 10;
4401 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4402
4403 /* Put all the overlays we want in a vector in overlay_vec.
4404 Store the length in len.
4405 prevpos gets the position of the previous change. */
4406 overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
4407 0, &prevpos, 1);
4408
4409 xfree (overlay_vec);
4410 return make_fixnum (prevpos);
4411} 3850}
3851
4412 3852
4413/* These functions are for debugging overlays. */ 3853/* These functions are for debugging overlays. */
4414 3854
@@ -4418,19 +3858,16 @@ The car has all the overlays before the overlay center;
4418the cdr has all the overlays after the overlay center. 3858the cdr has all the overlays after the overlay center.
4419Recentering overlays moves overlays between these lists. 3859Recentering overlays moves overlays between these lists.
4420The lists you get are copies, so that changing them has no effect. 3860The lists you get are copies, so that changing them has no effect.
4421However, the overlays you get are the real objects that the buffer uses. */) 3861However, the overlays you get are the real objects that the buffer uses. */)
4422 (void) 3862 (void)
4423{ 3863{
4424 Lisp_Object before = Qnil, after = Qnil; 3864 Lisp_Object overlays = Qnil;
3865 struct itree_node *node;
4425 3866
4426 for (struct Lisp_Overlay *ol = current_buffer->overlays_before; 3867 ITREE_FOREACH (node, current_buffer->overlays, BEG, Z, DESCENDING)
4427 ol; ol = ol->next) 3868 overlays = Fcons (node->data, overlays);
4428 before = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), before);
4429 for (struct Lisp_Overlay *ol = current_buffer->overlays_after;
4430 ol; ol = ol->next)
4431 after = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), after);
4432 3869
4433 return Fcons (Fnreverse (before), Fnreverse (after)); 3870 return Fcons (overlays, Qnil);
4434} 3871}
4435 3872
4436DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0, 3873DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
@@ -4439,11 +3876,8 @@ That makes overlay lookup faster for positions near POS (but perhaps slower
4439for positions far away from POS). */) 3876for positions far away from POS). */)
4440 (Lisp_Object pos) 3877 (Lisp_Object pos)
4441{ 3878{
4442 ptrdiff_t p;
4443 CHECK_FIXNUM_COERCE_MARKER (pos); 3879 CHECK_FIXNUM_COERCE_MARKER (pos);
4444 3880 /* Noop */
4445 p = clip_to_bounds (PTRDIFF_MIN, XFIXNUM (pos), PTRDIFF_MAX);
4446 recenter_overlay_lists (current_buffer, p);
4447 return Qnil; 3881 return Qnil;
4448} 3882}
4449 3883
@@ -4460,12 +3894,13 @@ DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
4460VALUE will be returned.*/) 3894VALUE will be returned.*/)
4461 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value) 3895 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
4462{ 3896{
4463 Lisp_Object tail, buffer; 3897 Lisp_Object tail;
3898 struct buffer *b;
4464 bool changed; 3899 bool changed;
4465 3900
4466 CHECK_OVERLAY (overlay); 3901 CHECK_OVERLAY (overlay);
4467 3902
4468 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3903 b = OVERLAY_BUFFER (overlay);
4469 3904
4470 for (tail = XOVERLAY (overlay)->plist; 3905 for (tail = XOVERLAY (overlay)->plist;
4471 CONSP (tail) && CONSP (XCDR (tail)); 3906 CONSP (tail) && CONSP (XCDR (tail));
@@ -4481,15 +3916,14 @@ VALUE will be returned.*/)
4481 set_overlay_plist 3916 set_overlay_plist
4482 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist))); 3917 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist)));
4483 found: 3918 found:
4484 if (! NILP (buffer)) 3919 if (b)
4485 { 3920 {
4486 if (changed) 3921 if (changed)
4487 modify_overlay (XBUFFER (buffer), 3922 modify_overlay (b, OVERLAY_START (overlay),
4488 marker_position (OVERLAY_START (overlay)), 3923 OVERLAY_END (overlay));
4489 marker_position (OVERLAY_END (overlay)));
4490 if (EQ (prop, Qevaporate) && ! NILP (value) 3924 if (EQ (prop, Qevaporate) && ! NILP (value)
4491 && (OVERLAY_POSITION (OVERLAY_START (overlay)) 3925 && (OVERLAY_START (overlay)
4492 == OVERLAY_POSITION (OVERLAY_END (overlay)))) 3926 == OVERLAY_END (overlay)))
4493 Fdelete_overlay (overlay); 3927 Fdelete_overlay (overlay);
4494 } 3928 }
4495 3929
@@ -4560,70 +3994,33 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4560 3994
4561 if (!after) 3995 if (!after)
4562 { 3996 {
3997 struct itree_node *node;
3998 EMACS_INT begin_arg = XFIXNUM (start);
3999 EMACS_INT end_arg = XFIXNUM (end);
4563 /* We are being called before a change. 4000 /* We are being called before a change.
4564 Scan the overlays to find the functions to call. */ 4001 Scan the overlays to find the functions to call. */
4565 last_overlay_modification_hooks_used = 0; 4002 last_overlay_modification_hooks_used = 0;
4566 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
4567 tail; tail = tail->next)
4568 {
4569 ptrdiff_t startpos, endpos;
4570 Lisp_Object ostart, oend;
4571
4572 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4573
4574 ostart = OVERLAY_START (overlay);
4575 oend = OVERLAY_END (overlay);
4576 endpos = OVERLAY_POSITION (oend);
4577 if (XFIXNAT (start) > endpos)
4578 break;
4579 startpos = OVERLAY_POSITION (ostart);
4580 if (insertion && (XFIXNAT (start) == startpos
4581 || XFIXNAT (end) == startpos))
4582 {
4583 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4584 if (!NILP (prop))
4585 add_overlay_mod_hooklist (prop, overlay);
4586 }
4587 if (insertion && (XFIXNAT (start) == endpos
4588 || XFIXNAT (end) == endpos))
4589 {
4590 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4591 if (!NILP (prop))
4592 add_overlay_mod_hooklist (prop, overlay);
4593 }
4594 /* Test for intersecting intervals. This does the right thing
4595 for both insertion and deletion. */
4596 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
4597 {
4598 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
4599 if (!NILP (prop))
4600 add_overlay_mod_hooklist (prop, overlay);
4601 }
4602 }
4603 4003
4604 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 4004 if (! current_buffer->overlays)
4605 tail; tail = tail->next) 4005 return;
4006 ITREE_FOREACH (node, current_buffer->overlays,
4007 begin_arg - (insertion ? 1 : 0),
4008 end_arg + (insertion ? 1 : 0),
4009 ASCENDING)
4606 { 4010 {
4607 ptrdiff_t startpos, endpos; 4011 Lisp_Object overlay = node->data;
4608 Lisp_Object ostart, oend; 4012 ptrdiff_t obegin = OVERLAY_START (overlay);
4609 4013 ptrdiff_t oend = OVERLAY_END (overlay);
4610 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 4014
4611 4015 if (insertion && (begin_arg == obegin
4612 ostart = OVERLAY_START (overlay); 4016 || end_arg == obegin))
4613 oend = OVERLAY_END (overlay);
4614 startpos = OVERLAY_POSITION (ostart);
4615 endpos = OVERLAY_POSITION (oend);
4616 if (XFIXNAT (end) < startpos)
4617 break;
4618 if (insertion && (XFIXNAT (start) == startpos
4619 || XFIXNAT (end) == startpos))
4620 { 4017 {
4621 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 4018 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4622 if (!NILP (prop)) 4019 if (!NILP (prop))
4623 add_overlay_mod_hooklist (prop, overlay); 4020 add_overlay_mod_hooklist (prop, overlay);
4624 } 4021 }
4625 if (insertion && (XFIXNAT (start) == endpos 4022 if (insertion && (begin_arg == oend
4626 || XFIXNAT (end) == endpos)) 4023 || end_arg == oend))
4627 { 4024 {
4628 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks); 4025 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4629 if (!NILP (prop)) 4026 if (!NILP (prop))
@@ -4631,7 +4028,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4631 } 4028 }
4632 /* Test for intersecting intervals. This does the right thing 4029 /* Test for intersecting intervals. This does the right thing
4633 for both insertion and deletion. */ 4030 for both insertion and deletion. */
4634 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) 4031 if (! insertion || (end_arg > obegin && begin_arg < oend))
4635 { 4032 {
4636 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks); 4033 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
4637 if (!NILP (prop)) 4034 if (!NILP (prop))
@@ -4639,7 +4036,6 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4639 } 4036 }
4640 } 4037 }
4641 } 4038 }
4642
4643 { 4039 {
4644 /* Call the functions recorded in last_overlay_modification_hooks. 4040 /* Call the functions recorded in last_overlay_modification_hooks.
4645 First copy the vector contents, in case some of these hooks 4041 First copy the vector contents, in case some of these hooks
@@ -4662,7 +4058,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4662 (which makes its markers' buffers be nil), or that (due to 4058 (which makes its markers' buffers be nil), or that (due to
4663 some bug) it belongs to a different buffer. Only run this 4059 some bug) it belongs to a different buffer. Only run this
4664 hook if the overlay belongs to the current buffer. */ 4060 hook if the overlay belongs to the current buffer. */
4665 if (XMARKER (OVERLAY_START (overlay_i))->buffer == current_buffer) 4061 if (OVERLAY_BUFFER (overlay_i) == current_buffer)
4666 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3); 4062 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
4667 } 4063 }
4668 4064
@@ -4690,30 +4086,15 @@ void
4690evaporate_overlays (ptrdiff_t pos) 4086evaporate_overlays (ptrdiff_t pos)
4691{ 4087{
4692 Lisp_Object hit_list = Qnil; 4088 Lisp_Object hit_list = Qnil;
4693 if (pos <= current_buffer->overlay_center) 4089 struct itree_node *node;
4694 for (struct Lisp_Overlay *tail = current_buffer->overlays_before; 4090
4695 tail; tail = tail->next) 4091 ITREE_FOREACH (node, current_buffer->overlays, pos, pos, ASCENDING)
4696 { 4092 {
4697 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 4093 if (node->end == pos
4698 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 4094 && ! NILP (Foverlay_get (node->data, Qevaporate)))
4699 if (endpos < pos) 4095 hit_list = Fcons (node->data, hit_list);
4700 break; 4096 }
4701 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos 4097
4702 && ! NILP (Foverlay_get (overlay, Qevaporate)))
4703 hit_list = Fcons (overlay, hit_list);
4704 }
4705 else
4706 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
4707 tail; tail = tail->next)
4708 {
4709 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4710 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4711 if (startpos > pos)
4712 break;
4713 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
4714 && ! NILP (Foverlay_get (overlay, Qevaporate)))
4715 hit_list = Fcons (overlay, hit_list);
4716 }
4717 for (; CONSP (hit_list); hit_list = XCDR (hit_list)) 4098 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4718 Fdelete_overlay (XCAR (hit_list)); 4099 Fdelete_overlay (XCAR (hit_list));
4719} 4100}
@@ -5339,9 +4720,7 @@ init_buffer_once (void)
5339 bset_mark_active (&buffer_defaults, Qnil); 4720 bset_mark_active (&buffer_defaults, Qnil);
5340 bset_file_format (&buffer_defaults, Qnil); 4721 bset_file_format (&buffer_defaults, Qnil);
5341 bset_auto_save_file_format (&buffer_defaults, Qt); 4722 bset_auto_save_file_format (&buffer_defaults, Qt);
5342 set_buffer_overlays_before (&buffer_defaults, NULL); 4723 buffer_defaults.overlays = NULL;
5343 set_buffer_overlays_after (&buffer_defaults, NULL);
5344 buffer_defaults.overlay_center = BEG;
5345 4724
5346 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8); 4725 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8);
5347 bset_truncate_lines (&buffer_defaults, Qnil); 4726 bset_truncate_lines (&buffer_defaults, Qnil);
@@ -5546,6 +4925,48 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5546 emacs_abort (); 4925 emacs_abort ();
5547} 4926}
5548 4927
4928#ifdef ITREE_DEBUG
4929static Lisp_Object
4930make_lispy_itree_node (const struct itree_node *node)
4931{
4932 return listn (12,
4933 intern (":begin"),
4934 make_fixnum (node->begin),
4935 intern (":end"),
4936 make_fixnum (node->end),
4937 intern (":limit"),
4938 make_fixnum (node->limit),
4939 intern (":offset"),
4940 make_fixnum (node->offset),
4941 intern (":rear-advance"),
4942 node->rear_advance ? Qt : Qnil,
4943 intern (":front-advance"),
4944 node->front_advance ? Qt : Qnil);
4945}
4946
4947static Lisp_Object
4948overlay_tree (const struct itree_tree *tree,
4949 const struct itree_node *node)
4950{
4951 if (node == ITREE_NULL)
4952 return Qnil;
4953 return list3 (make_lispy_itree_node (node),
4954 overlay_tree (tree, node->left),
4955 overlay_tree (tree, node->right));
4956}
4957
4958DEFUN ("overlay-tree", Foverlay_tree, Soverlay_tree, 0, 1, 0,
4959 doc: /* Get the overlay tree for BUFFER. */)
4960 (Lisp_Object buffer)
4961{
4962 struct buffer *b = decode_buffer (buffer);
4963 if (! b->overlays)
4964 return Qnil;
4965 return overlay_tree (b->overlays, b->overlays->root);
4966}
4967#endif
4968
4969
5549 4970
5550/* Initialize the buffer routines. */ 4971/* Initialize the buffer routines. */
5551void 4972void
@@ -6517,6 +5938,10 @@ There is no reason to change that value except for debugging purposes. */);
6517 5938
6518 DEFSYM (Qautosaved, "autosaved"); 5939 DEFSYM (Qautosaved, "autosaved");
6519 5940
5941#ifdef ITREE_DEBUG
5942 defsubr (&Soverlay_tree);
5943#endif
5944
6520 DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save"); 5945 DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save");
6521 5946
6522 DEFSYM (Qbuffer_stale_function, "buffer-stale-function"); 5947 DEFSYM (Qbuffer_stale_function, "buffer-stale-function");