aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorYuan Fu2022-11-21 12:54:35 -0800
committerYuan Fu2022-11-21 12:54:35 -0800
commitaaeaa310f0391f5a5193e1a3d6e026986c4f2c0c (patch)
tree67765b95359bfc462e95606043e6b0cea3bb7c49 /src/buffer.c
parentb2ea38ab03e801859163b74a292aa75008e36541 (diff)
parentf176a36f4629b56c9fd9e3fc15aebd04a168c4f5 (diff)
downloademacs-aaeaa310f0391f5a5193e1a3d6e026986c4f2c0c.tar.gz
emacs-aaeaa310f0391f5a5193e1a3d6e026986c4f2c0c.zip
Merge remote-tracking branch 'savannah/master' into feature/tree-sitter
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c1528
1 files changed, 485 insertions, 1043 deletions
diff --git a/src/buffer.c b/src/buffer.c
index be7c2f2161e..ac7f4f8e9d4 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);
@@ -645,52 +645,33 @@ even if it is dead. The return value is never nil. */)
645 return buffer; 645 return buffer;
646} 646}
647 647
648 648static void
649/* Return a list of overlays which is a copy of the overlay list 649add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov,
650 LIST, but for buffer B. */ 650 ptrdiff_t begin, ptrdiff_t end)
651
652static struct Lisp_Overlay *
653copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
654{ 651{
655 struct Lisp_Overlay *result = NULL, *tail = NULL; 652 eassert (! ov->buffer);
656 653 if (! b->overlays)
657 for (; list; list = list->next) 654 b->overlays = itree_create ();
658 { 655 ov->buffer = b;
659 Lisp_Object overlay, start, end; 656 itree_insert (b->overlays, ov->interval, begin, end);
660 struct Lisp_Marker *m;
661
662 eassert (MARKERP (list->start));
663 m = XMARKER (list->start);
664 start = build_marker (b, m->charpos, m->bytepos);
665 XMARKER (start)->insertion_type = m->insertion_type;
666
667 eassert (MARKERP (list->end));
668 m = XMARKER (list->end);
669 end = build_marker (b, m->charpos, m->bytepos);
670 XMARKER (end)->insertion_type = m->insertion_type;
671
672 overlay = build_overlay (start, end, Fcopy_sequence (list->plist));
673 if (tail)
674 tail = tail->next = XOVERLAY (overlay);
675 else
676 result = tail = XOVERLAY (overlay);
677 }
678
679 return result;
680} 657}
681 658
682/* Set an appropriate overlay of B. */ 659/* Copy overlays of buffer FROM to buffer TO. */
683 660
684static void 661static void
685set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o) 662copy_overlays (struct buffer *from, struct buffer *to)
686{ 663{
687 b->overlays_before = o; 664 eassert (to && ! to->overlays);
688} 665 struct itree_node *node;
689 666
690static void 667 ITREE_FOREACH (node, from->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
691set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o) 668 {
692{ 669 Lisp_Object ov = node->data;
693 b->overlays_after = o; 670 Lisp_Object copy = build_overlay (node->front_advance,
671 node->rear_advance,
672 Fcopy_sequence (OVERLAY_PLIST (ov)));
673 add_buffer_overlay (to, XOVERLAY (copy), node->begin, node->end);
674 }
694} 675}
695 676
696bool 677bool
@@ -733,8 +714,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to)
733 714
734 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags); 715 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags);
735 716
736 set_buffer_overlays_before (to, copy_overlays (to, from->overlays_before)); 717 copy_overlays (from, to);
737 set_buffer_overlays_after (to, copy_overlays (to, from->overlays_after));
738 718
739 /* Get (a copy of) the alist of Lisp-level local variables of FROM 719 /* Get (a copy of) the alist of Lisp-level local variables of FROM
740 and install that in TO. */ 720 and install that in TO. */
@@ -933,17 +913,25 @@ does not run the hooks `kill-buffer-hook',
933 return buf; 913 return buf;
934} 914}
935 915
936/* Mark OV as no longer associated with B. */ 916static void
917remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov)
918{
919 eassert (b->overlays);
920 eassert (ov->buffer == b);
921 itree_remove (ov->buffer->overlays, ov->interval);
922 ov->buffer = NULL;
923}
924
925/* Mark OV as no longer associated with its buffer. */
937 926
938static void 927static void
939drop_overlay (struct buffer *b, struct Lisp_Overlay *ov) 928drop_overlay (struct Lisp_Overlay *ov)
940{ 929{
941 eassert (b == XBUFFER (Fmarker_buffer (ov->start))); 930 if (! ov->buffer)
942 modify_overlay (b, marker_position (ov->start), 931 return;
943 marker_position (ov->end));
944 unchain_marker (XMARKER (ov->start));
945 unchain_marker (XMARKER (ov->end));
946 932
933 modify_overlay (ov->buffer, overlay_start (ov), overlay_end (ov));
934 remove_buffer_overlay (ov->buffer, ov);
947} 935}
948 936
949/* Delete all overlays of B and reset its overlay lists. */ 937/* Delete all overlays of B and reset its overlay lists. */
@@ -951,26 +939,91 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
951void 939void
952delete_all_overlays (struct buffer *b) 940delete_all_overlays (struct buffer *b)
953{ 941{
954 struct Lisp_Overlay *ov, *next; 942 struct itree_node *node;
943
944 if (! b->overlays)
945 return;
955 946
956 /* FIXME: Since each drop_overlay will scan BUF_MARKERS to unlink its 947 /* The general rule is that the tree cannot be modified from within
957 markers, we have an unneeded O(N^2) behavior here. */ 948 ITREE_FOREACH, but here we bend this rule a little because we know
958 for (ov = b->overlays_before; ov; ov = next) 949 that the POST_ORDER iterator will not need to look at `node` again. */
950 ITREE_FOREACH (node, b->overlays, PTRDIFF_MIN, PTRDIFF_MAX, POST_ORDER)
959 { 951 {
960 drop_overlay (b, ov); 952 modify_overlay (b, node->begin, node->end);
961 next = ov->next; 953 XOVERLAY (node->data)->buffer = NULL;
962 ov->next = NULL; 954 node->parent = NULL;
955 node->left = NULL;
956 node->right = NULL;
963 } 957 }
958 itree_clear (b->overlays);
959}
964 960
965 for (ov = b->overlays_after; ov; ov = next) 961static void
962free_buffer_overlays (struct buffer *b)
963{
964 /* Actually this does not free any overlay, but the tree only. --ap */
965 if (b->overlays)
966 { 966 {
967 drop_overlay (b, ov); 967 itree_destroy (b->overlays);
968 next = ov->next; 968 b->overlays = NULL;
969 ov->next = NULL;
970 } 969 }
970}
971 971
972 set_buffer_overlays_before (b, NULL); 972/* Adjust the position of overlays in the current buffer according to
973 set_buffer_overlays_after (b, NULL); 973 MULTIBYTE.
974
975 Assume that positions currently correspond to byte positions, if
976 MULTIBYTE is true and to character positions if not.
977*/
978
979static void
980set_overlays_multibyte (bool multibyte)
981{
982 if (! current_buffer->overlays || Z == Z_BYTE)
983 return;
984
985 struct itree_node **nodes = NULL;
986 struct itree_tree *tree = current_buffer->overlays;
987 const intmax_t size = itree_size (tree);
988
989 /* We can't use `itree_node_set_region` at the same time
990 as we iterate over the itree, so we need an auxiliary storage
991 to keep the list of nodes. */
992 USE_SAFE_ALLOCA;
993 SAFE_NALLOCA (nodes, 1, size);
994 {
995 struct itree_node *node, **cursor = nodes;
996 ITREE_FOREACH (node, tree, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
997 *(cursor++) = node;
998 }
999
1000 for (int i = 0; i < size; ++i, ++nodes)
1001 {
1002 struct itree_node * const node = *nodes;
1003
1004 if (multibyte)
1005 {
1006 ptrdiff_t begin = itree_node_begin (tree, node);
1007 ptrdiff_t end = itree_node_end (tree, node);
1008
1009 /* This models the behavior of markers. (The behavior of
1010 text-intervals differs slightly.) */
1011 while (begin < Z_BYTE
1012 && !CHAR_HEAD_P (FETCH_BYTE (begin)))
1013 begin++;
1014 while (end < Z_BYTE
1015 && !CHAR_HEAD_P (FETCH_BYTE (end)))
1016 end++;
1017 itree_node_set_region (tree, node, BYTE_TO_CHAR (begin),
1018 BYTE_TO_CHAR (end));
1019 }
1020 else
1021 {
1022 itree_node_set_region (tree, node, CHAR_TO_BYTE (node->begin),
1023 CHAR_TO_BYTE (node->end));
1024 }
1025 }
1026 SAFE_FREE ();
974} 1027}
975 1028
976/* Reinitialize everything about a buffer except its name and contents 1029/* Reinitialize everything about a buffer except its name and contents
@@ -1000,9 +1053,7 @@ reset_buffer (register struct buffer *b)
1000 b->auto_save_failure_time = 0; 1053 b->auto_save_failure_time = 0;
1001 bset_auto_save_file_name (b, Qnil); 1054 bset_auto_save_file_name (b, Qnil);
1002 bset_read_only (b, Qnil); 1055 bset_read_only (b, Qnil);
1003 set_buffer_overlays_before (b, NULL); 1056 b->overlays = NULL;
1004 set_buffer_overlays_after (b, NULL);
1005 b->overlay_center = BEG;
1006 bset_mark_active (b, Qnil); 1057 bset_mark_active (b, Qnil);
1007 bset_point_before_scroll (b, Qnil); 1058 bset_point_before_scroll (b, Qnil);
1008 bset_file_format (b, Qnil); 1059 bset_file_format (b, Qnil);
@@ -1988,10 +2039,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1988 2039
1989 /* Perhaps we should explicitly free the interval tree here... */ 2040 /* Perhaps we should explicitly free the interval tree here... */
1990 } 2041 }
1991 /* Since we've unlinked the markers, the overlays can't be here any more 2042 delete_all_overlays (b);
1992 either. */ 2043 free_buffer_overlays (b);
1993 set_buffer_overlays_before (b, NULL);
1994 set_buffer_overlays_after (b, NULL);
1995 2044
1996 /* Reset the local variables, so that this buffer's local values 2045 /* Reset the local variables, so that this buffer's local values
1997 won't be protected from GC. They would be protected 2046 won't be protected from GC. They would be protected
@@ -2391,6 +2440,23 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
2391 return byte_pos; 2440 return byte_pos;
2392} 2441}
2393 2442
2443static void
2444swap_buffer_overlays (struct buffer *buffer, struct buffer *other)
2445{
2446 struct itree_node *node;
2447
2448 ITREE_FOREACH (node, buffer->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
2449 XOVERLAY (node->data)->buffer = other;
2450
2451 ITREE_FOREACH (node, other->overlays, PTRDIFF_MIN, PTRDIFF_MAX, ASCENDING)
2452 XOVERLAY (node->data)->buffer = buffer;
2453
2454 /* Swap the interval trees. */
2455 void *tmp = buffer->overlays;
2456 buffer->overlays = other->overlays;
2457 other->overlays = tmp;
2458}
2459
2394DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, 2460DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2395 1, 1, 0, 2461 1, 1, 0,
2396 doc: /* Swap the text between current buffer and BUFFER. 2462 doc: /* Swap the text between current buffer and BUFFER.
@@ -2462,9 +2528,6 @@ results, see Info node `(elisp)Swapping Text'. */)
2462 current_buffer->prevent_redisplay_optimizations_p = 1; 2528 current_buffer->prevent_redisplay_optimizations_p = 1;
2463 other_buffer->prevent_redisplay_optimizations_p = 1; 2529 other_buffer->prevent_redisplay_optimizations_p = 1;
2464 swapfield (long_line_optimizations_p, bool_bf); 2530 swapfield (long_line_optimizations_p, bool_bf);
2465 swapfield (overlays_before, struct Lisp_Overlay *);
2466 swapfield (overlays_after, struct Lisp_Overlay *);
2467 swapfield (overlay_center, ptrdiff_t);
2468 swapfield_ (undo_list, Lisp_Object); 2531 swapfield_ (undo_list, Lisp_Object);
2469 swapfield_ (mark, Lisp_Object); 2532 swapfield_ (mark, Lisp_Object);
2470 swapfield_ (mark_active, Lisp_Object); /* Belongs with the `mark'. */ 2533 swapfield_ (mark_active, Lisp_Object); /* Belongs with the `mark'. */
@@ -2491,6 +2554,7 @@ results, see Info node `(elisp)Swapping Text'. */)
2491 current_buffer->text->end_unchanged = current_buffer->text->gpt; 2554 current_buffer->text->end_unchanged = current_buffer->text->gpt;
2492 other_buffer->text->beg_unchanged = other_buffer->text->gpt; 2555 other_buffer->text->beg_unchanged = other_buffer->text->gpt;
2493 other_buffer->text->end_unchanged = other_buffer->text->gpt; 2556 other_buffer->text->end_unchanged = other_buffer->text->gpt;
2557 swap_buffer_overlays (current_buffer, other_buffer);
2494 { 2558 {
2495 struct Lisp_Marker *m; 2559 struct Lisp_Marker *m;
2496 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 2560 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
@@ -2607,7 +2671,8 @@ current buffer is cleared. */)
2607 2671
2608 /* Do this first, so it can use CHAR_TO_BYTE 2672 /* Do this first, so it can use CHAR_TO_BYTE
2609 to calculate the old correspondences. */ 2673 to calculate the old correspondences. */
2610 set_intervals_multibyte (0); 2674 set_intervals_multibyte (false);
2675 set_overlays_multibyte (false);
2611 2676
2612 bset_enable_multibyte_characters (current_buffer, Qnil); 2677 bset_enable_multibyte_characters (current_buffer, Qnil);
2613 2678
@@ -2794,7 +2859,8 @@ current buffer is cleared. */)
2794 /* FIXME: Is it worth the trouble, really? Couldn't we just throw 2859 /* FIXME: Is it worth the trouble, really? Couldn't we just throw
2795 away all the text-properties instead of trying to guess how 2860 away all the text-properties instead of trying to guess how
2796 to adjust them? AFAICT the result is not reliable anyway. */ 2861 to adjust them? AFAICT the result is not reliable anyway. */
2797 set_intervals_multibyte (1); 2862 set_intervals_multibyte (true);
2863 set_overlays_multibyte (true);
2798 } 2864 }
2799 2865
2800 if (!EQ (old_undo, Qt)) 2866 if (!EQ (old_undo, Qt))
@@ -2877,272 +2943,154 @@ the normal hook `change-major-mode-hook'. */)
2877} 2943}
2878 2944
2879 2945
2880/* Find all the overlays in the current buffer that contain position POS. 2946/* Find all the overlays in the current buffer that overlap the range
2947 [BEG, END).
2948
2949 If EMPTY is true, include empty overlays in that range and also at
2950 END, provided END denotes the position at the end of the accessible
2951 part of the buffer.
2952
2953 If TRAILING is true, include overlays that begin at END, provided
2954 END denotes the position at the end of the accessible part of the
2955 buffer.
2956
2881 Return the number found, and store them in a vector in *VEC_PTR. 2957 Return the number found, and store them in a vector in *VEC_PTR.
2882 Store in *LEN_PTR the size allocated for the vector. 2958 Store in *LEN_PTR the size allocated for the vector.
2883 Store in *NEXT_PTR the next position after POS where an overlay starts, 2959 Store in *NEXT_PTR the next position after POS where an overlay starts,
2884 or ZV if there are no more overlays between POS and ZV. 2960 or ZV if there are no more overlays.
2885 Store in *PREV_PTR the previous position before POS where an overlay ends, 2961 NEXT_PTR may be 0, meaning don't store that info.
2886 or where an overlay starts which ends at or after POS;
2887 or BEGV if there are no such overlays from BEGV to POS.
2888 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2889 2962
2890 *VEC_PTR and *LEN_PTR should contain a valid vector and size 2963 *VEC_PTR and *LEN_PTR should contain a valid vector and size
2891 when this function is called. 2964 when this function is called.
2892 2965
2893 If EXTEND, make the vector bigger if necessary. 2966 If EXTEND, make the vector bigger if necessary. If not, never
2894 If not, never extend the vector, 2967 extend the vector, and store only as many overlays as will fit.
2895 and store only as many overlays as will fit.
2896 But still return the total number of overlays. 2968 But still return the total number of overlays.
2897 2969*/
2898 If CHANGE_REQ, any position written into *PREV_PTR or
2899 *NEXT_PTR is guaranteed to be not equal to POS, unless it is the
2900 default (BEGV or ZV). */
2901 2970
2902ptrdiff_t 2971ptrdiff_t
2903overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr, 2972overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
2904 ptrdiff_t *len_ptr, 2973 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
2905 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req) 2974 bool empty, bool trailing,
2975 ptrdiff_t *next_ptr)
2906{ 2976{
2907 ptrdiff_t idx = 0; 2977 ptrdiff_t idx = 0;
2908 ptrdiff_t len = *len_ptr; 2978 ptrdiff_t len = *len_ptr;
2909 Lisp_Object *vec = *vec_ptr;
2910 ptrdiff_t next = ZV; 2979 ptrdiff_t next = ZV;
2911 ptrdiff_t prev = BEGV; 2980 Lisp_Object *vec = *vec_ptr;
2912 bool inhibit_storing = 0; 2981 struct itree_node *node;
2913
2914 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
2915 tail; tail = tail->next)
2916 {
2917 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
2918 Lisp_Object start = OVERLAY_START (overlay);
2919 Lisp_Object end = OVERLAY_END (overlay);
2920 ptrdiff_t endpos = OVERLAY_POSITION (end);
2921 if (endpos < pos)
2922 {
2923 if (prev < endpos)
2924 prev = endpos;
2925 break;
2926 }
2927 ptrdiff_t startpos = OVERLAY_POSITION (start);
2928 /* This one ends at or after POS
2929 so its start counts for PREV_PTR if it's before POS. */
2930 if (prev < startpos && startpos < pos)
2931 prev = startpos;
2932 if (endpos == pos)
2933 continue;
2934 if (startpos <= pos)
2935 {
2936 if (idx == len)
2937 {
2938 /* The supplied vector is full.
2939 Either make it bigger, or don't store any more in it. */
2940 if (extend)
2941 {
2942 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2943 sizeof *vec);
2944 *vec_ptr = vec;
2945 len = *len_ptr;
2946 }
2947 else
2948 inhibit_storing = 1;
2949 }
2950 2982
2951 if (!inhibit_storing) 2983 /* Extend the search range if overlays beginning at ZV are
2952 vec[idx] = overlay; 2984 wanted. */
2953 /* Keep counting overlays even if we can't return them all. */ 2985 ptrdiff_t search_end = ZV;
2954 idx++; 2986 if (end >= ZV && (empty || trailing))
2955 } 2987 ++search_end;
2956 else if (startpos < next)
2957 next = startpos;
2958 }
2959 2988
2960 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 2989 ITREE_FOREACH (node, current_buffer->overlays, beg, search_end,
2961 tail; tail = tail->next) 2990 ASCENDING)
2962 { 2991 {
2963 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 2992 if (node->begin > end)
2964 Lisp_Object start = OVERLAY_START (overlay); 2993 {
2965 Lisp_Object end = OVERLAY_END (overlay); 2994 next = min (next, node->begin);
2966 ptrdiff_t startpos = OVERLAY_POSITION (start); 2995 break;
2967 if (pos < startpos) 2996 }
2968 { 2997 else if (node->begin == end)
2969 if (startpos < next) 2998 {
2970 next = startpos; 2999 next = node->begin;
2971 break; 3000 if ((! empty || end < ZV) && beg < end)
2972 } 3001 break;
2973 ptrdiff_t endpos = OVERLAY_POSITION (end); 3002 if (empty && node->begin != node->end)
2974 if (pos < endpos) 3003 continue;
2975 { 3004 }
2976 if (idx == len)
2977 {
2978 if (extend)
2979 {
2980 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2981 sizeof *vec);
2982 *vec_ptr = vec;
2983 len = *len_ptr;
2984 }
2985 else
2986 inhibit_storing = 1;
2987 }
2988 3005
2989 if (!inhibit_storing) 3006 if (! empty && node->begin == node->end)
2990 vec[idx] = overlay; 3007 continue;
2991 idx++;
2992 3008
2993 if (startpos < pos && startpos > prev) 3009 if (extend && idx == len)
2994 prev = startpos; 3010 {
2995 } 3011 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2996 else if (endpos < pos && endpos > prev) 3012 sizeof *vec);
2997 prev = endpos; 3013 *vec_ptr = vec;
2998 else if (endpos == pos && startpos > prev 3014 len = *len_ptr;
2999 && (!change_req || startpos < pos)) 3015 }
3000 prev = startpos; 3016 if (idx < len)
3017 vec[idx] = node->data;
3018 /* Keep counting overlays even if we can't return them all. */
3019 idx++;
3001 } 3020 }
3002
3003 if (next_ptr) 3021 if (next_ptr)
3004 *next_ptr = next; 3022 *next_ptr = next ? next : ZV;
3005 if (prev_ptr) 3023
3006 *prev_ptr = prev;
3007 return idx; 3024 return idx;
3008} 3025}
3009
3010/* Find all the overlays in the current buffer that overlap the range
3011 BEG-END, or are empty at BEG, or are empty at END provided END
3012 denotes the position at the end of the current buffer.
3013 3026
3014 Return the number found, and store them in a vector in *VEC_PTR. 3027/* Find all non-empty overlays in the current buffer that contain
3015 Store in *LEN_PTR the size allocated for the vector. 3028 position POS.
3016 Store in *NEXT_PTR the next position after POS where an overlay starts,
3017 or ZV if there are no more overlays.
3018 Store in *PREV_PTR the previous position before POS where an overlay ends,
3019 or BEGV if there are no previous overlays.
3020 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
3021 3029
3022 *VEC_PTR and *LEN_PTR should contain a valid vector and size 3030 See overlays_in for the meaning of the arguments.
3023 when this function is called. 3031 */
3024 3032
3025 If EXTEND, make the vector bigger if necessary. 3033ptrdiff_t
3026 If not, never extend the vector, 3034overlays_at (ptrdiff_t pos, bool extend,
3027 and store only as many overlays as will fit. 3035 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
3028 But still return the total number of overlays. */ 3036 ptrdiff_t *next_ptr)
3037{
3038 return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr,
3039 false, true, next_ptr);
3040}
3029 3041
3030static ptrdiff_t 3042ptrdiff_t
3031overlays_in (EMACS_INT beg, EMACS_INT end, bool extend, 3043next_overlay_change (ptrdiff_t pos)
3032 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
3033 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
3034{ 3044{
3035 ptrdiff_t idx = 0;
3036 ptrdiff_t len = *len_ptr;
3037 Lisp_Object *vec = *vec_ptr;
3038 ptrdiff_t next = ZV; 3045 ptrdiff_t next = ZV;
3039 ptrdiff_t prev = BEGV; 3046 struct itree_node *node;
3040 bool inhibit_storing = 0;
3041 bool end_is_Z = end == ZV;
3042 3047
3043 for (struct Lisp_Overlay *tail = current_buffer->overlays_before; 3048 ITREE_FOREACH (node, current_buffer->overlays, pos, next, ASCENDING)
3044 tail; tail = tail->next)
3045 { 3049 {
3046 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 3050 if (node->begin > pos)
3047 Lisp_Object ostart = OVERLAY_START (overlay); 3051 {
3048 Lisp_Object oend = OVERLAY_END (overlay); 3052 /* If we reach this branch, node->begin must be the least upper bound
3049 ptrdiff_t endpos = OVERLAY_POSITION (oend); 3053 of pos, because the search is limited to [pos,next) . */
3050 if (endpos < beg) 3054 eassert (node->begin < next);
3051 { 3055 next = node->begin;
3052 if (prev < endpos) 3056 break;
3053 prev = endpos; 3057 }
3054 break; 3058 else if (node->begin < node->end && node->end < next)
3055 } 3059 {
3056 ptrdiff_t startpos = OVERLAY_POSITION (ostart); 3060 next = node->end;
3057 /* Count an interval if it overlaps the range, is empty at the 3061 ITREE_FOREACH_NARROW (pos, next);
3058 start of the range, or is empty at END provided END denotes the 3062 }
3059 end of the buffer. */
3060 if ((beg < endpos && startpos < end)
3061 || (startpos == endpos
3062 && (beg == endpos || (end_is_Z && endpos == end))))
3063 {
3064 if (idx == len)
3065 {
3066 /* The supplied vector is full.
3067 Either make it bigger, or don't store any more in it. */
3068 if (extend)
3069 {
3070 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3071 sizeof *vec);
3072 *vec_ptr = vec;
3073 len = *len_ptr;
3074 }
3075 else
3076 inhibit_storing = 1;
3077 }
3078
3079 if (!inhibit_storing)
3080 vec[idx] = overlay;
3081 /* Keep counting overlays even if we can't return them all. */
3082 idx++;
3083 }
3084 else if (startpos < next)
3085 next = startpos;
3086 } 3063 }
3087 3064
3088 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 3065 return next;
3089 tail; tail = tail->next) 3066}
3090 {
3091 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3092 Lisp_Object ostart = OVERLAY_START (overlay);
3093 Lisp_Object oend = OVERLAY_END (overlay);
3094 ptrdiff_t startpos = OVERLAY_POSITION (ostart);
3095 if (end < startpos)
3096 {
3097 if (startpos < next)
3098 next = startpos;
3099 break;
3100 }
3101 ptrdiff_t endpos = OVERLAY_POSITION (oend);
3102 /* Count an interval if it overlaps the range, is empty at the
3103 start of the range, or is empty at END provided END denotes the
3104 end of the buffer. */
3105 if ((beg < endpos && startpos < end)
3106 || (startpos == endpos
3107 && (beg == endpos || (end_is_Z && endpos == end))))
3108 {
3109 if (idx == len)
3110 {
3111 if (extend)
3112 {
3113 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3114 sizeof *vec);
3115 *vec_ptr = vec;
3116 len = *len_ptr;
3117 }
3118 else
3119 inhibit_storing = 1;
3120 }
3121 3067
3122 if (!inhibit_storing) 3068ptrdiff_t
3123 vec[idx] = overlay; 3069previous_overlay_change (ptrdiff_t pos)
3124 idx++; 3070{
3125 } 3071 struct itree_node *node;
3126 else if (endpos < beg && endpos > prev) 3072 ptrdiff_t prev = BEGV;
3127 prev = endpos; 3073
3074 ITREE_FOREACH (node, current_buffer->overlays, prev, pos, DESCENDING)
3075 {
3076 if (node->end < pos)
3077 prev = node->end;
3078 else
3079 prev = max (prev, node->begin);
3080 ITREE_FOREACH_NARROW (prev, pos);
3128 } 3081 }
3129 3082
3130 if (next_ptr) 3083 return prev;
3131 *next_ptr = next;
3132 if (prev_ptr)
3133 *prev_ptr = prev;
3134 return idx;
3135} 3084}
3136 3085
3137
3138/* Return true if there exists an overlay with a non-nil 3086/* Return true if there exists an overlay with a non-nil
3139 `mouse-face' property overlapping OVERLAY. */ 3087 `mouse-face' property overlapping OVERLAY. */
3140 3088
3141bool 3089bool
3142mouse_face_overlay_overlaps (Lisp_Object overlay) 3090mouse_face_overlay_overlaps (Lisp_Object overlay)
3143{ 3091{
3144 ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay)); 3092 ptrdiff_t start = OVERLAY_START (overlay);
3145 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3093 ptrdiff_t end = OVERLAY_END (overlay);
3146 ptrdiff_t n, i, size; 3094 ptrdiff_t n, i, size;
3147 Lisp_Object *v, tem; 3095 Lisp_Object *v, tem;
3148 Lisp_Object vbuf[10]; 3096 Lisp_Object vbuf[10];
@@ -3150,11 +3098,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
3150 3098
3151 size = ARRAYELTS (vbuf); 3099 size = ARRAYELTS (vbuf);
3152 v = vbuf; 3100 v = vbuf;
3153 n = overlays_in (start, end, 0, &v, &size, NULL, NULL); 3101 n = overlays_in (start, end, 0, &v, &size, true, false, NULL);
3154 if (n > size) 3102 if (n > size)
3155 { 3103 {
3156 SAFE_NALLOCA (v, 1, n); 3104 SAFE_NALLOCA (v, 1, n);
3157 overlays_in (start, end, 0, &v, &n, NULL, NULL); 3105 overlays_in (start, end, 0, &v, &n, true, false, NULL);
3158 } 3106 }
3159 3107
3160 for (i = 0; i < n; ++i) 3108 for (i = 0; i < n; ++i)
@@ -3179,11 +3127,11 @@ disable_line_numbers_overlay_at_eob (void)
3179 3127
3180 size = ARRAYELTS (vbuf); 3128 size = ARRAYELTS (vbuf);
3181 v = vbuf; 3129 v = vbuf;
3182 n = overlays_in (ZV, ZV, 0, &v, &size, NULL, NULL); 3130 n = overlays_in (ZV, ZV, 0, &v, &size, false, false, NULL);
3183 if (n > size) 3131 if (n > size)
3184 { 3132 {
3185 SAFE_NALLOCA (v, 1, n); 3133 SAFE_NALLOCA (v, 1, n);
3186 overlays_in (ZV, ZV, 0, &v, &n, NULL, NULL); 3134 overlays_in (ZV, ZV, 0, &v, &n, false, false, NULL);
3187 } 3135 }
3188 3136
3189 for (i = 0; i < n; ++i) 3137 for (i = 0; i < n; ++i)
@@ -3196,47 +3144,25 @@ disable_line_numbers_overlay_at_eob (void)
3196} 3144}
3197 3145
3198 3146
3199/* Fast function to just test if we're at an overlay boundary. */ 3147/* Fast function to just test if we're at an overlay boundary.
3148
3149 Returns true if some overlay starts or ends (or both) at POS,
3150*/
3200bool 3151bool
3201overlay_touches_p (ptrdiff_t pos) 3152overlay_touches_p (ptrdiff_t pos)
3202{ 3153{
3203 for (struct Lisp_Overlay *tail = current_buffer->overlays_before; 3154 struct itree_node *node;
3204 tail; tail = tail->next)
3205 {
3206 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3207 eassert (OVERLAYP (overlay));
3208
3209 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3210 if (endpos < pos)
3211 break;
3212 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
3213 return 1;
3214 }
3215 3155
3216 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 3156 /* We need to find overlays ending in pos, as well as empty ones at
3217 tail; tail = tail->next) 3157 pos. */
3218 { 3158 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
3219 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 3159 if (node->begin == pos || node->end == pos)
3220 eassert (OVERLAYP (overlay)); 3160 return true;
3221 3161 return false;
3222 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3223 if (pos < startpos)
3224 break;
3225 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
3226 return 1;
3227 }
3228 return 0;
3229} 3162}
3230
3231struct sortvec
3232{
3233 Lisp_Object overlay;
3234 ptrdiff_t beg, end;
3235 EMACS_INT priority;
3236 EMACS_INT spriority; /* Secondary priority. */
3237};
3238 3163
3239static int 3164
3165int
3240compare_overlays (const void *v1, const void *v2) 3166compare_overlays (const void *v1, const void *v2)
3241{ 3167{
3242 const struct sortvec *s1 = v1; 3168 const struct sortvec *s1 = v1;
@@ -3265,6 +3191,33 @@ compare_overlays (const void *v1, const void *v2)
3265 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1; 3191 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3266} 3192}
3267 3193
3194void
3195make_sortvec_item (struct sortvec *item, Lisp_Object overlay)
3196{
3197 Lisp_Object tem;
3198 /* This overlay is good and counts: put it into sortvec. */
3199 item->overlay = overlay;
3200 item->beg = OVERLAY_START (overlay);
3201 item->end = OVERLAY_END (overlay);
3202 tem = Foverlay_get (overlay, Qpriority);
3203 if (NILP (tem))
3204 {
3205 item->priority = 0;
3206 item->spriority = 0;
3207 }
3208 else if (FIXNUMP (tem))
3209 {
3210 item->priority = XFIXNUM (tem);
3211 item->spriority = 0;
3212 }
3213 else if (CONSP (tem))
3214 {
3215 Lisp_Object car = XCAR (tem);
3216 Lisp_Object cdr = XCDR (tem);
3217 item->priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
3218 item->spriority = FIXNUMP (cdr) ? XFIXNUM (cdr) : 0;
3219 }
3220}
3268/* Sort an array of overlays by priority. The array is modified in place. 3221/* Sort an array of overlays by priority. The array is modified in place.
3269 The return value is the new size; this may be smaller than the original 3222 The return value is the new size; this may be smaller than the original
3270 size if some of the overlays were invalid or were window-specific. */ 3223 size if some of the overlays were invalid or were window-specific. */
@@ -3281,47 +3234,18 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
3281 3234
3282 for (i = 0, j = 0; i < noverlays; i++) 3235 for (i = 0, j = 0; i < noverlays; i++)
3283 { 3236 {
3284 Lisp_Object tem;
3285 Lisp_Object overlay; 3237 Lisp_Object overlay;
3286 3238
3287 overlay = overlay_vec[i]; 3239 overlay = overlay_vec[i];
3288 if (OVERLAYP (overlay) 3240 if (OVERLAYP (overlay)
3289 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 3241 && OVERLAY_START (overlay) > 0
3290 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) 3242 && OVERLAY_END (overlay) > 0)
3291 { 3243 {
3292 /* If we're interested in a specific window, then ignore 3244 /* If we're interested in a specific window, then ignore
3293 overlays that are limited to some other window. */ 3245 overlays that are limited to some other window. */
3294 if (w) 3246 if (w && ! overlay_matches_window (w, overlay))
3295 { 3247 continue;
3296 Lisp_Object window; 3248 make_sortvec_item (sortvec + j, overlay);
3297
3298 window = Foverlay_get (overlay, Qwindow);
3299 if (WINDOWP (window) && XWINDOW (window) != w)
3300 continue;
3301 }
3302
3303 /* This overlay is good and counts: put it into sortvec. */
3304 sortvec[j].overlay = overlay;
3305 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3306 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
3307 tem = Foverlay_get (overlay, Qpriority);
3308 if (NILP (tem))
3309 {
3310 sortvec[j].priority = 0;
3311 sortvec[j].spriority = 0;
3312 }
3313 else if (FIXNUMP (tem))
3314 {
3315 sortvec[j].priority = XFIXNUM (tem);
3316 sortvec[j].spriority = 0;
3317 }
3318 else if (CONSP (tem))
3319 {
3320 Lisp_Object car = XCAR (tem);
3321 Lisp_Object cdr = XCDR (tem);
3322 sortvec[j].priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
3323 sortvec[j].spriority = FIXNUMP (cdr) ? XFIXNUM (cdr) : 0;
3324 }
3325 j++; 3249 j++;
3326 } 3250 }
3327 } 3251 }
@@ -3436,25 +3360,27 @@ ptrdiff_t
3436overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) 3360overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3437{ 3361{
3438 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 3362 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
3363 struct itree_node *node;
3439 3364
3440 overlay_heads.used = overlay_heads.bytes = 0; 3365 overlay_heads.used = overlay_heads.bytes = 0;
3441 overlay_tails.used = overlay_tails.bytes = 0; 3366 overlay_tails.used = overlay_tails.bytes = 0;
3442 for (struct Lisp_Overlay *ov = current_buffer->overlays_before; 3367
3443 ov; ov = ov->next) 3368 ITREE_FOREACH (node, current_buffer->overlays, pos - 1, pos + 1, DESCENDING)
3444 { 3369 {
3445 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike); 3370 Lisp_Object overlay = node->data;
3446 eassert (OVERLAYP (overlay)); 3371 eassert (OVERLAYP (overlay));
3447 3372
3448 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3373 ptrdiff_t startpos = node->begin;
3449 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3374 ptrdiff_t endpos = node->end;
3450 if (endpos < pos) 3375
3451 break;
3452 if (endpos != pos && startpos != pos) 3376 if (endpos != pos && startpos != pos)
3453 continue; 3377 continue;
3454 Lisp_Object window = Foverlay_get (overlay, Qwindow); 3378 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3455 if (WINDOWP (window) && XWINDOW (window) != w) 3379 if (WINDOWP (window) && XWINDOW (window) != w)
3456 continue; 3380 continue;
3457 Lisp_Object str; 3381 Lisp_Object str;
3382 /* FIXME: Are we really sure that `record_overlay_string` can
3383 never cause a non-local exit? */
3458 if (startpos == pos 3384 if (startpos == pos
3459 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3385 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3460 record_overlay_string (&overlay_heads, str, 3386 record_overlay_string (&overlay_heads, str,
@@ -3469,36 +3395,7 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3469 Foverlay_get (overlay, Qpriority), 3395 Foverlay_get (overlay, Qpriority),
3470 endpos - startpos); 3396 endpos - startpos);
3471 } 3397 }
3472 for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
3473 ov; ov = ov->next)
3474 {
3475 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
3476 eassert (OVERLAYP (overlay));
3477 3398
3478 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3479 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3480 if (startpos > pos)
3481 break;
3482 if (endpos != pos && startpos != pos)
3483 continue;
3484 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3485 if (WINDOWP (window) && XWINDOW (window) != w)
3486 continue;
3487 Lisp_Object str;
3488 if (startpos == pos
3489 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3490 record_overlay_string (&overlay_heads, str,
3491 (startpos == endpos
3492 ? Foverlay_get (overlay, Qafter_string)
3493 : Qnil),
3494 Foverlay_get (overlay, Qpriority),
3495 endpos - startpos);
3496 else if (endpos == pos
3497 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3498 record_overlay_string (&overlay_tails, str, Qnil,
3499 Foverlay_get (overlay, Qpriority),
3500 endpos - startpos);
3501 }
3502 if (overlay_tails.used > 1) 3399 if (overlay_tails.used > 1)
3503 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr), 3400 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
3504 cmp_for_strings); 3401 cmp_for_strings);
@@ -3553,384 +3450,71 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3553 } 3450 }
3554 return 0; 3451 return 0;
3555} 3452}
3556
3557/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
3558 3453
3454
3559void 3455void
3560recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) 3456adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length, bool before_markers)
3561{ 3457{
3562 struct Lisp_Overlay *prev, *next; 3458 if (!current_buffer->indirections)
3563 3459 itree_insert_gap (current_buffer->overlays, pos, length, before_markers);
3564 /* See if anything in overlays_before should move to overlays_after. */ 3460 else
3565
3566 /* We don't strictly need prev in this loop; it should always be nil.
3567 But we use it for symmetry and in case that should cease to be true
3568 with some future change. */
3569 prev = NULL;
3570 for (struct Lisp_Overlay *tail = buf->overlays_before;
3571 tail; prev = tail, tail = next)
3572 {
3573 next = tail->next;
3574 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3575 eassert (OVERLAYP (overlay));
3576
3577 Lisp_Object beg = OVERLAY_START (overlay);
3578 Lisp_Object end = OVERLAY_END (overlay);
3579
3580 if (OVERLAY_POSITION (end) > pos)
3581 {
3582 /* OVERLAY needs to be moved. */
3583 ptrdiff_t where = OVERLAY_POSITION (beg);
3584 struct Lisp_Overlay *other, *other_prev;
3585
3586 /* Splice the cons cell TAIL out of overlays_before. */
3587 if (prev)
3588 prev->next = next;
3589 else
3590 set_buffer_overlays_before (buf, next);
3591
3592 /* Search thru overlays_after for where to put it. */
3593 other_prev = NULL;
3594 for (other = buf->overlays_after; other;
3595 other_prev = other, other = other->next)
3596 {
3597 Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
3598 eassert (OVERLAYP (otheroverlay));
3599
3600 Lisp_Object otherbeg = OVERLAY_START (otheroverlay);
3601 if (OVERLAY_POSITION (otherbeg) >= where)
3602 break;
3603 }
3604
3605 /* Add TAIL to overlays_after before OTHER. */
3606 tail->next = other;
3607 if (other_prev)
3608 other_prev->next = tail;
3609 else
3610 set_buffer_overlays_after (buf, tail);
3611 tail = prev;
3612 }
3613 else
3614 /* We've reached the things that should stay in overlays_before.
3615 All the rest of overlays_before must end even earlier,
3616 so stop now. */
3617 break;
3618 }
3619
3620 /* See if anything in overlays_after should be in overlays_before. */
3621 prev = NULL;
3622 for (struct Lisp_Overlay *tail = buf->overlays_after;
3623 tail; prev = tail, tail = next)
3624 { 3461 {
3625 next = tail->next; 3462 struct buffer *base = current_buffer->base_buffer
3626 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 3463 ? current_buffer->base_buffer
3627 eassert (OVERLAYP (overlay)); 3464 : current_buffer;
3628 3465 Lisp_Object tail, other;
3629 Lisp_Object beg = OVERLAY_START (overlay); 3466 itree_insert_gap (base->overlays, pos, length, before_markers);
3630 Lisp_Object end = OVERLAY_END (overlay); 3467 FOR_EACH_LIVE_BUFFER (tail, other)
3631 3468 if (XBUFFER (other)->base_buffer == base)
3632 /* Stop looking, when we know that nothing further 3469 itree_insert_gap (XBUFFER (other)->overlays, pos, length,
3633 can possibly end before POS. */ 3470 before_markers);
3634 if (OVERLAY_POSITION (beg) > pos)
3635 break;
3636
3637 if (OVERLAY_POSITION (end) <= pos)
3638 {
3639 /* OVERLAY needs to be moved. */
3640 ptrdiff_t where = OVERLAY_POSITION (end);
3641 struct Lisp_Overlay *other, *other_prev;
3642
3643 /* Splice the cons cell TAIL out of overlays_after. */
3644 if (prev)
3645 prev->next = next;
3646 else
3647 set_buffer_overlays_after (buf, next);
3648
3649 /* Search thru overlays_before for where to put it. */
3650 other_prev = NULL;
3651 for (other = buf->overlays_before; other;
3652 other_prev = other, other = other->next)
3653 {
3654 Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
3655 eassert (OVERLAYP (otheroverlay));
3656
3657 Lisp_Object otherend = OVERLAY_END (otheroverlay);
3658 if (OVERLAY_POSITION (otherend) <= where)
3659 break;
3660 }
3661
3662 /* Add TAIL to overlays_before before OTHER. */
3663 tail->next = other;
3664 if (other_prev)
3665 other_prev->next = tail;
3666 else
3667 set_buffer_overlays_before (buf, tail);
3668 tail = prev;
3669 }
3670 } 3471 }
3671
3672 buf->overlay_center = pos;
3673}
3674
3675void
3676adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
3677{
3678 /* After an insertion, the lists are still sorted properly,
3679 but we may need to update the value of the overlay center. */
3680 if (current_buffer->overlay_center >= pos)
3681 current_buffer->overlay_center += length;
3682} 3472}
3683 3473
3684void 3474static void
3685adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) 3475adjust_overlays_for_delete_in_buffer (struct buffer * buf,
3476 ptrdiff_t pos, ptrdiff_t length)
3686{ 3477{
3687 if (current_buffer->overlay_center < pos) 3478 Lisp_Object hit_list = Qnil;
3688 /* The deletion was to our right. No change needed; the before- and 3479 struct itree_node *node;
3689 after-lists are still consistent. */
3690 ;
3691 else if (current_buffer->overlay_center - pos > length)
3692 /* The deletion was to our left. We need to adjust the center value
3693 to account for the change in position, but the lists are consistent
3694 given the new value. */
3695 current_buffer->overlay_center -= length;
3696 else
3697 /* We're right in the middle. There might be things on the after-list
3698 that now belong on the before-list. Recentering will move them,
3699 and also update the center point. */
3700 recenter_overlay_lists (current_buffer, pos);
3701}
3702
3703/* Fix up overlays that were garbled as a result of permuting markers
3704 in the range START through END. Any overlay with at least one
3705 endpoint in this range will need to be unlinked from the overlay
3706 list and reinserted in its proper place.
3707 Such an overlay might even have negative size at this point.
3708 If so, we'll make the overlay empty. */
3709void
3710fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3711{
3712 struct Lisp_Overlay *before_list UNINIT;
3713 struct Lisp_Overlay *after_list UNINIT;
3714 /* These are either nil, indicating that before_list or after_list
3715 should be assigned, or the cons cell the cdr of which should be
3716 assigned. */
3717 struct Lisp_Overlay *beforep = NULL, *afterp = NULL;
3718 /* 'Parent', likewise, indicates a cons cell or
3719 current_buffer->overlays_before or overlays_after, depending
3720 which loop we're in. */
3721 struct Lisp_Overlay *parent;
3722
3723 /* This algorithm shifts links around instead of consing and GCing.
3724 The loop invariant is that before_list (resp. after_list) is a
3725 well-formed list except that its last element, the CDR of beforep
3726 (resp. afterp) if beforep (afterp) isn't nil or before_list
3727 (after_list) if it is, is still uninitialized. So it's not a bug
3728 that before_list isn't initialized, although it may look
3729 strange. */
3730 parent = NULL;
3731 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
3732 tail; tail = tail->next)
3733 {
3734 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3735
3736 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3737 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3738
3739 /* If the overlay is backwards, make it empty. */
3740 if (endpos < startpos)
3741 {
3742 startpos = endpos;
3743 Fset_marker (OVERLAY_START (overlay), make_fixnum (startpos),
3744 Qnil);
3745 }
3746
3747 if (endpos < start)
3748 break;
3749
3750 if (endpos < end
3751 || (startpos >= start && startpos < end))
3752 {
3753 /* Add it to the end of the wrong list. Later on,
3754 recenter_overlay_lists will move it to the right place. */
3755 if (endpos < current_buffer->overlay_center)
3756 {
3757 if (!afterp)
3758 after_list = tail;
3759 else
3760 afterp->next = tail;
3761 afterp = tail;
3762 }
3763 else
3764 {
3765 if (!beforep)
3766 before_list = tail;
3767 else
3768 beforep->next = tail;
3769 beforep = tail;
3770 }
3771 if (!parent)
3772 set_buffer_overlays_before (current_buffer, tail->next);
3773 else
3774 parent->next = tail->next;
3775 }
3776 else
3777 parent = tail;
3778 }
3779 parent = NULL;
3780 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
3781 tail; tail = tail->next)
3782 {
3783 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3784
3785 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3786 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3787
3788 /* If the overlay is backwards, make it empty. */
3789 if (endpos < startpos)
3790 {
3791 startpos = endpos;
3792 Fset_marker (OVERLAY_START (overlay), make_fixnum (startpos),
3793 Qnil);
3794 }
3795 3480
3796 if (startpos >= end) 3481 /* Ideally, the evaporate check would be done directly within
3797 break; 3482 `itree_delete_gap`, but that code isn't supposed to know about overlays,
3483 only about `itree_node`s, so it would break an abstraction boundary. */
3484 itree_delete_gap (buf->overlays, pos, length);
3798 3485
3799 if (startpos >= start 3486 /* Delete any zero-sized overlays at position POS, if the `evaporate'
3800 || (endpos >= start && endpos < end)) 3487 property is set. */
3801 {
3802 if (endpos < current_buffer->overlay_center)
3803 {
3804 if (!afterp)
3805 after_list = tail;
3806 else
3807 afterp->next = tail;
3808 afterp = tail;
3809 }
3810 else
3811 {
3812 if (!beforep)
3813 before_list = tail;
3814 else
3815 beforep->next = tail;
3816 beforep = tail;
3817 }
3818 if (!parent)
3819 set_buffer_overlays_after (current_buffer, tail->next);
3820 else
3821 parent->next = tail->next;
3822 }
3823 else
3824 parent = tail;
3825 }
3826 3488
3827 /* Splice the constructed (wrong) lists into the buffer's lists, 3489 ITREE_FOREACH (node, buf->overlays, pos, pos, ASCENDING)
3828 and let the recenter function make it sane again. */
3829 if (beforep)
3830 { 3490 {
3831 beforep->next = current_buffer->overlays_before; 3491 if (node->end == pos && node->begin == pos
3832 set_buffer_overlays_before (current_buffer, before_list); 3492 && ! NILP (Foverlay_get (node->data, Qevaporate)))
3493 hit_list = Fcons (node->data, hit_list);
3833 } 3494 }
3834 3495
3835 if (afterp) 3496 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
3836 { 3497 Fdelete_overlay (XCAR (hit_list));
3837 afterp->next = current_buffer->overlays_after;
3838 set_buffer_overlays_after (current_buffer, after_list);
3839 }
3840 recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
3841} 3498}
3842 3499
3843/* We have two types of overlay: the one whose ending marker is
3844 after-insertion-marker (this is the usual case) and the one whose
3845 ending marker is before-insertion-marker. When `overlays_before'
3846 contains overlays of the latter type and the former type in this
3847 order and both overlays end at inserting position, inserting a text
3848 increases only the ending marker of the latter type, which results
3849 in incorrect ordering of `overlays_before'.
3850
3851 This function fixes ordering of overlays in the slot
3852 `overlays_before' of the buffer *BP. Before the insertion, `point'
3853 was at PREV, and now is at POS. */
3854
3855void 3500void
3856fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos) 3501adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
3857{ 3502{
3858 /* If parent is nil, replace overlays_before; otherwise, parent->next. */ 3503 if (!current_buffer->indirections)
3859 struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair; 3504 adjust_overlays_for_delete_in_buffer (current_buffer, pos, length);
3860 Lisp_Object tem; 3505 else
3861 ptrdiff_t end UNINIT;
3862
3863 /* After the insertion, the several overlays may be in incorrect
3864 order. The possibility is that, in the list `overlays_before',
3865 an overlay which ends at POS appears after an overlay which ends
3866 at PREV. Since POS is greater than PREV, we must fix the
3867 ordering of these overlays, by moving overlays ends at POS before
3868 the overlays ends at PREV. */
3869
3870 /* At first, find a place where disordered overlays should be linked
3871 in. It is where an overlay which end before POS exists. (i.e. an
3872 overlay whose ending marker is after-insertion-marker if disorder
3873 exists). */
3874 while (tail
3875 && (tem = make_lisp_ptr (tail, Lisp_Vectorlike),
3876 (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
3877 {
3878 parent = tail;
3879 tail = tail->next;
3880 }
3881
3882 /* If we don't find such an overlay,
3883 or the found one ends before PREV,
3884 or the found one is the last one in the list,
3885 we don't have to fix anything. */
3886 if (!tail)
3887 return;
3888 if (end < prev || !tail->next)
3889 return;
3890
3891 right_pair = parent;
3892 parent = tail;
3893 tail = tail->next;
3894
3895 /* Now, end position of overlays in the list TAIL should be before
3896 or equal to PREV. In the loop, an overlay which ends at POS is
3897 moved ahead to the place indicated by the CDR of RIGHT_PAIR. If
3898 we found an overlay which ends before PREV, the remaining
3899 overlays are in correct order. */
3900 while (tail)
3901 { 3506 {
3902 tem = make_lisp_ptr (tail, Lisp_Vectorlike); 3507 struct buffer *base = current_buffer->base_buffer
3903 end = OVERLAY_POSITION (OVERLAY_END (tem)); 3508 ? current_buffer->base_buffer
3904 3509 : current_buffer;
3905 if (end == pos) 3510 Lisp_Object tail, other;
3906 { /* This overlay is disordered. */ 3511 adjust_overlays_for_delete_in_buffer (base, pos, length);
3907 struct Lisp_Overlay *found = tail; 3512 FOR_EACH_LIVE_BUFFER (tail, other)
3908 3513 if (XBUFFER (other)->base_buffer == base)
3909 /* Unlink the found overlay. */ 3514 adjust_overlays_for_delete_in_buffer (XBUFFER (other), pos, length);
3910 tail = found->next;
3911 parent->next = tail;
3912 /* Move an overlay at RIGHT_PLACE to the next of the found one,
3913 and link it into the right place. */
3914 if (!right_pair)
3915 {
3916 found->next = bp->overlays_before;
3917 set_buffer_overlays_before (bp, found);
3918 }
3919 else
3920 {
3921 found->next = right_pair->next;
3922 right_pair->next = found;
3923 }
3924 }
3925 else if (end == prev)
3926 {
3927 parent = tail;
3928 tail = tail->next;
3929 }
3930 else /* No more disordered overlay. */
3931 break;
3932 } 3515 }
3933} 3516}
3517
3934 3518
3935DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0, 3519DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
3936 doc: /* Return t if OBJECT is an overlay. */) 3520 doc: /* Return t if OBJECT is an overlay. */)
@@ -3952,7 +3536,7 @@ for the rear of the overlay advance when text is inserted there
3952 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, 3536 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
3953 Lisp_Object front_advance, Lisp_Object rear_advance) 3537 Lisp_Object front_advance, Lisp_Object rear_advance)
3954{ 3538{
3955 Lisp_Object overlay; 3539 Lisp_Object ov;
3956 struct buffer *b; 3540 struct buffer *b;
3957 3541
3958 if (NILP (buffer)) 3542 if (NILP (buffer))
@@ -3960,6 +3544,10 @@ for the rear of the overlay advance when text is inserted there
3960 else 3544 else
3961 CHECK_BUFFER (buffer); 3545 CHECK_BUFFER (buffer);
3962 3546
3547 b = XBUFFER (buffer);
3548 if (! BUFFER_LIVE_P (b))
3549 error ("Attempt to create overlay in a dead buffer");
3550
3963 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer)) 3551 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
3964 signal_error ("Marker points into wrong buffer", beg); 3552 signal_error ("Marker points into wrong buffer", beg);
3965 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer)) 3553 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
@@ -3974,39 +3562,16 @@ for the rear of the overlay advance when text is inserted there
3974 temp = beg; beg = end; end = temp; 3562 temp = beg; beg = end; end = temp;
3975 } 3563 }
3976 3564
3977 b = XBUFFER (buffer); 3565 ptrdiff_t obeg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3978 3566 ptrdiff_t oend = clip_to_bounds (obeg, XFIXNUM (end), BUF_Z (b));
3979 beg = Fset_marker (Fmake_marker (), beg, buffer); 3567 ov = build_overlay (! NILP (front_advance),
3980 end = Fset_marker (Fmake_marker (), end, buffer); 3568 ! NILP (rear_advance), Qnil);
3981 3569 add_buffer_overlay (b, XOVERLAY (ov), obeg, oend);
3982 if (!NILP (front_advance))
3983 XMARKER (beg)->insertion_type = 1;
3984 if (!NILP (rear_advance))
3985 XMARKER (end)->insertion_type = 1;
3986
3987 overlay = build_overlay (beg, end, Qnil);
3988
3989 /* Put the new overlay on the wrong list. */
3990 end = OVERLAY_END (overlay);
3991 if (OVERLAY_POSITION (end) < b->overlay_center)
3992 {
3993 eassert (b->overlays_after || (XOVERLAY (overlay)->next == NULL));
3994 XOVERLAY (overlay)->next = b->overlays_after;
3995 set_buffer_overlays_after (b, XOVERLAY (overlay));
3996 }
3997 else
3998 {
3999 eassert (b->overlays_before || (XOVERLAY (overlay)->next == NULL));
4000 XOVERLAY (overlay)->next = b->overlays_before;
4001 set_buffer_overlays_before (b, XOVERLAY (overlay));
4002 }
4003 /* This puts it in the right list, and in the right order. */
4004 recenter_overlay_lists (b, b->overlay_center);
4005 3570
4006 /* We don't need to redisplay the region covered by the overlay, because 3571 /* We don't need to redisplay the region covered by the overlay, because
4007 the overlay has no properties at the moment. */ 3572 the overlay has no properties at the moment. */
4008 3573
4009 return overlay; 3574 return ov;
4010} 3575}
4011 3576
4012/* Mark a section of BUF as needing redisplay because of overlays changes. */ 3577/* Mark a section of BUF as needing redisplay because of overlays changes. */
@@ -4028,35 +3593,6 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
4028 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1); 3593 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1);
4029} 3594}
4030 3595
4031/* Remove OVERLAY from LIST. */
4032
4033static struct Lisp_Overlay *
4034unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay)
4035{
4036 register struct Lisp_Overlay *tail, **prev = &list;
4037
4038 for (tail = list; tail; prev = &tail->next, tail = *prev)
4039 if (tail == overlay)
4040 {
4041 *prev = overlay->next;
4042 overlay->next = NULL;
4043 break;
4044 }
4045 return list;
4046}
4047
4048/* Remove OVERLAY from both overlay lists of B. */
4049
4050static void
4051unchain_both (struct buffer *b, Lisp_Object overlay)
4052{
4053 struct Lisp_Overlay *ov = XOVERLAY (overlay);
4054
4055 set_buffer_overlays_before (b, unchain_overlay (b->overlays_before, ov));
4056 set_buffer_overlays_after (b, unchain_overlay (b->overlays_after, ov));
4057 eassert (XOVERLAY (overlay)->next == NULL);
4058}
4059
4060DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, 3596DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
4061 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER. 3597 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
4062If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now. 3598If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
@@ -4067,12 +3603,11 @@ buffer. */)
4067 struct buffer *b, *ob = 0; 3603 struct buffer *b, *ob = 0;
4068 Lisp_Object obuffer; 3604 Lisp_Object obuffer;
4069 specpdl_ref count = SPECPDL_INDEX (); 3605 specpdl_ref count = SPECPDL_INDEX ();
4070 ptrdiff_t n_beg, n_end;
4071 ptrdiff_t o_beg UNINIT, o_end UNINIT; 3606 ptrdiff_t o_beg UNINIT, o_end UNINIT;
4072 3607
4073 CHECK_OVERLAY (overlay); 3608 CHECK_OVERLAY (overlay);
4074 if (NILP (buffer)) 3609 if (NILP (buffer))
4075 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3610 buffer = Foverlay_buffer (overlay);
4076 if (NILP (buffer)) 3611 if (NILP (buffer))
4077 XSETBUFFER (buffer, current_buffer); 3612 XSETBUFFER (buffer, current_buffer);
4078 CHECK_BUFFER (buffer); 3613 CHECK_BUFFER (buffer);
@@ -4094,37 +3629,31 @@ buffer. */)
4094 temp = beg; beg = end; end = temp; 3629 temp = beg; beg = end; end = temp;
4095 } 3630 }
4096 3631
4097 specbind (Qinhibit_quit, Qt); 3632 specbind (Qinhibit_quit, Qt); /* FIXME: Why? */
4098 3633
4099 obuffer = Fmarker_buffer (OVERLAY_START (overlay)); 3634 obuffer = Foverlay_buffer (overlay);
4100 b = XBUFFER (buffer); 3635 b = XBUFFER (buffer);
4101 3636
3637 ptrdiff_t n_beg = clip_to_bounds (BUF_BEG (b), XFIXNUM (beg), BUF_Z (b));
3638 ptrdiff_t n_end = clip_to_bounds (n_beg, XFIXNUM (end), BUF_Z (b));
3639
4102 if (!NILP (obuffer)) 3640 if (!NILP (obuffer))
4103 { 3641 {
4104 ob = XBUFFER (obuffer); 3642 ob = XBUFFER (obuffer);
4105 3643
4106 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay)); 3644 o_beg = OVERLAY_START (overlay);
4107 o_end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3645 o_end = OVERLAY_END (overlay);
3646 }
4108 3647
4109 unchain_both (ob, overlay); 3648 if (! BASE_EQ (buffer, obuffer))
3649 {
3650 if (! NILP (obuffer))
3651 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
3652 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay), n_beg, n_end);
4110 } 3653 }
4111 else 3654 else
4112 /* An overlay not associated with any buffer will normally have its 3655 itree_node_set_region (b->overlays, XOVERLAY (overlay)->interval,
4113 `next' field set to NULL, but not always: when killing a buffer, 3656 n_beg, n_end);
4114 we just set its overlays_after and overlays_before to NULL without
4115 manually setting each overlay's `next' field to NULL.
4116 Let's correct it here, to simplify subsequent assertions.
4117 FIXME: Maybe the better fix is to change `kill-buffer'!? */
4118 XOVERLAY (overlay)->next = NULL;
4119
4120 eassert (XOVERLAY (overlay)->next == NULL);
4121
4122 /* Set the overlay boundaries, which may clip them. */
4123 Fset_marker (OVERLAY_START (overlay), beg, buffer);
4124 Fset_marker (OVERLAY_END (overlay), end, buffer);
4125
4126 n_beg = marker_position (OVERLAY_START (overlay));
4127 n_end = marker_position (OVERLAY_END (overlay));
4128 3657
4129 /* If the overlay has changed buffers, do a thorough redisplay. */ 3658 /* If the overlay has changed buffers, do a thorough redisplay. */
4130 if (!BASE_EQ (buffer, obuffer)) 3659 if (!BASE_EQ (buffer, obuffer))
@@ -4147,8 +3676,6 @@ buffer. */)
4147 modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end)); 3676 modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
4148 } 3677 }
4149 3678
4150 eassert (XOVERLAY (overlay)->next == NULL);
4151
4152 /* Delete the overlay if it is empty after clipping and has the 3679 /* Delete the overlay if it is empty after clipping and has the
4153 evaporate property. */ 3680 evaporate property. */
4154 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate))) 3681 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
@@ -4158,26 +3685,10 @@ buffer. */)
4158 contrary to `Fdelete_overlay's assumptions. 3685 contrary to `Fdelete_overlay's assumptions.
4159 - Most of the work done by Fdelete_overlay has already been done 3686 - Most of the work done by Fdelete_overlay has already been done
4160 here for other reasons. */ 3687 here for other reasons. */
4161 drop_overlay (XBUFFER (buffer), XOVERLAY (overlay)); 3688 drop_overlay (XOVERLAY (overlay));
4162 return unbind_to (count, overlay); 3689 return unbind_to (count, overlay);
4163 } 3690 }
4164 3691
4165 /* Put the overlay into the new buffer's overlay lists, first on the
4166 wrong list. */
4167 if (n_end < b->overlay_center)
4168 {
4169 XOVERLAY (overlay)->next = b->overlays_after;
4170 set_buffer_overlays_after (b, XOVERLAY (overlay));
4171 }
4172 else
4173 {
4174 XOVERLAY (overlay)->next = b->overlays_before;
4175 set_buffer_overlays_before (b, XOVERLAY (overlay));
4176 }
4177
4178 /* This puts it in the right list, and in the right order. */
4179 recenter_overlay_lists (b, b->overlay_center);
4180
4181 return unbind_to (count, overlay); 3692 return unbind_to (count, overlay);
4182} 3693}
4183 3694
@@ -4185,21 +3696,18 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
4185 doc: /* Delete the overlay OVERLAY from its buffer. */) 3696 doc: /* Delete the overlay OVERLAY from its buffer. */)
4186 (Lisp_Object overlay) 3697 (Lisp_Object overlay)
4187{ 3698{
4188 Lisp_Object buffer;
4189 struct buffer *b; 3699 struct buffer *b;
4190 specpdl_ref count = SPECPDL_INDEX (); 3700 specpdl_ref count = SPECPDL_INDEX ();
4191 3701
4192 CHECK_OVERLAY (overlay); 3702 CHECK_OVERLAY (overlay);
4193 3703
4194 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3704 b = OVERLAY_BUFFER (overlay);
4195 if (NILP (buffer)) 3705 if (! b)
4196 return Qnil; 3706 return Qnil;
4197 3707
4198 b = XBUFFER (buffer);
4199 specbind (Qinhibit_quit, Qt); 3708 specbind (Qinhibit_quit, Qt);
4200 3709
4201 unchain_both (b, overlay); 3710 drop_overlay (XOVERLAY (overlay));
4202 drop_overlay (b, XOVERLAY (overlay));
4203 3711
4204 /* When deleting an overlay with before or after strings, turn off 3712 /* When deleting an overlay with before or after strings, turn off
4205 display optimizations for the affected buffer, on the basis that 3713 display optimizations for the affected buffer, on the basis that
@@ -4230,8 +3738,10 @@ DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
4230 (Lisp_Object overlay) 3738 (Lisp_Object overlay)
4231{ 3739{
4232 CHECK_OVERLAY (overlay); 3740 CHECK_OVERLAY (overlay);
3741 if (! OVERLAY_BUFFER (overlay))
3742 return Qnil;
4233 3743
4234 return (Fmarker_position (OVERLAY_START (overlay))); 3744 return make_fixnum (OVERLAY_START (overlay));
4235} 3745}
4236 3746
4237DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0, 3747DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
@@ -4239,8 +3749,10 @@ DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
4239 (Lisp_Object overlay) 3749 (Lisp_Object overlay)
4240{ 3750{
4241 CHECK_OVERLAY (overlay); 3751 CHECK_OVERLAY (overlay);
3752 if (! OVERLAY_BUFFER (overlay))
3753 return Qnil;
4242 3754
4243 return (Fmarker_position (OVERLAY_END (overlay))); 3755 return make_fixnum (OVERLAY_END (overlay));
4244} 3756}
4245 3757
4246DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0, 3758DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
@@ -4248,9 +3760,16 @@ DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
4248Return nil if OVERLAY has been deleted. */) 3760Return nil if OVERLAY has been deleted. */)
4249 (Lisp_Object overlay) 3761 (Lisp_Object overlay)
4250{ 3762{
3763 Lisp_Object buffer;
3764
4251 CHECK_OVERLAY (overlay); 3765 CHECK_OVERLAY (overlay);
4252 3766
4253 return Fmarker_buffer (OVERLAY_START (overlay)); 3767 if (! OVERLAY_BUFFER (overlay))
3768 return Qnil;
3769
3770 XSETBUFFER (buffer, OVERLAY_BUFFER (overlay));
3771
3772 return buffer;
4254} 3773}
4255 3774
4256DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0, 3775DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
@@ -4261,7 +3780,7 @@ OVERLAY. */)
4261{ 3780{
4262 CHECK_OVERLAY (overlay); 3781 CHECK_OVERLAY (overlay);
4263 3782
4264 return Fcopy_sequence (XOVERLAY (overlay)->plist); 3783 return Fcopy_sequence (OVERLAY_PLIST (overlay));
4265} 3784}
4266 3785
4267 3786
@@ -4289,8 +3808,7 @@ interest. */)
4289 3808
4290 /* 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.
4291 Store the length in len. */ 3810 Store the length in len. */
4292 noverlays = overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len, 3811 noverlays = overlays_at (XFIXNUM (pos), true, &overlay_vec, &len, NULL);
4293 NULL, NULL, 0);
4294 3812
4295 if (!NILP (sorted)) 3813 if (!NILP (sorted))
4296 noverlays = sort_overlays (overlay_vec, noverlays, 3814 noverlays = sort_overlays (overlay_vec, noverlays,
@@ -4316,7 +3834,9 @@ and also contained within the specified region.
4316 3834
4317Empty overlays are included in the result if they are located at BEG, 3835Empty overlays are included in the result if they are located at BEG,
4318between BEG and END, or at END provided END denotes the position at the 3836between BEG and END, or at END provided END denotes the position at the
4319end of the accessible part of the buffer. */) 3837end of the accessible part of the buffer.
3838
3839The resulting list of overlays is in an arbitrary unpredictable order. */)
4320 (Lisp_Object beg, Lisp_Object end) 3840 (Lisp_Object beg, Lisp_Object end)
4321{ 3841{
4322 ptrdiff_t len, noverlays; 3842 ptrdiff_t len, noverlays;
@@ -4335,7 +3855,7 @@ end of the accessible part of the buffer. */)
4335 /* Put all the overlays we want in a vector in overlay_vec. 3855 /* Put all the overlays we want in a vector in overlay_vec.
4336 Store the length in len. */ 3856 Store the length in len. */
4337 noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len, 3857 noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len,
4338 NULL, NULL); 3858 true, false, NULL);
4339 3859
4340 /* Make a list of them all. */ 3860 /* Make a list of them all. */
4341 result = Flist (noverlays, overlay_vec); 3861 result = Flist (noverlays, overlay_vec);
@@ -4351,39 +3871,12 @@ If there are no overlay boundaries from POS to (point-max),
4351the value is (point-max). */) 3871the value is (point-max). */)
4352 (Lisp_Object pos) 3872 (Lisp_Object pos)
4353{ 3873{
4354 ptrdiff_t i, len, noverlays;
4355 ptrdiff_t endpos;
4356 Lisp_Object *overlay_vec;
4357
4358 CHECK_FIXNUM_COERCE_MARKER (pos); 3874 CHECK_FIXNUM_COERCE_MARKER (pos);
4359 3875
4360 if (!buffer_has_overlays ()) 3876 if (!buffer_has_overlays ())
4361 return make_fixnum (ZV); 3877 return make_fixnum (ZV);
4362 3878
4363 len = 10; 3879 return make_fixnum (next_overlay_change (XFIXNUM (pos)));
4364 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4365
4366 /* Put all the overlays we want in a vector in overlay_vec.
4367 Store the length in len.
4368 endpos gets the position where the next overlay starts. */
4369 noverlays = overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
4370 &endpos, 0, 1);
4371
4372 /* If any of these overlays ends before endpos,
4373 use its ending point instead. */
4374 for (i = 0; i < noverlays; i++)
4375 {
4376 Lisp_Object oend;
4377 ptrdiff_t oendpos;
4378
4379 oend = OVERLAY_END (overlay_vec[i]);
4380 oendpos = OVERLAY_POSITION (oend);
4381 if (oendpos < endpos)
4382 endpos = oendpos;
4383 }
4384
4385 xfree (overlay_vec);
4386 return make_fixnum (endpos);
4387} 3880}
4388 3881
4389DEFUN ("previous-overlay-change", Fprevious_overlay_change, 3882DEFUN ("previous-overlay-change", Fprevious_overlay_change,
@@ -4393,32 +3886,15 @@ If there are no overlay boundaries from (point-min) to POS,
4393the value is (point-min). */) 3886the value is (point-min). */)
4394 (Lisp_Object pos) 3887 (Lisp_Object pos)
4395{ 3888{
4396 ptrdiff_t prevpos;
4397 Lisp_Object *overlay_vec;
4398 ptrdiff_t len;
4399 3889
4400 CHECK_FIXNUM_COERCE_MARKER (pos); 3890 CHECK_FIXNUM_COERCE_MARKER (pos);
4401 3891
4402 if (!buffer_has_overlays ()) 3892 if (!buffer_has_overlays ())
4403 return make_fixnum (BEGV); 3893 return make_fixnum (BEGV);
4404 3894
4405 /* At beginning of buffer, we know the answer; 3895 return make_fixnum (previous_overlay_change (XFIXNUM (pos)));
4406 avoid bug subtracting 1 below. */
4407 if (XFIXNUM (pos) == BEGV)
4408 return pos;
4409
4410 len = 10;
4411 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4412
4413 /* Put all the overlays we want in a vector in overlay_vec.
4414 Store the length in len.
4415 prevpos gets the position of the previous change. */
4416 overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
4417 0, &prevpos, 1);
4418
4419 xfree (overlay_vec);
4420 return make_fixnum (prevpos);
4421} 3896}
3897
4422 3898
4423/* These functions are for debugging overlays. */ 3899/* These functions are for debugging overlays. */
4424 3900
@@ -4428,19 +3904,16 @@ The car has all the overlays before the overlay center;
4428the cdr has all the overlays after the overlay center. 3904the cdr has all the overlays after the overlay center.
4429Recentering overlays moves overlays between these lists. 3905Recentering overlays moves overlays between these lists.
4430The lists you get are copies, so that changing them has no effect. 3906The lists you get are copies, so that changing them has no effect.
4431However, the overlays you get are the real objects that the buffer uses. */) 3907However, the overlays you get are the real objects that the buffer uses. */)
4432 (void) 3908 (void)
4433{ 3909{
4434 Lisp_Object before = Qnil, after = Qnil; 3910 Lisp_Object overlays = Qnil;
3911 struct itree_node *node;
4435 3912
4436 for (struct Lisp_Overlay *ol = current_buffer->overlays_before; 3913 ITREE_FOREACH (node, current_buffer->overlays, BEG, Z, DESCENDING)
4437 ol; ol = ol->next) 3914 overlays = Fcons (node->data, overlays);
4438 before = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), before);
4439 for (struct Lisp_Overlay *ol = current_buffer->overlays_after;
4440 ol; ol = ol->next)
4441 after = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), after);
4442 3915
4443 return Fcons (Fnreverse (before), Fnreverse (after)); 3916 return Fcons (overlays, Qnil);
4444} 3917}
4445 3918
4446DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0, 3919DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
@@ -4449,11 +3922,8 @@ That makes overlay lookup faster for positions near POS (but perhaps slower
4449for positions far away from POS). */) 3922for positions far away from POS). */)
4450 (Lisp_Object pos) 3923 (Lisp_Object pos)
4451{ 3924{
4452 ptrdiff_t p;
4453 CHECK_FIXNUM_COERCE_MARKER (pos); 3925 CHECK_FIXNUM_COERCE_MARKER (pos);
4454 3926 /* Noop */
4455 p = clip_to_bounds (PTRDIFF_MIN, XFIXNUM (pos), PTRDIFF_MAX);
4456 recenter_overlay_lists (current_buffer, p);
4457 return Qnil; 3927 return Qnil;
4458} 3928}
4459 3929
@@ -4470,12 +3940,13 @@ DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
4470VALUE will be returned.*/) 3940VALUE will be returned.*/)
4471 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value) 3941 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
4472{ 3942{
4473 Lisp_Object tail, buffer; 3943 Lisp_Object tail;
3944 struct buffer *b;
4474 bool changed; 3945 bool changed;
4475 3946
4476 CHECK_OVERLAY (overlay); 3947 CHECK_OVERLAY (overlay);
4477 3948
4478 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3949 b = OVERLAY_BUFFER (overlay);
4479 3950
4480 for (tail = XOVERLAY (overlay)->plist; 3951 for (tail = XOVERLAY (overlay)->plist;
4481 CONSP (tail) && CONSP (XCDR (tail)); 3952 CONSP (tail) && CONSP (XCDR (tail));
@@ -4491,15 +3962,14 @@ VALUE will be returned.*/)
4491 set_overlay_plist 3962 set_overlay_plist
4492 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist))); 3963 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist)));
4493 found: 3964 found:
4494 if (! NILP (buffer)) 3965 if (b)
4495 { 3966 {
4496 if (changed) 3967 if (changed)
4497 modify_overlay (XBUFFER (buffer), 3968 modify_overlay (b, OVERLAY_START (overlay),
4498 marker_position (OVERLAY_START (overlay)), 3969 OVERLAY_END (overlay));
4499 marker_position (OVERLAY_END (overlay)));
4500 if (EQ (prop, Qevaporate) && ! NILP (value) 3970 if (EQ (prop, Qevaporate) && ! NILP (value)
4501 && (OVERLAY_POSITION (OVERLAY_START (overlay)) 3971 && (OVERLAY_START (overlay)
4502 == OVERLAY_POSITION (OVERLAY_END (overlay)))) 3972 == OVERLAY_END (overlay)))
4503 Fdelete_overlay (overlay); 3973 Fdelete_overlay (overlay);
4504 } 3974 }
4505 3975
@@ -4570,70 +4040,33 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4570 4040
4571 if (!after) 4041 if (!after)
4572 { 4042 {
4043 struct itree_node *node;
4044 EMACS_INT begin_arg = XFIXNUM (start);
4045 EMACS_INT end_arg = XFIXNUM (end);
4573 /* We are being called before a change. 4046 /* We are being called before a change.
4574 Scan the overlays to find the functions to call. */ 4047 Scan the overlays to find the functions to call. */
4575 last_overlay_modification_hooks_used = 0; 4048 last_overlay_modification_hooks_used = 0;
4576 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
4577 tail; tail = tail->next)
4578 {
4579 ptrdiff_t startpos, endpos;
4580 Lisp_Object ostart, oend;
4581
4582 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4583
4584 ostart = OVERLAY_START (overlay);
4585 oend = OVERLAY_END (overlay);
4586 endpos = OVERLAY_POSITION (oend);
4587 if (XFIXNAT (start) > endpos)
4588 break;
4589 startpos = OVERLAY_POSITION (ostart);
4590 if (insertion && (XFIXNAT (start) == startpos
4591 || XFIXNAT (end) == startpos))
4592 {
4593 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4594 if (!NILP (prop))
4595 add_overlay_mod_hooklist (prop, overlay);
4596 }
4597 if (insertion && (XFIXNAT (start) == endpos
4598 || XFIXNAT (end) == endpos))
4599 {
4600 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4601 if (!NILP (prop))
4602 add_overlay_mod_hooklist (prop, overlay);
4603 }
4604 /* Test for intersecting intervals. This does the right thing
4605 for both insertion and deletion. */
4606 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
4607 {
4608 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
4609 if (!NILP (prop))
4610 add_overlay_mod_hooklist (prop, overlay);
4611 }
4612 }
4613 4049
4614 for (struct Lisp_Overlay *tail = current_buffer->overlays_after; 4050 if (! current_buffer->overlays)
4615 tail; tail = tail->next) 4051 return;
4052 ITREE_FOREACH (node, current_buffer->overlays,
4053 begin_arg - (insertion ? 1 : 0),
4054 end_arg + (insertion ? 1 : 0),
4055 ASCENDING)
4616 { 4056 {
4617 ptrdiff_t startpos, endpos; 4057 Lisp_Object overlay = node->data;
4618 Lisp_Object ostart, oend; 4058 ptrdiff_t obegin = OVERLAY_START (overlay);
4619 4059 ptrdiff_t oend = OVERLAY_END (overlay);
4620 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike); 4060
4621 4061 if (insertion && (begin_arg == obegin
4622 ostart = OVERLAY_START (overlay); 4062 || end_arg == obegin))
4623 oend = OVERLAY_END (overlay);
4624 startpos = OVERLAY_POSITION (ostart);
4625 endpos = OVERLAY_POSITION (oend);
4626 if (XFIXNAT (end) < startpos)
4627 break;
4628 if (insertion && (XFIXNAT (start) == startpos
4629 || XFIXNAT (end) == startpos))
4630 { 4063 {
4631 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 4064 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4632 if (!NILP (prop)) 4065 if (!NILP (prop))
4633 add_overlay_mod_hooklist (prop, overlay); 4066 add_overlay_mod_hooklist (prop, overlay);
4634 } 4067 }
4635 if (insertion && (XFIXNAT (start) == endpos 4068 if (insertion && (begin_arg == oend
4636 || XFIXNAT (end) == endpos)) 4069 || end_arg == oend))
4637 { 4070 {
4638 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks); 4071 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4639 if (!NILP (prop)) 4072 if (!NILP (prop))
@@ -4641,7 +4074,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4641 } 4074 }
4642 /* Test for intersecting intervals. This does the right thing 4075 /* Test for intersecting intervals. This does the right thing
4643 for both insertion and deletion. */ 4076 for both insertion and deletion. */
4644 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) 4077 if (! insertion || (end_arg > obegin && begin_arg < oend))
4645 { 4078 {
4646 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks); 4079 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
4647 if (!NILP (prop)) 4080 if (!NILP (prop))
@@ -4649,7 +4082,6 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4649 } 4082 }
4650 } 4083 }
4651 } 4084 }
4652
4653 { 4085 {
4654 /* Call the functions recorded in last_overlay_modification_hooks. 4086 /* Call the functions recorded in last_overlay_modification_hooks.
4655 First copy the vector contents, in case some of these hooks 4087 First copy the vector contents, in case some of these hooks
@@ -4672,7 +4104,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4672 (which makes its markers' buffers be nil), or that (due to 4104 (which makes its markers' buffers be nil), or that (due to
4673 some bug) it belongs to a different buffer. Only run this 4105 some bug) it belongs to a different buffer. Only run this
4674 hook if the overlay belongs to the current buffer. */ 4106 hook if the overlay belongs to the current buffer. */
4675 if (XMARKER (OVERLAY_START (overlay_i))->buffer == current_buffer) 4107 if (OVERLAY_BUFFER (overlay_i) == current_buffer)
4676 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3); 4108 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
4677 } 4109 }
4678 4110
@@ -4694,40 +4126,6 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after,
4694 } 4126 }
4695} 4127}
4696 4128
4697/* Delete any zero-sized overlays at position POS, if the `evaporate'
4698 property is set. */
4699void
4700evaporate_overlays (ptrdiff_t pos)
4701{
4702 Lisp_Object hit_list = Qnil;
4703 if (pos <= current_buffer->overlay_center)
4704 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
4705 tail; tail = tail->next)
4706 {
4707 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4708 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
4709 if (endpos < pos)
4710 break;
4711 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
4712 && ! NILP (Foverlay_get (overlay, Qevaporate)))
4713 hit_list = Fcons (overlay, hit_list);
4714 }
4715 else
4716 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
4717 tail; tail = tail->next)
4718 {
4719 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4720 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4721 if (startpos > pos)
4722 break;
4723 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
4724 && ! NILP (Foverlay_get (overlay, Qevaporate)))
4725 hit_list = Fcons (overlay, hit_list);
4726 }
4727 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4728 Fdelete_overlay (XCAR (hit_list));
4729}
4730
4731/*********************************************************************** 4129/***********************************************************************
4732 Allocation with mmap 4130 Allocation with mmap
4733 ***********************************************************************/ 4131 ***********************************************************************/
@@ -5352,9 +4750,7 @@ init_buffer_once (void)
5352 bset_mark_active (&buffer_defaults, Qnil); 4750 bset_mark_active (&buffer_defaults, Qnil);
5353 bset_file_format (&buffer_defaults, Qnil); 4751 bset_file_format (&buffer_defaults, Qnil);
5354 bset_auto_save_file_format (&buffer_defaults, Qt); 4752 bset_auto_save_file_format (&buffer_defaults, Qt);
5355 set_buffer_overlays_before (&buffer_defaults, NULL); 4753 buffer_defaults.overlays = NULL;
5356 set_buffer_overlays_after (&buffer_defaults, NULL);
5357 buffer_defaults.overlay_center = BEG;
5358 4754
5359 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8); 4755 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8);
5360 bset_truncate_lines (&buffer_defaults, Qnil); 4756 bset_truncate_lines (&buffer_defaults, Qnil);
@@ -5562,6 +4958,48 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5562 emacs_abort (); 4958 emacs_abort ();
5563} 4959}
5564 4960
4961#ifdef ITREE_DEBUG
4962static Lisp_Object
4963make_lispy_itree_node (const struct itree_node *node)
4964{
4965 return listn (12,
4966 intern (":begin"),
4967 make_fixnum (node->begin),
4968 intern (":end"),
4969 make_fixnum (node->end),
4970 intern (":limit"),
4971 make_fixnum (node->limit),
4972 intern (":offset"),
4973 make_fixnum (node->offset),
4974 intern (":rear-advance"),
4975 node->rear_advance ? Qt : Qnil,
4976 intern (":front-advance"),
4977 node->front_advance ? Qt : Qnil);
4978}
4979
4980static Lisp_Object
4981overlay_tree (const struct itree_tree *tree,
4982 const struct itree_node *node)
4983{
4984 if (node == ITREE_NULL)
4985 return Qnil;
4986 return list3 (make_lispy_itree_node (node),
4987 overlay_tree (tree, node->left),
4988 overlay_tree (tree, node->right));
4989}
4990
4991DEFUN ("overlay-tree", Foverlay_tree, Soverlay_tree, 0, 1, 0,
4992 doc: /* Get the overlay tree for BUFFER. */)
4993 (Lisp_Object buffer)
4994{
4995 struct buffer *b = decode_buffer (buffer);
4996 if (! b->overlays)
4997 return Qnil;
4998 return overlay_tree (b->overlays, b->overlays->root);
4999}
5000#endif
5001
5002
5565 5003
5566/* Initialize the buffer routines. */ 5004/* Initialize the buffer routines. */
5567void 5005void
@@ -6533,6 +5971,10 @@ There is no reason to change that value except for debugging purposes. */);
6533 5971
6534 DEFSYM (Qautosaved, "autosaved"); 5972 DEFSYM (Qautosaved, "autosaved");
6535 5973
5974#ifdef ITREE_DEBUG
5975 defsubr (&Soverlay_tree);
5976#endif
5977
6536 DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save"); 5978 DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save");
6537 5979
6538 DEFSYM (Qbuffer_stale_function, "buffer-stale-function"); 5980 DEFSYM (Qbuffer_stale_function, "buffer-stale-function");