aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorAndreas Politz2017-02-07 17:56:50 +0100
committerAndreas Politz2017-10-04 22:32:26 +0200
commit8d7bdfa3fca076b34aaf86548d3243bee11872ad (patch)
tree419c7897f336ad206bb9e99824f35819ba9796c1 /src/buffer.c
parentf204e6e1a418073bd1e24a83947f1f3c53581c7f (diff)
downloademacs-8d7bdfa3fca076b34aaf86548d3243bee11872ad.tar.gz
emacs-8d7bdfa3fca076b34aaf86548d3243bee11872ad.zip
Provide a new tree data-structure for overlays.
* src/itree.c (interval_generator_narrow, interval_generator_next) (interval_node_init, interval_node_begin) (interval_node_end, interval_node_set_region) (interval_tree_create, interval_tree_clear) (interval_tree_init, interval_tree_destroy) (interval_tree_size, interval_tree_insert) (interval_tree_contains, interval_tree_remove) (interval_tree_validate, interval_tree_iter_start) (interval_tree_iter_finish, interval_tree_iter_next) (interval_tree_iter_ensure_space, interval_tree_max_height) (interval_tree_insert_gap, interval_tree_delete_gap) (interval_generator_create, interval_generator_reset) (interval_generator_ensure_space, interval_node_intersects) (interval_generator_next, interval_generator_narrow) (interval_generator_destroy, interval_stack_create) (interval_stack_destroy, interval_stack_clear) (interval_stack_ensure_space, interval_stack_push) (interval_stack_push_flagged, interval_stack_pop) (interval_tree_update_limit, interval_tree_inherit_offset) (interval_tree_propagate_limit, interval_tree_rotate_left) (interval_tree_rotate_right, interval_tree_insert_fix) (interval_tree_remove_fix, interval_tree_transplant) (interval_tree_subtree_min): New file and new functions. * src/itree.h: New file. * configure.ac: Create Makefile for manual overlay tests. * src/Makefile.in: Add itree.o target. * src/alloc.c (build_overlay, mark_overlay, mark_buffer) (sweep_misc, sweep_buffers): Adapt to new tree data-structure. * src/buffer.c (overlays_in, overlays_at): Remove unused arguments prev_ptr and change_req, adapt to new data-structure and reuse code. (copy_overlays, drop_overlays, delete_all_overlays) (reset_buffer, kill-buffer, buffer-swap-text, next_overlay_change) (previous_overlay_change, mouse_face_overlay_overlaps) (disable_line_numbers_overlay_at_eob, overlay_touches_p) (overlay_strings, adjust_overlays_for_insert) (adjust_overlays_for_delete, overlayp, make-overlay, move-overlay) (delete-overlay, overlay-start, overlay-end, overlay-buffer) (overlay-properties, overlays-at, overlays-in) (next-overlay-change, previous-overlay-change, overlay-put) (overlay-get, report_overlay_modification, evaporate_overlays) (init_buffer_once): Adapt to changes and tree data-structure. (overlay-lists, overlay-recenter): Funtions are now obsolete, but kept anyway. (set_buffer_overlays_before, set_buffer_overlays_after) (recenter_overlay_lists,fix_start_end_in_overlays,fix_overlays_before) (unchain_overlay,): Removed functions of the old list data-structure. (swap_buffer_overlays, make_sortvec_item): New functions. (sort_overlays): Adapt to changes and tree data-structure. (sortvec): Moved to buffer.h . (make_lispy_interval_node, overlay_tree, overlay-tree) [ITREE_DEBUG]: New debugging functions. * src/buffer.h (overlays_before, overlays_after): Removed struct member of the list data-structure. (overlays): Added tree struct member. (sortvec): Moved here from buffer.c . (GET_OVERLAYS_AT): Adapt to changes. (set_buffer_intervals, OVERLAY_START, OVERLAY_END, OVERLAY_PLIST): Adapt to tree data-structure. (OVERLAY_POSITION): Removed macro of the list data-structure. (OVERLAY_REAR_ADVANCE_P, OVERLAY_FRONT_ADVANCE_P): New macros. (overlay_start, overlay_end) (set_overlay_region, maybe_alloc_buffer_overlays) (free_buffer_overlays, add_buffer_overlay) (remove_buffer_overlay, buffer_overlay_iter_start) (buffer_overlay_iter_next, buffer_overlay_iter_finish) (buffer_overlay_iter_narrow): New functions. (compare_overlays, make_sortvec_item): Export functions. * src/editfns.c (overlays_around): Reuse overlays_in. (get-pos-property): Adapt to tree data-structure. (transpose-regions): Remove call to deleted function. * src/fileio.c: (insert-file-contents): Remove references to deleted struct member. * src/fns.c (internal_equal): Adapt to tree data-structure. * src/indent.c (check_display_width): Adapt to tree data-structure. (skip_invisible): Remove call to deleted function. * src/insdel.c (adjust_markers_for_insert): Remove calls to deleted functions. * src/intervals.c (adjust_for_invis_intang): Adapt to tree data-structure. * src/keyboard.c (adjust_point_for_property): Adapt to tree data-structure. * src/lisp.h (Lisp_Overlay): Modified struct layout. * src/print.c (temp_output_buffer_setup, print_object): Adapt to tree data-structure. * src/textprop.c (get_char_property_and_overlay): Adapt to tree data-structure. Take advantage of the new data-structure. * src/window.h (overlay_matches_window): New function. * src/xdisp.h (next_overlay_change): Removed function. Use next-overlay-change, which does not use xmalloc anymore. (handle_single_display_spec, load_overlay_strings) (back_to_previous_visible_line_start, note_mouse_highlight): Adapt to tree data-structure. (move_it_to, display_line): Remove calls to deleted functions. * src/xfaces.c (face_at_buffer_position): Adapt to changes and tree data-structure. * test/src/buffer-tests.el: Many tests regarding overlays added. * test/manual/noverlay/itree-tests.c: New file with tests of the tree data-structure on the C level. * test/manual/noverlay/Makefile.in: New file. * test/manual/noverlay/check-sanitize.sh: New file. * test/manual/noverlay/emacs-compat.h: New file. * test/manual/noverlay/.gitignore: New file. * test/manual/noverlay/overlay-perf.el: New file providing performance tests. * test/manual/noverlay/many-errors.h: New file.
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c1458
1 files changed, 406 insertions, 1052 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 76670b89545..21c040ad0e1 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -44,6 +44,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
44#include "keymap.h" 44#include "keymap.h"
45#include "frame.h" 45#include "frame.h"
46#include "xwidget.h" 46#include "xwidget.h"
47#include "itree.h"
47 48
48#ifdef WINDOWSNT 49#ifdef WINDOWSNT
49#include "w32heap.h" /* for mmap_* */ 50#include "w32heap.h" /* for mmap_* */
@@ -120,7 +121,7 @@ static Lisp_Object QSFundamental; /* A string "Fundamental". */
120 121
121static void alloc_buffer_text (struct buffer *, ptrdiff_t); 122static void alloc_buffer_text (struct buffer *, ptrdiff_t);
122static void free_buffer_text (struct buffer *b); 123static void free_buffer_text (struct buffer *b);
123static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *); 124static void copy_overlays (struct buffer *, struct buffer *);
124static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t); 125static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
125static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool); 126static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool);
126 127
@@ -600,51 +601,30 @@ even if it is dead. The return value is never nil. */)
600} 601}
601 602
602 603
603/* Return a list of overlays which is a copy of the overlay list 604/* Copy overlays of buffer FROM to buffer TO. */
604 LIST, but for buffer B. */
605 605
606static struct Lisp_Overlay * 606static void
607copy_overlays (struct buffer *b, struct Lisp_Overlay *list) 607copy_overlays (struct buffer *from, struct buffer *to)
608{ 608{
609 struct Lisp_Overlay *result = NULL, *tail = NULL; 609 eassert (to && ! to->overlays);
610 610
611 for (; list; list = list->next) 611 struct interval_node *node;
612 {
613 Lisp_Object overlay, start, end;
614 struct Lisp_Marker *m;
615
616 eassert (MARKERP (list->start));
617 m = XMARKER (list->start);
618 start = build_marker (b, m->charpos, m->bytepos);
619 XMARKER (start)->insertion_type = m->insertion_type;
620
621 eassert (MARKERP (list->end));
622 m = XMARKER (list->end);
623 end = build_marker (b, m->charpos, m->bytepos);
624 XMARKER (end)->insertion_type = m->insertion_type;
625
626 overlay = build_overlay (start, end, Fcopy_sequence (list->plist));
627 if (tail)
628 tail = tail->next = XOVERLAY (overlay);
629 else
630 result = tail = XOVERLAY (overlay);
631 }
632
633 return result;
634}
635 612
636/* Set an appropriate overlay of B. */ 613 if (! from->overlays)
614 return;
637 615
638static void 616 buffer_overlay_iter_start (from, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING);
639set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o)
640{
641 b->overlays_before = o;
642}
643 617
644static void 618 while ((node = buffer_overlay_iter_next (from)))
645set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o) 619 {
646{ 620 Lisp_Object ov = node->data;
647 b->overlays_after = o; 621 Lisp_Object copy = build_overlay (node->begin, node->end,
622 node->front_advance,
623 node->rear_advance,
624 Fcopy_sequence (OVERLAY_PLIST (ov)));
625 add_buffer_overlay (to, XOVERLAY (copy));
626 }
627 buffer_overlay_iter_finish (from);
648} 628}
649 629
650/* Clone per-buffer values of buffer FROM. 630/* Clone per-buffer values of buffer FROM.
@@ -681,8 +661,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to)
681 661
682 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags); 662 memcpy (to->local_flags, from->local_flags, sizeof to->local_flags);
683 663
684 set_buffer_overlays_before (to, copy_overlays (to, from->overlays_before)); 664 copy_overlays (from, to);
685 set_buffer_overlays_after (to, copy_overlays (to, from->overlays_after));
686 665
687 /* Get (a copy of) the alist of Lisp-level local variables of FROM 666 /* Get (a copy of) the alist of Lisp-level local variables of FROM
688 and install that in TO. */ 667 and install that in TO. */
@@ -867,17 +846,16 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
867 return buf; 846 return buf;
868} 847}
869 848
870/* Mark OV as no longer associated with B. */ 849/* Mark OV as no longer associated with its buffer. */
871 850
872static void 851static void
873drop_overlay (struct buffer *b, struct Lisp_Overlay *ov) 852drop_overlay (struct Lisp_Overlay *ov)
874{ 853{
875 eassert (b == XBUFFER (Fmarker_buffer (ov->start))); 854 if (! ov->buffer)
876 modify_overlay (b, marker_position (ov->start), 855 return;
877 marker_position (ov->end));
878 unchain_marker (XMARKER (ov->start));
879 unchain_marker (XMARKER (ov->end));
880 856
857 modify_overlay (ov->buffer, overlay_start (ov), overlay_end (ov));
858 remove_buffer_overlay (ov->buffer, ov);
881} 859}
882 860
883/* Delete all overlays of B and reset its overlay lists. */ 861/* Delete all overlays of B and reset its overlay lists. */
@@ -885,26 +863,20 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
885void 863void
886delete_all_overlays (struct buffer *b) 864delete_all_overlays (struct buffer *b)
887{ 865{
888 struct Lisp_Overlay *ov, *next; 866 struct interval_node *node;
889 867
890 /* FIXME: Since each drop_overlay will scan BUF_MARKERS to unlink its 868 if (! b->overlays)
891 markers, we have an unneeded O(N^2) behavior here. */ 869 return;
892 for (ov = b->overlays_before; ov; ov = next)
893 {
894 drop_overlay (b, ov);
895 next = ov->next;
896 ov->next = NULL;
897 }
898 870
899 for (ov = b->overlays_after; ov; ov = next) 871 buffer_overlay_iter_start (b, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING);
872 while ((node = buffer_overlay_iter_next (b)))
900 { 873 {
901 drop_overlay (b, ov); 874 modify_overlay (b, node->begin, node->end);
902 next = ov->next; 875 /* Where are the nodes freed ? --ap */
903 ov->next = NULL; 876 XOVERLAY (node->data)->buffer = NULL;
904 } 877 }
905 878 buffer_overlay_iter_finish (b);
906 set_buffer_overlays_before (b, NULL); 879 interval_tree_clear (b->overlays);
907 set_buffer_overlays_after (b, NULL);
908} 880}
909 881
910/* Reinitialize everything about a buffer except its name and contents 882/* Reinitialize everything about a buffer except its name and contents
@@ -932,9 +904,7 @@ reset_buffer (register struct buffer *b)
932 b->auto_save_failure_time = 0; 904 b->auto_save_failure_time = 0;
933 bset_auto_save_file_name (b, Qnil); 905 bset_auto_save_file_name (b, Qnil);
934 bset_read_only (b, Qnil); 906 bset_read_only (b, Qnil);
935 set_buffer_overlays_before (b, NULL); 907 b->overlays = NULL;
936 set_buffer_overlays_after (b, NULL);
937 b->overlay_center = BEG;
938 bset_mark_active (b, Qnil); 908 bset_mark_active (b, Qnil);
939 bset_point_before_scroll (b, Qnil); 909 bset_point_before_scroll (b, Qnil);
940 bset_file_format (b, Qnil); 910 bset_file_format (b, Qnil);
@@ -1843,10 +1813,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1843 1813
1844 /* Perhaps we should explicitly free the interval tree here... */ 1814 /* Perhaps we should explicitly free the interval tree here... */
1845 } 1815 }
1846 /* Since we've unlinked the markers, the overlays can't be here any more 1816 delete_all_overlays (b);
1847 either. */ 1817 free_buffer_overlays (b);
1848 b->overlays_before = NULL;
1849 b->overlays_after = NULL;
1850 1818
1851 /* Reset the local variables, so that this buffer's local values 1819 /* Reset the local variables, so that this buffer's local values
1852 won't be protected from GC. They would be protected 1820 won't be protected from GC. They would be protected
@@ -2254,6 +2222,31 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
2254 return byte_pos; 2222 return byte_pos;
2255} 2223}
2256 2224
2225static void
2226swap_buffer_overlays (struct buffer *buffer, struct buffer *other)
2227{
2228 struct interval_node *node;
2229
2230 if (buffer->overlays)
2231 {
2232 buffer_overlay_iter_start (buffer, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING);
2233 while ((node = buffer_overlay_iter_next (buffer)))
2234 XOVERLAY (node->data)->buffer = other;
2235 buffer_overlay_iter_finish (buffer);
2236 }
2237 if (other->overlays)
2238 {
2239 buffer_overlay_iter_start (other, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING);
2240 while ((node = buffer_overlay_iter_next (other)))
2241 XOVERLAY (node->data)->buffer = buffer;
2242 buffer_overlay_iter_finish (other);
2243 }
2244 /* Swap the interval trees. */
2245 void *tmp = buffer->overlays;
2246 buffer->overlays = other->overlays;
2247 other->overlays = tmp;
2248}
2249
2257DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, 2250DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2258 1, 1, 0, 2251 1, 1, 0,
2259 doc: /* Swap the text between current buffer and BUFFER. 2252 doc: /* Swap the text between current buffer and BUFFER.
@@ -2324,9 +2317,6 @@ results, see Info node `(elisp)Swapping Text'. */)
2324 swapfield (bidi_paragraph_cache, struct region_cache *); 2317 swapfield (bidi_paragraph_cache, struct region_cache *);
2325 current_buffer->prevent_redisplay_optimizations_p = 1; 2318 current_buffer->prevent_redisplay_optimizations_p = 1;
2326 other_buffer->prevent_redisplay_optimizations_p = 1; 2319 other_buffer->prevent_redisplay_optimizations_p = 1;
2327 swapfield (overlays_before, struct Lisp_Overlay *);
2328 swapfield (overlays_after, struct Lisp_Overlay *);
2329 swapfield (overlay_center, ptrdiff_t);
2330 swapfield_ (undo_list, Lisp_Object); 2320 swapfield_ (undo_list, Lisp_Object);
2331 swapfield_ (mark, Lisp_Object); 2321 swapfield_ (mark, Lisp_Object);
2332 swapfield_ (enable_multibyte_characters, Lisp_Object); 2322 swapfield_ (enable_multibyte_characters, Lisp_Object);
@@ -2349,6 +2339,7 @@ results, see Info node `(elisp)Swapping Text'. */)
2349 current_buffer->text->end_unchanged = current_buffer->text->gpt; 2339 current_buffer->text->end_unchanged = current_buffer->text->gpt;
2350 other_buffer->text->beg_unchanged = other_buffer->text->gpt; 2340 other_buffer->text->beg_unchanged = other_buffer->text->gpt;
2351 other_buffer->text->end_unchanged = other_buffer->text->gpt; 2341 other_buffer->text->end_unchanged = other_buffer->text->gpt;
2342 swap_buffer_overlays (current_buffer, other_buffer);
2352 { 2343 {
2353 struct Lisp_Marker *m; 2344 struct Lisp_Marker *m;
2354 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 2345 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
@@ -2763,285 +2754,160 @@ swap_out_buffer_local_variables (struct buffer *b)
2763 } 2754 }
2764 } 2755 }
2765} 2756}
2757
2766 2758
2767/* Find all the overlays in the current buffer that contain position POS. 2759/* Find all the overlays in the current buffer that overlap the range
2760 [BEG, END).
2761
2762 If EMPTY is true, include empty overlays in that range and also at
2763 END, provided END denotes the position at the end of the buffer.
2764
2768 Return the number found, and store them in a vector in *VEC_PTR. 2765 Return the number found, and store them in a vector in *VEC_PTR.
2769 Store in *LEN_PTR the size allocated for the vector. 2766 Store in *LEN_PTR the size allocated for the vector.
2770 Store in *NEXT_PTR the next position after POS where an overlay starts, 2767 Store in *NEXT_PTR the next position after POS where an overlay starts,
2771 or ZV if there are no more overlays between POS and ZV. 2768 or ZV if there are no more overlays.
2772 Store in *PREV_PTR the previous position before POS where an overlay ends, 2769 NEXT_PTR may be 0, meaning don't store that info.
2773 or where an overlay starts which ends at or after POS;
2774 or BEGV if there are no such overlays from BEGV to POS.
2775 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2776 2770
2777 *VEC_PTR and *LEN_PTR should contain a valid vector and size 2771 *VEC_PTR and *LEN_PTR should contain a valid vector and size
2778 when this function is called. 2772 when this function is called.
2779 2773
2780 If EXTEND, make the vector bigger if necessary. 2774 If EXTEND, make the vector bigger if necessary. If not, never
2781 If not, never extend the vector, 2775 extend the vector, and store only as many overlays as will fit.
2782 and store only as many overlays as will fit.
2783 But still return the total number of overlays. 2776 But still return the total number of overlays.
2784 2777*/
2785 If CHANGE_REQ, any position written into *PREV_PTR or
2786 *NEXT_PTR is guaranteed to be not equal to POS, unless it is the
2787 default (BEGV or ZV). */
2788 2778
2789ptrdiff_t 2779ptrdiff_t
2790overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr, 2780overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
2791 ptrdiff_t *len_ptr, 2781 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, bool empty,
2792 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req) 2782 ptrdiff_t *next_ptr)
2793{ 2783{
2794 Lisp_Object overlay, start, end;
2795 struct Lisp_Overlay *tail;
2796 ptrdiff_t idx = 0; 2784 ptrdiff_t idx = 0;
2797 ptrdiff_t len = *len_ptr; 2785 ptrdiff_t len = *len_ptr;
2798 Lisp_Object *vec = *vec_ptr;
2799 ptrdiff_t next = ZV; 2786 ptrdiff_t next = ZV;
2800 ptrdiff_t prev = BEGV; 2787 Lisp_Object *vec = *vec_ptr;
2801 bool inhibit_storing = 0;
2802
2803 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
2804 {
2805 ptrdiff_t startpos, endpos;
2806 2788
2807 XSETMISC (overlay, tail); 2789 struct interval_node *node;
2808 2790
2809 start = OVERLAY_START (overlay); 2791 if (! current_buffer->overlays)
2810 end = OVERLAY_END (overlay); 2792 return idx;
2811 endpos = OVERLAY_POSITION (end);
2812 if (endpos < pos)
2813 {
2814 if (prev < endpos)
2815 prev = endpos;
2816 break;
2817 }
2818 startpos = OVERLAY_POSITION (start);
2819 /* This one ends at or after POS
2820 so its start counts for PREV_PTR if it's before POS. */
2821 if (prev < startpos && startpos < pos)
2822 prev = startpos;
2823 if (endpos == pos)
2824 continue;
2825 if (startpos <= pos)
2826 {
2827 if (idx == len)
2828 {
2829 /* The supplied vector is full.
2830 Either make it bigger, or don't store any more in it. */
2831 if (extend)
2832 {
2833 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2834 sizeof *vec);
2835 *vec_ptr = vec;
2836 len = *len_ptr;
2837 }
2838 else
2839 inhibit_storing = 1;
2840 }
2841 2793
2842 if (!inhibit_storing) 2794 buffer_overlay_iter_start (current_buffer, beg,
2843 vec[idx] = overlay; 2795 /* Find empty OV at Z ? */
2844 /* Keep counting overlays even if we can't return them all. */ 2796 (end >= Z && empty) ? Z + 1 : ZV,
2845 idx++; 2797 ITREE_ASCENDING);
2846 }
2847 else if (startpos < next)
2848 next = startpos;
2849 }
2850 2798
2851 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 2799 while ((node = buffer_overlay_iter_next (current_buffer)))
2852 { 2800 {
2853 ptrdiff_t startpos, endpos; 2801 if (node->begin > end)
2854 2802 {
2855 XSETMISC (overlay, tail); 2803 next = min (next, node->begin);
2856 2804 break;
2857 start = OVERLAY_START (overlay); 2805 }
2858 end = OVERLAY_END (overlay); 2806 else if (node->begin == end)
2859 startpos = OVERLAY_POSITION (start); 2807 {
2860 if (pos < startpos) 2808 next = node->begin;
2861 { 2809 if ((! empty || end < Z) && beg < end)
2862 if (startpos < next) 2810 break;
2863 next = startpos; 2811 }
2864 break;
2865 }
2866 endpos = OVERLAY_POSITION (end);
2867 if (pos < endpos)
2868 {
2869 if (idx == len)
2870 {
2871 if (extend)
2872 {
2873 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2874 sizeof *vec);
2875 *vec_ptr = vec;
2876 len = *len_ptr;
2877 }
2878 else
2879 inhibit_storing = 1;
2880 }
2881 2812
2882 if (!inhibit_storing) 2813 if (! empty && node->begin == node->end)
2883 vec[idx] = overlay; 2814 continue;
2884 idx++;
2885 2815
2886 if (startpos < pos && startpos > prev) 2816 if (extend && idx == len)
2887 prev = startpos; 2817 {
2888 } 2818 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2889 else if (endpos < pos && endpos > prev) 2819 sizeof *vec);
2890 prev = endpos; 2820 *vec_ptr = vec;
2891 else if (endpos == pos && startpos > prev 2821 len = *len_ptr;
2892 && (!change_req || startpos < pos)) 2822 }
2893 prev = startpos; 2823 if (idx < len)
2824 vec[idx] = node->data;
2825 /* Keep counting overlays even if we can't return them all. */
2826 idx++;
2894 } 2827 }
2895 2828 buffer_overlay_iter_finish (current_buffer);
2896 if (next_ptr) 2829 if (next_ptr)
2897 *next_ptr = next; 2830 *next_ptr = next ? next : ZV;
2898 if (prev_ptr) 2831
2899 *prev_ptr = prev;
2900 return idx; 2832 return idx;
2901} 2833}
2902
2903/* Find all the overlays in the current buffer that overlap the range
2904 BEG-END, or are empty at BEG, or are empty at END provided END
2905 denotes the position at the end of the current buffer.
2906 2834
2907 Return the number found, and store them in a vector in *VEC_PTR. 2835/* Find all non-empty overlays in the current buffer that contain
2908 Store in *LEN_PTR the size allocated for the vector. 2836 position POS.
2909 Store in *NEXT_PTR the next position after POS where an overlay starts,
2910 or ZV if there are no more overlays.
2911 Store in *PREV_PTR the previous position before POS where an overlay ends,
2912 or BEGV if there are no previous overlays.
2913 NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
2914 2837
2915 *VEC_PTR and *LEN_PTR should contain a valid vector and size 2838 See overlays_in for the meaning of the arguments.
2916 when this function is called. 2839 */
2917 2840
2918 If EXTEND, make the vector bigger if necessary. 2841ptrdiff_t
2919 If not, never extend the vector, 2842overlays_at (ptrdiff_t pos, bool extend,
2920 and store only as many overlays as will fit. 2843 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
2921 But still return the total number of overlays. */ 2844 ptrdiff_t *next_ptr)
2845{
2846 return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr, false, next_ptr);
2847}
2922 2848
2923static ptrdiff_t 2849ptrdiff_t
2924overlays_in (EMACS_INT beg, EMACS_INT end, bool extend, 2850next_overlay_change (ptrdiff_t pos)
2925 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
2926 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
2927{ 2851{
2928 Lisp_Object overlay, ostart, oend;
2929 struct Lisp_Overlay *tail;
2930 ptrdiff_t idx = 0;
2931 ptrdiff_t len = *len_ptr;
2932 Lisp_Object *vec = *vec_ptr;
2933 ptrdiff_t next = ZV; 2852 ptrdiff_t next = ZV;
2934 ptrdiff_t prev = BEGV; 2853 struct interval_node *node;
2935 bool inhibit_storing = 0;
2936 bool end_is_Z = end == Z;
2937 2854
2938 for (tail = current_buffer->overlays_before; tail; tail = tail->next) 2855 if (! current_buffer->overlays)
2939 { 2856 return next;
2940 ptrdiff_t startpos, endpos;
2941 2857
2942 XSETMISC (overlay, tail); 2858 buffer_overlay_iter_start (current_buffer, pos, ZV, ITREE_ASCENDING);
2943 2859 while ((node = buffer_overlay_iter_next (current_buffer)))
2944 ostart = OVERLAY_START (overlay); 2860 {
2945 oend = OVERLAY_END (overlay); 2861 if (node->begin > pos)
2946 endpos = OVERLAY_POSITION (oend); 2862 {
2947 if (endpos < beg) 2863 /* If we reach this branch, node->begin must be the least upper bound
2948 { 2864 of pos, because the search is limited to [pos,next) . */
2949 if (prev < endpos) 2865 eassert (node->begin < next);
2950 prev = endpos; 2866 next = node->begin;
2951 break; 2867 break;
2952 } 2868 }
2953 startpos = OVERLAY_POSITION (ostart); 2869 else if (node->begin < node->end && node->end < next)
2954 /* Count an interval if it overlaps the range, is empty at the 2870 {
2955 start of the range, or is empty at END provided END denotes the 2871 next = node->end;
2956 end of the buffer. */ 2872 buffer_overlay_iter_narrow (current_buffer, pos, next);
2957 if ((beg < endpos && startpos < end) 2873 }
2958 || (startpos == endpos
2959 && (beg == endpos || (end_is_Z && endpos == end))))
2960 {
2961 if (idx == len)
2962 {
2963 /* The supplied vector is full.
2964 Either make it bigger, or don't store any more in it. */
2965 if (extend)
2966 {
2967 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
2968 sizeof *vec);
2969 *vec_ptr = vec;
2970 len = *len_ptr;
2971 }
2972 else
2973 inhibit_storing = 1;
2974 }
2975
2976 if (!inhibit_storing)
2977 vec[idx] = overlay;
2978 /* Keep counting overlays even if we can't return them all. */
2979 idx++;
2980 }
2981 else if (startpos < next)
2982 next = startpos;
2983 } 2874 }
2875 buffer_overlay_iter_finish (current_buffer);
2984 2876
2985 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 2877 return next;
2986 { 2878}
2987 ptrdiff_t startpos, endpos;
2988 2879
2989 XSETMISC (overlay, tail); 2880ptrdiff_t
2881previous_overlay_change (ptrdiff_t pos)
2882{
2883 struct interval_node *node;
2884 ptrdiff_t prev = BEGV;
2990 2885
2991 ostart = OVERLAY_START (overlay); 2886 if (! current_buffer->overlays)
2992 oend = OVERLAY_END (overlay); 2887 return prev;
2993 startpos = OVERLAY_POSITION (ostart);
2994 if (end < startpos)
2995 {
2996 if (startpos < next)
2997 next = startpos;
2998 break;
2999 }
3000 endpos = OVERLAY_POSITION (oend);
3001 /* Count an interval if it overlaps the range, is empty at the
3002 start of the range, or is empty at END provided END denotes the
3003 end of the buffer. */
3004 if ((beg < endpos && startpos < end)
3005 || (startpos == endpos
3006 && (beg == endpos || (end_is_Z && endpos == end))))
3007 {
3008 if (idx == len)
3009 {
3010 if (extend)
3011 {
3012 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
3013 sizeof *vec);
3014 *vec_ptr = vec;
3015 len = *len_ptr;
3016 }
3017 else
3018 inhibit_storing = 1;
3019 }
3020 2888
3021 if (!inhibit_storing) 2889 buffer_overlay_iter_start (current_buffer, BEGV, pos, ITREE_DESCENDING);
3022 vec[idx] = overlay; 2890 while ((node = buffer_overlay_iter_next (current_buffer)))
3023 idx++; 2891 {
3024 } 2892 if (node->end < pos)
3025 else if (endpos < beg && endpos > prev) 2893 prev = node->end;
3026 prev = endpos; 2894 else
2895 prev = max (prev, node->begin);
2896 buffer_overlay_iter_narrow (current_buffer, prev, pos);
3027 } 2897 }
2898 buffer_overlay_iter_finish (current_buffer);
3028 2899
3029 if (next_ptr) 2900 return prev;
3030 *next_ptr = next;
3031 if (prev_ptr)
3032 *prev_ptr = prev;
3033 return idx;
3034} 2901}
3035 2902
3036
3037/* Return true if there exists an overlay with a non-nil 2903/* Return true if there exists an overlay with a non-nil
3038 `mouse-face' property overlapping OVERLAY. */ 2904 `mouse-face' property overlapping OVERLAY. */
3039 2905
3040bool 2906bool
3041mouse_face_overlay_overlaps (Lisp_Object overlay) 2907mouse_face_overlay_overlaps (Lisp_Object overlay)
3042{ 2908{
3043 ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay)); 2909 ptrdiff_t start = OVERLAY_START (overlay);
3044 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay)); 2910 ptrdiff_t end = OVERLAY_END (overlay);
3045 ptrdiff_t n, i, size; 2911 ptrdiff_t n, i, size;
3046 Lisp_Object *v, tem; 2912 Lisp_Object *v, tem;
3047 Lisp_Object vbuf[10]; 2913 Lisp_Object vbuf[10];
@@ -3049,11 +2915,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
3049 2915
3050 size = ARRAYELTS (vbuf); 2916 size = ARRAYELTS (vbuf);
3051 v = vbuf; 2917 v = vbuf;
3052 n = overlays_in (start, end, 0, &v, &size, NULL, NULL); 2918 n = overlays_in (start, end, 0, &v, &size, true, NULL);
3053 if (n > size) 2919 if (n > size)
3054 { 2920 {
3055 SAFE_NALLOCA (v, 1, n); 2921 SAFE_NALLOCA (v, 1, n);
3056 overlays_in (start, end, 0, &v, &n, NULL, NULL); 2922 overlays_in (start, end, 0, &v, &n, true, NULL);
3057 } 2923 }
3058 2924
3059 for (i = 0; i < n; ++i) 2925 for (i = 0; i < n; ++i)
@@ -3095,52 +2961,34 @@ disable_line_numbers_overlay_at_eob (void)
3095} 2961}
3096 2962
3097 2963
3098/* Fast function to just test if we're at an overlay boundary. */ 2964/* Fast function to just test if we're at an overlay boundary.
2965
2966 Returns true if some overlay starts or ends (or both) at POS,
2967*/
3099bool 2968bool
3100overlay_touches_p (ptrdiff_t pos) 2969overlay_touches_p (ptrdiff_t pos)
3101{ 2970{
3102 Lisp_Object overlay; 2971 struct interval_node *node;
3103 struct Lisp_Overlay *tail; 2972 bool result = false;
3104
3105 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
3106 {
3107 ptrdiff_t endpos;
3108 2973
3109 XSETMISC (overlay ,tail); 2974 if (! current_buffer->overlays)
3110 eassert (OVERLAYP (overlay)); 2975 return false;
3111 2976
3112 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 2977 /* We need to find overlays ending in pos, as well as empty ones at
3113 if (endpos < pos) 2978 pos. */
3114 break; 2979 buffer_overlay_iter_start (current_buffer,
3115 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos) 2980 pos - 1, pos + 1, ITREE_DESCENDING);
3116 return 1;
3117 }
3118 2981
3119 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 2982 while (! result && (node = buffer_overlay_iter_next (current_buffer)))
3120 { 2983 result = (node->begin == pos || node->end == pos);
3121 ptrdiff_t startpos;
3122 2984
3123 XSETMISC (overlay, tail); 2985 buffer_overlay_iter_finish (current_buffer);
3124 eassert (OVERLAYP (overlay));
3125 2986
3126 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 2987 return result;
3127 if (pos < startpos)
3128 break;
3129 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
3130 return 1;
3131 }
3132 return 0;
3133} 2988}
3134
3135struct sortvec
3136{
3137 Lisp_Object overlay;
3138 ptrdiff_t beg, end;
3139 EMACS_INT priority;
3140 EMACS_INT spriority; /* Secondary priority. */
3141};
3142 2989
3143static int 2990
2991int
3144compare_overlays (const void *v1, const void *v2) 2992compare_overlays (const void *v1, const void *v2)
3145{ 2993{
3146 const struct sortvec *s1 = v1; 2994 const struct sortvec *s1 = v1;
@@ -3169,6 +3017,33 @@ compare_overlays (const void *v1, const void *v2)
3169 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1; 3017 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3170} 3018}
3171 3019
3020void
3021make_sortvec_item (struct sortvec *item, Lisp_Object overlay)
3022{
3023 Lisp_Object tem;
3024 /* This overlay is good and counts: put it into sortvec. */
3025 item->overlay = overlay;
3026 item->beg = OVERLAY_START (overlay);
3027 item->end = OVERLAY_END (overlay);
3028 tem = Foverlay_get (overlay, Qpriority);
3029 if (NILP (tem))
3030 {
3031 item->priority = 0;
3032 item->spriority = 0;
3033 }
3034 else if (INTEGERP (tem))
3035 {
3036 item->priority = XINT (tem);
3037 item->spriority = 0;
3038 }
3039 else if (CONSP (tem))
3040 {
3041 Lisp_Object car = XCAR (tem);
3042 Lisp_Object cdr = XCDR (tem);
3043 item->priority = INTEGERP (car) ? XINT (car) : 0;
3044 item->spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
3045 }
3046}
3172/* Sort an array of overlays by priority. The array is modified in place. 3047/* Sort an array of overlays by priority. The array is modified in place.
3173 The return value is the new size; this may be smaller than the original 3048 The return value is the new size; this may be smaller than the original
3174 size if some of the overlays were invalid or were window-specific. */ 3049 size if some of the overlays were invalid or were window-specific. */
@@ -3185,47 +3060,18 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
3185 3060
3186 for (i = 0, j = 0; i < noverlays; i++) 3061 for (i = 0, j = 0; i < noverlays; i++)
3187 { 3062 {
3188 Lisp_Object tem;
3189 Lisp_Object overlay; 3063 Lisp_Object overlay;
3190 3064
3191 overlay = overlay_vec[i]; 3065 overlay = overlay_vec[i];
3192 if (OVERLAYP (overlay) 3066 if (OVERLAYP (overlay)
3193 && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 3067 && OVERLAY_START (overlay) > 0
3194 && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) 3068 && OVERLAY_END (overlay) > 0)
3195 { 3069 {
3196 /* If we're interested in a specific window, then ignore 3070 /* If we're interested in a specific window, then ignore
3197 overlays that are limited to some other window. */ 3071 overlays that are limited to some other window. */
3198 if (w) 3072 if (w && ! overlay_matches_window (w, overlay))
3199 { 3073 continue;
3200 Lisp_Object window; 3074 make_sortvec_item (sortvec + j, overlay);
3201
3202 window = Foverlay_get (overlay, Qwindow);
3203 if (WINDOWP (window) && XWINDOW (window) != w)
3204 continue;
3205 }
3206
3207 /* This overlay is good and counts: put it into sortvec. */
3208 sortvec[j].overlay = overlay;
3209 sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
3210 sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
3211 tem = Foverlay_get (overlay, Qpriority);
3212 if (NILP (tem))
3213 {
3214 sortvec[j].priority = 0;
3215 sortvec[j].spriority = 0;
3216 }
3217 else if (INTEGERP (tem))
3218 {
3219 sortvec[j].priority = XINT (tem);
3220 sortvec[j].spriority = 0;
3221 }
3222 else if (CONSP (tem))
3223 {
3224 Lisp_Object car = XCAR (tem);
3225 Lisp_Object cdr = XCDR (tem);
3226 sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0;
3227 sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
3228 }
3229 j++; 3075 j++;
3230 } 3076 }
3231 } 3077 }
@@ -3340,68 +3186,44 @@ ptrdiff_t
3340overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) 3186overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3341{ 3187{
3342 Lisp_Object overlay, window, str; 3188 Lisp_Object overlay, window, str;
3343 struct Lisp_Overlay *ov; 3189 ptrdiff_t obegin, oend;
3344 ptrdiff_t startpos, endpos;
3345 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 3190 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
3191 struct interval_node *node;
3346 3192
3347 overlay_heads.used = overlay_heads.bytes = 0; 3193 overlay_heads.used = overlay_heads.bytes = 0;
3348 overlay_tails.used = overlay_tails.bytes = 0; 3194 overlay_tails.used = overlay_tails.bytes = 0;
3349 for (ov = current_buffer->overlays_before; ov; ov = ov->next) 3195
3196 buffer_overlay_iter_start (current_buffer,
3197 pos - 1, pos + 1, ITREE_DESCENDING);
3198 while ((node = buffer_overlay_iter_next (current_buffer)))
3350 { 3199 {
3351 XSETMISC (overlay, ov); 3200 overlay = node->data;
3352 eassert (OVERLAYP (overlay)); 3201 eassert (OVERLAYP (overlay));
3353 3202
3354 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3203 obegin = node->begin;
3355 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3204 oend = node->end;
3356 if (endpos < pos) 3205
3357 break; 3206 if (oend != pos && obegin != pos)
3358 if (endpos != pos && startpos != pos)
3359 continue; 3207 continue;
3360 window = Foverlay_get (overlay, Qwindow); 3208 window = Foverlay_get (overlay, Qwindow);
3361 if (WINDOWP (window) && XWINDOW (window) != w) 3209 if (WINDOWP (window) && XWINDOW (window) != w)
3362 continue; 3210 continue;
3363 if (startpos == pos 3211 if (obegin == pos
3364 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3212 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3365 record_overlay_string (&overlay_heads, str, 3213 record_overlay_string (&overlay_heads, str,
3366 (startpos == endpos 3214 (obegin == oend
3367 ? Foverlay_get (overlay, Qafter_string) 3215 ? Foverlay_get (overlay, Qafter_string)
3368 : Qnil), 3216 : Qnil),
3369 Foverlay_get (overlay, Qpriority), 3217 Foverlay_get (overlay, Qpriority),
3370 endpos - startpos); 3218 oend - obegin);
3371 else if (endpos == pos 3219 else if (oend == pos
3372 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))) 3220 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3373 record_overlay_string (&overlay_tails, str, Qnil, 3221 record_overlay_string (&overlay_tails, str, Qnil,
3374 Foverlay_get (overlay, Qpriority), 3222 Foverlay_get (overlay, Qpriority),
3375 endpos - startpos); 3223 oend - obegin);
3376 } 3224 }
3377 for (ov = current_buffer->overlays_after; ov; ov = ov->next) 3225 buffer_overlay_iter_finish (current_buffer);
3378 {
3379 XSETMISC (overlay, ov);
3380 eassert (OVERLAYP (overlay));
3381 3226
3382 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3383 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3384 if (startpos > pos)
3385 break;
3386 if (endpos != pos && startpos != pos)
3387 continue;
3388 window = Foverlay_get (overlay, Qwindow);
3389 if (WINDOWP (window) && XWINDOW (window) != w)
3390 continue;
3391 if (startpos == pos
3392 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3393 record_overlay_string (&overlay_heads, str,
3394 (startpos == endpos
3395 ? Foverlay_get (overlay, Qafter_string)
3396 : Qnil),
3397 Foverlay_get (overlay, Qpriority),
3398 endpos - startpos);
3399 else if (endpos == pos
3400 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
3401 record_overlay_string (&overlay_tails, str, Qnil,
3402 Foverlay_get (overlay, Qpriority),
3403 endpos - startpos);
3404 }
3405 if (overlay_tails.used > 1) 3227 if (overlay_tails.used > 1)
3406 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr), 3228 qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
3407 cmp_for_strings); 3229 cmp_for_strings);
@@ -3456,385 +3278,26 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3456 } 3278 }
3457 return 0; 3279 return 0;
3458} 3280}
3459
3460/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
3461
3462void
3463recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
3464{
3465 Lisp_Object overlay, beg, end;
3466 struct Lisp_Overlay *prev, *tail, *next;
3467
3468 /* See if anything in overlays_before should move to overlays_after. */
3469
3470 /* We don't strictly need prev in this loop; it should always be nil.
3471 But we use it for symmetry and in case that should cease to be true
3472 with some future change. */
3473 prev = NULL;
3474 for (tail = buf->overlays_before; tail; prev = tail, tail = next)
3475 {
3476 next = tail->next;
3477 XSETMISC (overlay, tail);
3478 eassert (OVERLAYP (overlay));
3479
3480 beg = OVERLAY_START (overlay);
3481 end = OVERLAY_END (overlay);
3482
3483 if (OVERLAY_POSITION (end) > pos)
3484 {
3485 /* OVERLAY needs to be moved. */
3486 ptrdiff_t where = OVERLAY_POSITION (beg);
3487 struct Lisp_Overlay *other, *other_prev;
3488
3489 /* Splice the cons cell TAIL out of overlays_before. */
3490 if (prev)
3491 prev->next = next;
3492 else
3493 set_buffer_overlays_before (buf, next);
3494
3495 /* Search thru overlays_after for where to put it. */
3496 other_prev = NULL;
3497 for (other = buf->overlays_after; other;
3498 other_prev = other, other = other->next)
3499 {
3500 Lisp_Object otherbeg, otheroverlay;
3501
3502 XSETMISC (otheroverlay, other);
3503 eassert (OVERLAYP (otheroverlay));
3504
3505 otherbeg = OVERLAY_START (otheroverlay);
3506 if (OVERLAY_POSITION (otherbeg) >= where)
3507 break;
3508 }
3509
3510 /* Add TAIL to overlays_after before OTHER. */
3511 tail->next = other;
3512 if (other_prev)
3513 other_prev->next = tail;
3514 else
3515 set_buffer_overlays_after (buf, tail);
3516 tail = prev;
3517 }
3518 else
3519 /* We've reached the things that should stay in overlays_before.
3520 All the rest of overlays_before must end even earlier,
3521 so stop now. */
3522 break;
3523 }
3524
3525 /* See if anything in overlays_after should be in overlays_before. */
3526 prev = NULL;
3527 for (tail = buf->overlays_after; tail; prev = tail, tail = next)
3528 {
3529 next = tail->next;
3530 XSETMISC (overlay, tail);
3531 eassert (OVERLAYP (overlay));
3532
3533 beg = OVERLAY_START (overlay);
3534 end = OVERLAY_END (overlay);
3535
3536 /* Stop looking, when we know that nothing further
3537 can possibly end before POS. */
3538 if (OVERLAY_POSITION (beg) > pos)
3539 break;
3540
3541 if (OVERLAY_POSITION (end) <= pos)
3542 {
3543 /* OVERLAY needs to be moved. */
3544 ptrdiff_t where = OVERLAY_POSITION (end);
3545 struct Lisp_Overlay *other, *other_prev;
3546
3547 /* Splice the cons cell TAIL out of overlays_after. */
3548 if (prev)
3549 prev->next = next;
3550 else
3551 set_buffer_overlays_after (buf, next);
3552
3553 /* Search thru overlays_before for where to put it. */
3554 other_prev = NULL;
3555 for (other = buf->overlays_before; other;
3556 other_prev = other, other = other->next)
3557 {
3558 Lisp_Object otherend, otheroverlay;
3559
3560 XSETMISC (otheroverlay, other);
3561 eassert (OVERLAYP (otheroverlay));
3562
3563 otherend = OVERLAY_END (otheroverlay);
3564 if (OVERLAY_POSITION (otherend) <= where)
3565 break;
3566 }
3567
3568 /* Add TAIL to overlays_before before OTHER. */
3569 tail->next = other;
3570 if (other_prev)
3571 other_prev->next = tail;
3572 else
3573 set_buffer_overlays_before (buf, tail);
3574 tail = prev;
3575 }
3576 }
3577
3578 buf->overlay_center = pos;
3579}
3580 3281
3282
3581void 3283void
3582adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length) 3284adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
3583{ 3285{
3584 /* After an insertion, the lists are still sorted properly, 3286 /* After an insertion, the lists are still sorted properly,
3585 but we may need to update the value of the overlay center. */ 3287 but we may need to update the value of the overlay center. */
3586 if (current_buffer->overlay_center >= pos) 3288 if (! current_buffer->overlays)
3587 current_buffer->overlay_center += length; 3289 return;
3290 interval_tree_insert_gap (current_buffer->overlays, pos, length);
3588} 3291}
3589 3292
3590void 3293void
3591adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length) 3294adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
3592{ 3295{
3593 if (current_buffer->overlay_center < pos) 3296 if (! current_buffer->overlays)
3594 /* The deletion was to our right. No change needed; the before- and
3595 after-lists are still consistent. */
3596 ;
3597 else if (current_buffer->overlay_center - pos > length)
3598 /* The deletion was to our left. We need to adjust the center value
3599 to account for the change in position, but the lists are consistent
3600 given the new value. */
3601 current_buffer->overlay_center -= length;
3602 else
3603 /* We're right in the middle. There might be things on the after-list
3604 that now belong on the before-list. Recentering will move them,
3605 and also update the center point. */
3606 recenter_overlay_lists (current_buffer, pos);
3607}
3608
3609/* Fix up overlays that were garbled as a result of permuting markers
3610 in the range START through END. Any overlay with at least one
3611 endpoint in this range will need to be unlinked from the overlay
3612 list and reinserted in its proper place.
3613 Such an overlay might even have negative size at this point.
3614 If so, we'll make the overlay empty. */
3615void
3616fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3617{
3618 Lisp_Object overlay;
3619 struct Lisp_Overlay *before_list;
3620 struct Lisp_Overlay *after_list;
3621 /* These are either nil, indicating that before_list or after_list
3622 should be assigned, or the cons cell the cdr of which should be
3623 assigned. */
3624 struct Lisp_Overlay *beforep = NULL, *afterp = NULL;
3625 /* 'Parent', likewise, indicates a cons cell or
3626 current_buffer->overlays_before or overlays_after, depending
3627 which loop we're in. */
3628 struct Lisp_Overlay *tail, *parent;
3629 ptrdiff_t startpos, endpos;
3630
3631 /* This algorithm shifts links around instead of consing and GCing.
3632 The loop invariant is that before_list (resp. after_list) is a
3633 well-formed list except that its last element, the CDR of beforep
3634 (resp. afterp) if beforep (afterp) isn't nil or before_list
3635 (after_list) if it is, is still uninitialized. So it's not a bug
3636 that before_list isn't initialized, although it may look
3637 strange. */
3638 for (parent = NULL, tail = current_buffer->overlays_before; tail;)
3639 {
3640 XSETMISC (overlay, tail);
3641
3642 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3643 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3644
3645 /* If the overlay is backwards, make it empty. */
3646 if (endpos < startpos)
3647 {
3648 startpos = endpos;
3649 Fset_marker (OVERLAY_START (overlay), make_number (startpos),
3650 Qnil);
3651 }
3652
3653 if (endpos < start)
3654 break;
3655
3656 if (endpos < end
3657 || (startpos >= start && startpos < end))
3658 {
3659 /* Add it to the end of the wrong list. Later on,
3660 recenter_overlay_lists will move it to the right place. */
3661 if (endpos < current_buffer->overlay_center)
3662 {
3663 if (!afterp)
3664 after_list = tail;
3665 else
3666 afterp->next = tail;
3667 afterp = tail;
3668 }
3669 else
3670 {
3671 if (!beforep)
3672 before_list = tail;
3673 else
3674 beforep->next = tail;
3675 beforep = tail;
3676 }
3677 if (!parent)
3678 set_buffer_overlays_before (current_buffer, tail->next);
3679 else
3680 parent->next = tail->next;
3681 tail = tail->next;
3682 }
3683 else
3684 parent = tail, tail = parent->next;
3685 }
3686 for (parent = NULL, tail = current_buffer->overlays_after; tail;)
3687 {
3688 XSETMISC (overlay, tail);
3689
3690 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3691 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3692
3693 /* If the overlay is backwards, make it empty. */
3694 if (endpos < startpos)
3695 {
3696 startpos = endpos;
3697 Fset_marker (OVERLAY_START (overlay), make_number (startpos),
3698 Qnil);
3699 }
3700
3701 if (startpos >= end)
3702 break;
3703
3704 if (startpos >= start
3705 || (endpos >= start && endpos < end))
3706 {
3707 if (endpos < current_buffer->overlay_center)
3708 {
3709 if (!afterp)
3710 after_list = tail;
3711 else
3712 afterp->next = tail;
3713 afterp = tail;
3714 }
3715 else
3716 {
3717 if (!beforep)
3718 before_list = tail;
3719 else
3720 beforep->next = tail;
3721 beforep = tail;
3722 }
3723 if (!parent)
3724 set_buffer_overlays_after (current_buffer, tail->next);
3725 else
3726 parent->next = tail->next;
3727 tail = tail->next;
3728 }
3729 else
3730 parent = tail, tail = parent->next;
3731 }
3732
3733 /* Splice the constructed (wrong) lists into the buffer's lists,
3734 and let the recenter function make it sane again. */
3735 if (beforep)
3736 {
3737 beforep->next = current_buffer->overlays_before;
3738 set_buffer_overlays_before (current_buffer, before_list);
3739 }
3740
3741 if (afterp)
3742 {
3743 afterp->next = current_buffer->overlays_after;
3744 set_buffer_overlays_after (current_buffer, after_list);
3745 }
3746 recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
3747}
3748
3749/* We have two types of overlay: the one whose ending marker is
3750 after-insertion-marker (this is the usual case) and the one whose
3751 ending marker is before-insertion-marker. When `overlays_before'
3752 contains overlays of the latter type and the former type in this
3753 order and both overlays end at inserting position, inserting a text
3754 increases only the ending marker of the latter type, which results
3755 in incorrect ordering of `overlays_before'.
3756
3757 This function fixes ordering of overlays in the slot
3758 `overlays_before' of the buffer *BP. Before the insertion, `point'
3759 was at PREV, and now is at POS. */
3760
3761void
3762fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
3763{
3764 /* If parent is nil, replace overlays_before; otherwise, parent->next. */
3765 struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
3766 Lisp_Object tem;
3767 ptrdiff_t end UNINIT;
3768
3769 /* After the insertion, the several overlays may be in incorrect
3770 order. The possibility is that, in the list `overlays_before',
3771 an overlay which ends at POS appears after an overlay which ends
3772 at PREV. Since POS is greater than PREV, we must fix the
3773 ordering of these overlays, by moving overlays ends at POS before
3774 the overlays ends at PREV. */
3775
3776 /* At first, find a place where disordered overlays should be linked
3777 in. It is where an overlay which end before POS exists. (i.e. an
3778 overlay whose ending marker is after-insertion-marker if disorder
3779 exists). */
3780 while (tail
3781 && (XSETMISC (tem, tail),
3782 (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
3783 {
3784 parent = tail;
3785 tail = tail->next;
3786 }
3787
3788 /* If we don't find such an overlay,
3789 or the found one ends before PREV,
3790 or the found one is the last one in the list,
3791 we don't have to fix anything. */
3792 if (!tail || end < prev || !tail->next)
3793 return; 3297 return;
3794 3298 interval_tree_delete_gap (current_buffer->overlays, pos, length);
3795 right_pair = parent;
3796 parent = tail;
3797 tail = tail->next;
3798
3799 /* Now, end position of overlays in the list TAIL should be before
3800 or equal to PREV. In the loop, an overlay which ends at POS is
3801 moved ahead to the place indicated by the CDR of RIGHT_PAIR. If
3802 we found an overlay which ends before PREV, the remaining
3803 overlays are in correct order. */
3804 while (tail)
3805 {
3806 XSETMISC (tem, tail);
3807 end = OVERLAY_POSITION (OVERLAY_END (tem));
3808
3809 if (end == pos)
3810 { /* This overlay is disordered. */
3811 struct Lisp_Overlay *found = tail;
3812
3813 /* Unlink the found overlay. */
3814 tail = found->next;
3815 parent->next = tail;
3816 /* Move an overlay at RIGHT_PLACE to the next of the found one,
3817 and link it into the right place. */
3818 if (!right_pair)
3819 {
3820 found->next = bp->overlays_before;
3821 set_buffer_overlays_before (bp, found);
3822 }
3823 else
3824 {
3825 found->next = right_pair->next;
3826 right_pair->next = found;
3827 }
3828 }
3829 else if (end == prev)
3830 {
3831 parent = tail;
3832 tail = tail->next;
3833 }
3834 else /* No more disordered overlay. */
3835 break;
3836 }
3837} 3299}
3300
3838 3301
3839DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0, 3302DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
3840 doc: /* Return t if OBJECT is an overlay. */) 3303 doc: /* Return t if OBJECT is an overlay. */)
@@ -3853,10 +3316,11 @@ for the front of the overlay advance when text is inserted there
3853The fifth arg REAR-ADVANCE, if non-nil, makes the marker 3316The fifth arg REAR-ADVANCE, if non-nil, makes the marker
3854for the rear of the overlay advance when text is inserted there 3317for the rear of the overlay advance when text is inserted there
3855\(which means the text *is* included in the overlay). */) 3318\(which means the text *is* included in the overlay). */)
3856 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, 3319 (Lisp_Object begin, Lisp_Object end, Lisp_Object buffer,
3857 Lisp_Object front_advance, Lisp_Object rear_advance) 3320 Lisp_Object front_advance, Lisp_Object rear_advance)
3858{ 3321{
3859 Lisp_Object overlay; 3322 Lisp_Object ov;
3323 ptrdiff_t obegin, oend;
3860 struct buffer *b; 3324 struct buffer *b;
3861 3325
3862 if (NILP (buffer)) 3326 if (NILP (buffer))
@@ -3864,53 +3328,35 @@ for the rear of the overlay advance when text is inserted there
3864 else 3328 else
3865 CHECK_BUFFER (buffer); 3329 CHECK_BUFFER (buffer);
3866 3330
3867 if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer)) 3331 b = XBUFFER (buffer);
3868 signal_error ("Marker points into wrong buffer", beg); 3332 if (! BUFFER_LIVE_P (b))
3333 error ("Attempt to create overlay in a dead buffer");
3334
3335 if (MARKERP (begin) && !EQ (Fmarker_buffer (begin), buffer))
3336 signal_error ("Marker points into wrong buffer", begin);
3869 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) 3337 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
3870 signal_error ("Marker points into wrong buffer", end); 3338 signal_error ("Marker points into wrong buffer", end);
3871 3339
3872 CHECK_NUMBER_COERCE_MARKER (beg); 3340 CHECK_NUMBER_COERCE_MARKER (begin);
3873 CHECK_NUMBER_COERCE_MARKER (end); 3341 CHECK_NUMBER_COERCE_MARKER (end);
3874 3342
3875 if (XINT (beg) > XINT (end)) 3343 if (XINT (begin) > XINT (end))
3876 { 3344 {
3877 Lisp_Object temp; 3345 Lisp_Object temp;
3878 temp = beg; beg = end; end = temp; 3346 temp = begin; begin = end; end = temp;
3879 } 3347 }
3880 3348
3881 b = XBUFFER (buffer); 3349 obegin = clip_to_bounds (BEG, XINT (begin), b->text->z);
3882 3350 oend = clip_to_bounds (obegin, XINT (end), b->text->z);
3883 beg = Fset_marker (Fmake_marker (), beg, buffer); 3351 ov = build_overlay (obegin, oend,
3884 end = Fset_marker (Fmake_marker (), end, buffer); 3352 ! NILP (front_advance),
3885 3353 ! NILP (rear_advance), Qnil);
3886 if (!NILP (front_advance)) 3354 add_buffer_overlay (b, XOVERLAY (ov));
3887 XMARKER (beg)->insertion_type = 1;
3888 if (!NILP (rear_advance))
3889 XMARKER (end)->insertion_type = 1;
3890
3891 overlay = build_overlay (beg, end, Qnil);
3892
3893 /* Put the new overlay on the wrong list. */
3894 end = OVERLAY_END (overlay);
3895 if (OVERLAY_POSITION (end) < b->overlay_center)
3896 {
3897 eassert (b->overlays_after || (XOVERLAY (overlay)->next == NULL));
3898 XOVERLAY (overlay)->next = b->overlays_after;
3899 set_buffer_overlays_after (b, XOVERLAY (overlay));
3900 }
3901 else
3902 {
3903 eassert (b->overlays_before || (XOVERLAY (overlay)->next == NULL));
3904 XOVERLAY (overlay)->next = b->overlays_before;
3905 set_buffer_overlays_before (b, XOVERLAY (overlay));
3906 }
3907 /* This puts it in the right list, and in the right order. */
3908 recenter_overlay_lists (b, b->overlay_center);
3909 3355
3910 /* We don't need to redisplay the region covered by the overlay, because 3356 /* We don't need to redisplay the region covered by the overlay, because
3911 the overlay has no properties at the moment. */ 3357 the overlay has no properties at the moment. */
3912 3358
3913 return overlay; 3359 return ov;
3914} 3360}
3915 3361
3916/* Mark a section of BUF as needing redisplay because of overlays changes. */ 3362/* Mark a section of BUF as needing redisplay because of overlays changes. */
@@ -3932,35 +3378,6 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
3932 ++BUF_OVERLAY_MODIFF (buf); 3378 ++BUF_OVERLAY_MODIFF (buf);
3933} 3379}
3934 3380
3935/* Remove OVERLAY from LIST. */
3936
3937static struct Lisp_Overlay *
3938unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay)
3939{
3940 register struct Lisp_Overlay *tail, **prev = &list;
3941
3942 for (tail = list; tail; prev = &tail->next, tail = *prev)
3943 if (tail == overlay)
3944 {
3945 *prev = overlay->next;
3946 overlay->next = NULL;
3947 break;
3948 }
3949 return list;
3950}
3951
3952/* Remove OVERLAY from both overlay lists of B. */
3953
3954static void
3955unchain_both (struct buffer *b, Lisp_Object overlay)
3956{
3957 struct Lisp_Overlay *ov = XOVERLAY (overlay);
3958
3959 set_buffer_overlays_before (b, unchain_overlay (b->overlays_before, ov));
3960 set_buffer_overlays_after (b, unchain_overlay (b->overlays_after, ov));
3961 eassert (XOVERLAY (overlay)->next == NULL);
3962}
3963
3964DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0, 3381DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
3965 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER. 3382 doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
3966If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now. 3383If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
@@ -3976,7 +3393,7 @@ buffer. */)
3976 3393
3977 CHECK_OVERLAY (overlay); 3394 CHECK_OVERLAY (overlay);
3978 if (NILP (buffer)) 3395 if (NILP (buffer))
3979 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3396 buffer = Foverlay_buffer (overlay);
3980 if (NILP (buffer)) 3397 if (NILP (buffer))
3981 XSETBUFFER (buffer, current_buffer); 3398 XSETBUFFER (buffer, current_buffer);
3982 CHECK_BUFFER (buffer); 3399 CHECK_BUFFER (buffer);
@@ -4000,25 +3417,28 @@ buffer. */)
4000 3417
4001 specbind (Qinhibit_quit, Qt); 3418 specbind (Qinhibit_quit, Qt);
4002 3419
4003 obuffer = Fmarker_buffer (OVERLAY_START (overlay)); 3420 obuffer = Foverlay_buffer (overlay);
4004 b = XBUFFER (buffer); 3421 b = XBUFFER (buffer);
4005 3422
4006 if (!NILP (obuffer)) 3423 if (!NILP (obuffer))
4007 { 3424 {
4008 ob = XBUFFER (obuffer); 3425 ob = XBUFFER (obuffer);
4009 3426
4010 o_beg = OVERLAY_POSITION (OVERLAY_START (overlay)); 3427 o_beg = OVERLAY_START (overlay);
4011 o_end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3428 o_end = OVERLAY_END (overlay);
4012
4013 unchain_both (ob, overlay);
4014 } 3429 }
4015 3430
3431 if (! EQ (buffer, obuffer))
3432 {
3433 if (! NILP (obuffer))
3434 remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
3435 add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay));
3436 }
4016 /* Set the overlay boundaries, which may clip them. */ 3437 /* Set the overlay boundaries, which may clip them. */
4017 Fset_marker (OVERLAY_START (overlay), beg, buffer); 3438 set_overlay_region (XOVERLAY (overlay), XINT (beg), XINT (end));
4018 Fset_marker (OVERLAY_END (overlay), end, buffer);
4019 3439
4020 n_beg = marker_position (OVERLAY_START (overlay)); 3440 n_beg = OVERLAY_START (overlay);
4021 n_end = marker_position (OVERLAY_END (overlay)); 3441 n_end = OVERLAY_END (overlay);
4022 3442
4023 /* If the overlay has changed buffers, do a thorough redisplay. */ 3443 /* If the overlay has changed buffers, do a thorough redisplay. */
4024 if (!EQ (buffer, obuffer)) 3444 if (!EQ (buffer, obuffer))
@@ -4046,22 +3466,6 @@ buffer. */)
4046 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate))) 3466 if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
4047 return unbind_to (count, Fdelete_overlay (overlay)); 3467 return unbind_to (count, Fdelete_overlay (overlay));
4048 3468
4049 /* Put the overlay into the new buffer's overlay lists, first on the
4050 wrong list. */
4051 if (n_end < b->overlay_center)
4052 {
4053 XOVERLAY (overlay)->next = b->overlays_after;
4054 set_buffer_overlays_after (b, XOVERLAY (overlay));
4055 }
4056 else
4057 {
4058 XOVERLAY (overlay)->next = b->overlays_before;
4059 set_buffer_overlays_before (b, XOVERLAY (overlay));
4060 }
4061
4062 /* This puts it in the right list, and in the right order. */
4063 recenter_overlay_lists (b, b->overlay_center);
4064
4065 return unbind_to (count, overlay); 3469 return unbind_to (count, overlay);
4066} 3470}
4067 3471
@@ -4069,21 +3473,18 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
4069 doc: /* Delete the overlay OVERLAY from its buffer. */) 3473 doc: /* Delete the overlay OVERLAY from its buffer. */)
4070 (Lisp_Object overlay) 3474 (Lisp_Object overlay)
4071{ 3475{
4072 Lisp_Object buffer;
4073 struct buffer *b; 3476 struct buffer *b;
4074 ptrdiff_t count = SPECPDL_INDEX (); 3477 ptrdiff_t count = SPECPDL_INDEX ();
4075 3478
4076 CHECK_OVERLAY (overlay); 3479 CHECK_OVERLAY (overlay);
4077 3480
4078 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3481 b = OVERLAY_BUFFER (overlay);
4079 if (NILP (buffer)) 3482 if (! b)
4080 return Qnil; 3483 return Qnil;
4081 3484
4082 b = XBUFFER (buffer);
4083 specbind (Qinhibit_quit, Qt); 3485 specbind (Qinhibit_quit, Qt);
4084 3486
4085 unchain_both (b, overlay); 3487 drop_overlay (XOVERLAY (overlay));
4086 drop_overlay (b, XOVERLAY (overlay));
4087 3488
4088 /* When deleting an overlay with before or after strings, turn off 3489 /* When deleting an overlay with before or after strings, turn off
4089 display optimizations for the affected buffer, on the basis that 3490 display optimizations for the affected buffer, on the basis that
@@ -4114,8 +3515,10 @@ DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
4114 (Lisp_Object overlay) 3515 (Lisp_Object overlay)
4115{ 3516{
4116 CHECK_OVERLAY (overlay); 3517 CHECK_OVERLAY (overlay);
3518 if (! OVERLAY_BUFFER (overlay))
3519 return Qnil;
4117 3520
4118 return (Fmarker_position (OVERLAY_START (overlay))); 3521 return make_number (OVERLAY_START (overlay));
4119} 3522}
4120 3523
4121DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0, 3524DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
@@ -4123,8 +3526,10 @@ DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
4123 (Lisp_Object overlay) 3526 (Lisp_Object overlay)
4124{ 3527{
4125 CHECK_OVERLAY (overlay); 3528 CHECK_OVERLAY (overlay);
3529 if (! OVERLAY_BUFFER (overlay))
3530 return Qnil;
4126 3531
4127 return (Fmarker_position (OVERLAY_END (overlay))); 3532 return make_number (OVERLAY_END (overlay));
4128} 3533}
4129 3534
4130DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0, 3535DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
@@ -4132,9 +3537,16 @@ DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
4132Return nil if OVERLAY has been deleted. */) 3537Return nil if OVERLAY has been deleted. */)
4133 (Lisp_Object overlay) 3538 (Lisp_Object overlay)
4134{ 3539{
3540 Lisp_Object buffer;
3541
4135 CHECK_OVERLAY (overlay); 3542 CHECK_OVERLAY (overlay);
4136 3543
4137 return Fmarker_buffer (OVERLAY_START (overlay)); 3544 if (! OVERLAY_BUFFER (overlay))
3545 return Qnil;
3546
3547 XSETBUFFER (buffer, OVERLAY_BUFFER (overlay));
3548
3549 return buffer;
4138} 3550}
4139 3551
4140DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0, 3552DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
@@ -4145,7 +3557,7 @@ OVERLAY. */)
4145{ 3557{
4146 CHECK_OVERLAY (overlay); 3558 CHECK_OVERLAY (overlay);
4147 3559
4148 return Fcopy_sequence (XOVERLAY (overlay)->plist); 3560 return Fcopy_sequence (OVERLAY_PLIST (overlay));
4149} 3561}
4150 3562
4151 3563
@@ -4169,8 +3581,7 @@ If SORTED is non-nil, then sort them by decreasing priority. */)
4169 3581
4170 /* Put all the overlays we want in a vector in overlay_vec. 3582 /* Put all the overlays we want in a vector in overlay_vec.
4171 Store the length in len. */ 3583 Store the length in len. */
4172 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, 3584 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, NULL);
4173 NULL, NULL, 0);
4174 3585
4175 if (!NILP (sorted)) 3586 if (!NILP (sorted))
4176 noverlays = sort_overlays (overlay_vec, noverlays, 3587 noverlays = sort_overlays (overlay_vec, noverlays,
@@ -4213,8 +3624,7 @@ end of the buffer. */)
4213 3624
4214 /* Put all the overlays we want in a vector in overlay_vec. 3625 /* Put all the overlays we want in a vector in overlay_vec.
4215 Store the length in len. */ 3626 Store the length in len. */
4216 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len, 3627 noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len, true, NULL);
4217 NULL, NULL);
4218 3628
4219 /* Make a list of them all. */ 3629 /* Make a list of them all. */
4220 result = Flist (noverlays, overlay_vec); 3630 result = Flist (noverlays, overlay_vec);
@@ -4230,39 +3640,12 @@ If there are no overlay boundaries from POS to (point-max),
4230the value is (point-max). */) 3640the value is (point-max). */)
4231 (Lisp_Object pos) 3641 (Lisp_Object pos)
4232{ 3642{
4233 ptrdiff_t i, len, noverlays;
4234 ptrdiff_t endpos;
4235 Lisp_Object *overlay_vec;
4236
4237 CHECK_NUMBER_COERCE_MARKER (pos); 3643 CHECK_NUMBER_COERCE_MARKER (pos);
4238 3644
4239 if (!buffer_has_overlays ()) 3645 if (!buffer_has_overlays ())
4240 return make_number (ZV); 3646 return make_number (ZV);
4241 3647
4242 len = 10; 3648 return make_number (next_overlay_change (XINT (pos)));
4243 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4244
4245 /* Put all the overlays we want in a vector in overlay_vec.
4246 Store the length in len.
4247 endpos gets the position where the next overlay starts. */
4248 noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
4249 &endpos, 0, 1);
4250
4251 /* If any of these overlays ends before endpos,
4252 use its ending point instead. */
4253 for (i = 0; i < noverlays; i++)
4254 {
4255 Lisp_Object oend;
4256 ptrdiff_t oendpos;
4257
4258 oend = OVERLAY_END (overlay_vec[i]);
4259 oendpos = OVERLAY_POSITION (oend);
4260 if (oendpos < endpos)
4261 endpos = oendpos;
4262 }
4263
4264 xfree (overlay_vec);
4265 return make_number (endpos);
4266} 3649}
4267 3650
4268DEFUN ("previous-overlay-change", Fprevious_overlay_change, 3651DEFUN ("previous-overlay-change", Fprevious_overlay_change,
@@ -4272,32 +3655,15 @@ If there are no overlay boundaries from (point-min) to POS,
4272the value is (point-min). */) 3655the value is (point-min). */)
4273 (Lisp_Object pos) 3656 (Lisp_Object pos)
4274{ 3657{
4275 ptrdiff_t prevpos;
4276 Lisp_Object *overlay_vec;
4277 ptrdiff_t len;
4278 3658
4279 CHECK_NUMBER_COERCE_MARKER (pos); 3659 CHECK_NUMBER_COERCE_MARKER (pos);
4280 3660
4281 if (!buffer_has_overlays ()) 3661 if (!buffer_has_overlays ())
4282 return make_number (BEGV); 3662 return make_number (BEGV);
4283 3663
4284 /* At beginning of buffer, we know the answer; 3664 return make_number (previous_overlay_change (XINT (pos)));
4285 avoid bug subtracting 1 below. */
4286 if (XINT (pos) == BEGV)
4287 return pos;
4288
4289 len = 10;
4290 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4291
4292 /* Put all the overlays we want in a vector in overlay_vec.
4293 Store the length in len.
4294 prevpos gets the position of the previous change. */
4295 overlays_at (XINT (pos), 1, &overlay_vec, &len,
4296 0, &prevpos, 1);
4297
4298 xfree (overlay_vec);
4299 return make_number (prevpos);
4300} 3665}
3666
4301 3667
4302/* These functions are for debugging overlays. */ 3668/* These functions are for debugging overlays. */
4303 3669
@@ -4307,24 +3673,21 @@ The car has all the overlays before the overlay center;
4307the cdr has all the overlays after the overlay center. 3673the cdr has all the overlays after the overlay center.
4308Recentering overlays moves overlays between these lists. 3674Recentering overlays moves overlays between these lists.
4309The lists you get are copies, so that changing them has no effect. 3675The lists you get are copies, so that changing them has no effect.
4310However, the overlays you get are the real objects that the buffer uses. */) 3676However, the overlays you get are the real objects that the buffer uses. */)
4311 (void) 3677 (void)
4312{ 3678{
4313 struct Lisp_Overlay *ol; 3679 Lisp_Object overlays = Qnil;
4314 Lisp_Object before = Qnil, after = Qnil, tmp;
4315 3680
4316 for (ol = current_buffer->overlays_before; ol; ol = ol->next) 3681 if (current_buffer->overlays)
4317 {
4318 XSETMISC (tmp, ol);
4319 before = Fcons (tmp, before);
4320 }
4321 for (ol = current_buffer->overlays_after; ol; ol = ol->next)
4322 { 3682 {
4323 XSETMISC (tmp, ol); 3683 struct interval_node *node;
4324 after = Fcons (tmp, after);
4325 }
4326 3684
4327 return Fcons (Fnreverse (before), Fnreverse (after)); 3685 buffer_overlay_iter_start (current_buffer, BEG, Z, ITREE_DESCENDING);
3686 while ((node = buffer_overlay_iter_next (current_buffer)))
3687 overlays = Fcons (node->data, overlays);
3688 buffer_overlay_iter_finish (current_buffer);
3689 }
3690 return Fcons (overlays, Qnil);
4328} 3691}
4329 3692
4330DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0, 3693DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
@@ -4333,11 +3696,8 @@ That makes overlay lookup faster for positions near POS (but perhaps slower
4333for positions far away from POS). */) 3696for positions far away from POS). */)
4334 (Lisp_Object pos) 3697 (Lisp_Object pos)
4335{ 3698{
4336 ptrdiff_t p;
4337 CHECK_NUMBER_COERCE_MARKER (pos); 3699 CHECK_NUMBER_COERCE_MARKER (pos);
4338 3700 /* Noop */
4339 p = clip_to_bounds (PTRDIFF_MIN, XINT (pos), PTRDIFF_MAX);
4340 recenter_overlay_lists (current_buffer, p);
4341 return Qnil; 3701 return Qnil;
4342} 3702}
4343 3703
@@ -4354,12 +3714,13 @@ DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
4354VALUE will be returned.*/) 3714VALUE will be returned.*/)
4355 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value) 3715 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
4356{ 3716{
4357 Lisp_Object tail, buffer; 3717 Lisp_Object tail;
3718 struct buffer *b;
4358 bool changed; 3719 bool changed;
4359 3720
4360 CHECK_OVERLAY (overlay); 3721 CHECK_OVERLAY (overlay);
4361 3722
4362 buffer = Fmarker_buffer (OVERLAY_START (overlay)); 3723 b = OVERLAY_BUFFER (overlay);
4363 3724
4364 for (tail = XOVERLAY (overlay)->plist; 3725 for (tail = XOVERLAY (overlay)->plist;
4365 CONSP (tail) && CONSP (XCDR (tail)); 3726 CONSP (tail) && CONSP (XCDR (tail));
@@ -4375,15 +3736,14 @@ VALUE will be returned.*/)
4375 set_overlay_plist 3736 set_overlay_plist
4376 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist))); 3737 (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist)));
4377 found: 3738 found:
4378 if (! NILP (buffer)) 3739 if (b)
4379 { 3740 {
4380 if (changed) 3741 if (changed)
4381 modify_overlay (XBUFFER (buffer), 3742 modify_overlay (b, OVERLAY_START (overlay),
4382 marker_position (OVERLAY_START (overlay)), 3743 OVERLAY_END (overlay));
4383 marker_position (OVERLAY_END (overlay)));
4384 if (EQ (prop, Qevaporate) && ! NILP (value) 3744 if (EQ (prop, Qevaporate) && ! NILP (value)
4385 && (OVERLAY_POSITION (OVERLAY_START (overlay)) 3745 && (OVERLAY_START (overlay)
4386 == OVERLAY_POSITION (OVERLAY_END (overlay)))) 3746 == OVERLAY_END (overlay)))
4387 Fdelete_overlay (overlay); 3747 Fdelete_overlay (overlay);
4388 } 3748 }
4389 3749
@@ -4441,14 +3801,9 @@ void
4441report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, 3801report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4442 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) 3802 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
4443{ 3803{
4444 Lisp_Object prop, overlay;
4445 struct Lisp_Overlay *tail;
4446 /* True if this change is an insertion. */ 3804 /* True if this change is an insertion. */
4447 bool insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end)); 3805 bool insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
4448 3806
4449 overlay = Qnil;
4450 tail = NULL;
4451
4452 /* We used to run the functions as soon as we found them and only register 3807 /* We used to run the functions as soon as we found them and only register
4453 them in last_overlay_modification_hooks for the purpose of the `after' 3808 them in last_overlay_modification_hooks for the purpose of the `after'
4454 case. But running elisp code as we traverse the list of overlays is 3809 case. But running elisp code as we traverse the list of overlays is
@@ -4459,68 +3814,35 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4459 3814
4460 if (!after) 3815 if (!after)
4461 { 3816 {
3817 struct interval_node *node;
3818 EMACS_INT begin_arg = XFASTINT (start);
3819 EMACS_INT end_arg = XFASTINT (end);
4462 /* We are being called before a change. 3820 /* We are being called before a change.
4463 Scan the overlays to find the functions to call. */ 3821 Scan the overlays to find the functions to call. */
4464 last_overlay_modification_hooks_used = 0; 3822 last_overlay_modification_hooks_used = 0;
4465 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
4466 {
4467 ptrdiff_t startpos, endpos;
4468 Lisp_Object ostart, oend;
4469
4470 XSETMISC (overlay, tail);
4471
4472 ostart = OVERLAY_START (overlay);
4473 oend = OVERLAY_END (overlay);
4474 endpos = OVERLAY_POSITION (oend);
4475 if (XFASTINT (start) > endpos)
4476 break;
4477 startpos = OVERLAY_POSITION (ostart);
4478 if (insertion && (XFASTINT (start) == startpos
4479 || XFASTINT (end) == startpos))
4480 {
4481 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4482 if (!NILP (prop))
4483 add_overlay_mod_hooklist (prop, overlay);
4484 }
4485 if (insertion && (XFASTINT (start) == endpos
4486 || XFASTINT (end) == endpos))
4487 {
4488 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4489 if (!NILP (prop))
4490 add_overlay_mod_hooklist (prop, overlay);
4491 }
4492 /* Test for intersecting intervals. This does the right thing
4493 for both insertion and deletion. */
4494 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
4495 {
4496 prop = Foverlay_get (overlay, Qmodification_hooks);
4497 if (!NILP (prop))
4498 add_overlay_mod_hooklist (prop, overlay);
4499 }
4500 }
4501 3823
4502 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 3824 if (! current_buffer->overlays)
3825 return;
3826 buffer_overlay_iter_start (current_buffer,
3827 begin_arg - (insertion ? 1 : 0),
3828 end_arg + (insertion ? 1 : 0),
3829 ITREE_ASCENDING);
3830 while ((node = buffer_overlay_iter_next (current_buffer)))
4503 { 3831 {
4504 ptrdiff_t startpos, endpos; 3832 Lisp_Object overlay = node->data;
4505 Lisp_Object ostart, oend; 3833 ptrdiff_t obegin = OVERLAY_START (overlay);
4506 3834 ptrdiff_t oend = OVERLAY_END (overlay);
4507 XSETMISC (overlay, tail); 3835 Lisp_Object prop;
4508 3836
4509 ostart = OVERLAY_START (overlay); 3837 if (insertion && (begin_arg == obegin
4510 oend = OVERLAY_END (overlay); 3838 || end_arg == obegin))
4511 startpos = OVERLAY_POSITION (ostart);
4512 endpos = OVERLAY_POSITION (oend);
4513 if (XFASTINT (end) < startpos)
4514 break;
4515 if (insertion && (XFASTINT (start) == startpos
4516 || XFASTINT (end) == startpos))
4517 { 3839 {
4518 prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 3840 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4519 if (!NILP (prop)) 3841 if (!NILP (prop))
4520 add_overlay_mod_hooklist (prop, overlay); 3842 add_overlay_mod_hooklist (prop, overlay);
4521 } 3843 }
4522 if (insertion && (XFASTINT (start) == endpos 3844 if (insertion && (begin_arg == oend
4523 || XFASTINT (end) == endpos)) 3845 || end_arg == oend))
4524 { 3846 {
4525 prop = Foverlay_get (overlay, Qinsert_behind_hooks); 3847 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4526 if (!NILP (prop)) 3848 if (!NILP (prop))
@@ -4528,15 +3850,15 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4528 } 3850 }
4529 /* Test for intersecting intervals. This does the right thing 3851 /* Test for intersecting intervals. This does the right thing
4530 for both insertion and deletion. */ 3852 for both insertion and deletion. */
4531 if (XFASTINT (end) > startpos && XFASTINT (start) < endpos) 3853 if (! insertion || (end_arg > obegin && begin_arg < oend))
4532 { 3854 {
4533 prop = Foverlay_get (overlay, Qmodification_hooks); 3855 prop = Foverlay_get (overlay, Qmodification_hooks);
4534 if (!NILP (prop)) 3856 if (!NILP (prop))
4535 add_overlay_mod_hooklist (prop, overlay); 3857 add_overlay_mod_hooklist (prop, overlay);
4536 } 3858 }
4537 } 3859 }
3860 buffer_overlay_iter_finish (current_buffer);
4538 } 3861 }
4539
4540 { 3862 {
4541 /* Call the functions recorded in last_overlay_modification_hooks. 3863 /* Call the functions recorded in last_overlay_modification_hooks.
4542 First copy the vector contents, in case some of these hooks 3864 First copy the vector contents, in case some of these hooks
@@ -4558,7 +3880,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4558 function is never called to record the overlay modification 3880 function is never called to record the overlay modification
4559 hook functions in the last_overlay_modification_hooks 3881 hook functions in the last_overlay_modification_hooks
4560 array, so anything we find there is not ours. */ 3882 array, so anything we find there is not ours. */
4561 if (XMARKER (OVERLAY_START (ovl))->buffer != current_buffer) 3883 if (OVERLAY_BUFFER (ovl) != current_buffer)
4562 return; 3884 return;
4563 } 3885 }
4564 3886
@@ -4598,34 +3920,22 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after,
4598void 3920void
4599evaporate_overlays (ptrdiff_t pos) 3921evaporate_overlays (ptrdiff_t pos)
4600{ 3922{
4601 Lisp_Object overlay, hit_list; 3923 Lisp_Object hit_list;
4602 struct Lisp_Overlay *tail; 3924 struct interval_node *node;
3925
3926 if (! current_buffer->overlays)
3927 return;
4603 3928
4604 hit_list = Qnil; 3929 hit_list = Qnil;
4605 if (pos <= current_buffer->overlay_center) 3930 buffer_overlay_iter_start (current_buffer, pos, pos, ITREE_ASCENDING);
4606 for (tail = current_buffer->overlays_before; tail; tail = tail->next) 3931
4607 { 3932 while ((node = buffer_overlay_iter_next (current_buffer)))
4608 ptrdiff_t endpos; 3933 {
4609 XSETMISC (overlay, tail); 3934 if (node->end == pos
4610 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3935 && ! NILP (Foverlay_get (node->data, Qevaporate)))
4611 if (endpos < pos) 3936 hit_list = Fcons (node->data, hit_list);
4612 break; 3937 }
4613 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos 3938 buffer_overlay_iter_finish (current_buffer);
4614 && ! NILP (Foverlay_get (overlay, Qevaporate)))
4615 hit_list = Fcons (overlay, hit_list);
4616 }
4617 else
4618 for (tail = current_buffer->overlays_after; tail; tail = tail->next)
4619 {
4620 ptrdiff_t startpos;
4621 XSETMISC (overlay, tail);
4622 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4623 if (startpos > pos)
4624 break;
4625 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
4626 && ! NILP (Foverlay_get (overlay, Qevaporate)))
4627 hit_list = Fcons (overlay, hit_list);
4628 }
4629 for (; CONSP (hit_list); hit_list = XCDR (hit_list)) 3939 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4630 Fdelete_overlay (XCAR (hit_list)); 3940 Fdelete_overlay (XCAR (hit_list));
4631} 3941}
@@ -5212,9 +4522,7 @@ init_buffer_once (void)
5212 bset_mark_active (&buffer_defaults, Qnil); 4522 bset_mark_active (&buffer_defaults, Qnil);
5213 bset_file_format (&buffer_defaults, Qnil); 4523 bset_file_format (&buffer_defaults, Qnil);
5214 bset_auto_save_file_format (&buffer_defaults, Qt); 4524 bset_auto_save_file_format (&buffer_defaults, Qt);
5215 set_buffer_overlays_before (&buffer_defaults, NULL); 4525 buffer_defaults.overlays = NULL;
5216 set_buffer_overlays_after (&buffer_defaults, NULL);
5217 buffer_defaults.overlay_center = BEG;
5218 4526
5219 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8); 4527 XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8);
5220 bset_truncate_lines (&buffer_defaults, Qnil); 4528 bset_truncate_lines (&buffer_defaults, Qnil);
@@ -5434,6 +4742,48 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5434 emacs_abort (); 4742 emacs_abort ();
5435} 4743}
5436 4744
4745#ifdef ITREE_DEBUG
4746static Lisp_Object
4747make_lispy_interval_node (const struct interval_node *node)
4748{
4749 return listn (CONSTYPE_HEAP, 12,
4750 intern (":begin"),
4751 make_number (node->begin),
4752 intern (":end"),
4753 make_number (node->end),
4754 intern (":limit"),
4755 make_number (node->limit),
4756 intern (":offset"),
4757 make_number (node->offset),
4758 intern (":rear-advance"),
4759 node->rear_advance ? Qt : Qnil,
4760 intern (":front-advance"),
4761 node->front_advance ? Qt : Qnil);
4762}
4763
4764static Lisp_Object
4765overlay_tree (const struct interval_tree *tree,
4766 const struct interval_node *node)
4767{
4768 if (node == &tree->nil)
4769 return Qnil;
4770 return list3 (make_lispy_interval_node (node),
4771 overlay_tree (tree, node->left),
4772 overlay_tree (tree, node->right));
4773}
4774
4775DEFUN ("overlay-tree", Foverlay_tree, Soverlay_tree, 0, 1, 0,
4776 doc: /* Get the overlay tree for BUFFER. */)
4777 (Lisp_Object buffer)
4778{
4779 struct buffer *b = decode_buffer (buffer);
4780 if (! b->overlays)
4781 return Qnil;
4782 return overlay_tree (b->overlays, b->overlays->root);
4783}
4784#endif
4785
4786
5437 4787
5438/* Initialize the buffer routines. */ 4788/* Initialize the buffer routines. */
5439void 4789void
@@ -6303,6 +5653,10 @@ Functions running this hook are, `get-buffer-create',
6303 defsubr (&Srestore_buffer_modified_p); 5653 defsubr (&Srestore_buffer_modified_p);
6304 5654
6305 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); 5655 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
5656
5657#ifdef ITREE_DEBUG
5658 defsubr (&Soverlay_tree);
5659#endif
6306} 5660}
6307 5661
6308void 5662void