+ beg = Fset_marker (Fmake_marker (), beg, buffer);
+ end = Fset_marker (Fmake_marker (), end, buffer);
+
+ overlay = Fcons (Fcons (beg, end), Qnil);
+ XSETTYPE (overlay, Lisp_Overlay);
+
+ /* Put the new overlay on the wrong list. */
+ end = OVERLAY_END (overlay);
+ if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
+ b->overlays_after = Fcons (overlay, b->overlays_after);
+ else
+ b->overlays_before = Fcons (overlay, b->overlays_before);
+
+ /* This puts it in the right list, and in the right order. */
+ recenter_overlay_lists (b, XINT (b->overlay_center));
+
+ /* We don't need to redisplay the region covered by the overlay, because
+ the overlay has no properties at the moment. */
+
+ return overlay;
+}
+
+DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
+ "Set the endpoints of OVERLAY to BEG and END in BUFFER.\n\
+If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.\n\
+If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current\n\
+buffer.")
+ (overlay, beg, end, buffer)
+ Lisp_Object overlay, beg, end, buffer;
+{
+ struct buffer *b, *ob;
+ Lisp_Object obuffer;
+ int count = specpdl_ptr - specpdl;
+
+ CHECK_OVERLAY (overlay, 0);
+ if (NILP (buffer))
+ buffer = Fmarker_buffer (OVERLAY_START (overlay));
+ if (NILP (buffer))
+ XSET (buffer, Lisp_Buffer, current_buffer);
+ CHECK_BUFFER (buffer, 3);
+
+ if (MARKERP (beg)
+ && ! EQ (Fmarker_buffer (beg), buffer))
+ error ("Marker points into wrong buffer");
+ if (MARKERP (end)
+ && ! EQ (Fmarker_buffer (end), buffer))
+ error ("Marker points into wrong buffer");
+
+ CHECK_NUMBER_COERCE_MARKER (beg, 1);
+ CHECK_NUMBER_COERCE_MARKER (end, 1);
+
+ specbind (Qinhibit_quit, Qt);
+
+ if (XINT (beg) > XINT (end))
+ {
+ Lisp_Object temp;
+ temp = beg; beg = end; end = temp;
+ }
+
+ obuffer = Fmarker_buffer (OVERLAY_START (overlay));
+ b = XBUFFER (buffer);
+ ob = XBUFFER (obuffer);
+
+ /* If the overlay has changed buffers, do a thorough redisplay. */
+ if (!EQ (buffer, obuffer))
+ windows_or_buffers_changed = 1;
+ else
+ /* Redisplay the area the overlay has just left, or just enclosed. */
+ {
+ Lisp_Object o_beg;
+ Lisp_Object o_end;
+ int change_beg, change_end;
+
+ o_beg = OVERLAY_START (overlay);
+ o_end = OVERLAY_END (overlay);
+ o_beg = OVERLAY_POSITION (o_beg);
+ o_end = OVERLAY_POSITION (o_end);
+
+ if (XINT (o_beg) == XINT (beg))
+ redisplay_region (b, XINT (o_end), XINT (end));
+ else if (XINT (o_end) == XINT (end))
+ redisplay_region (b, XINT (o_beg), XINT (beg));
+ else
+ {
+ if (XINT (beg) < XINT (o_beg)) o_beg = beg;
+ if (XINT (end) > XINT (o_end)) o_end = end;
+ redisplay_region (b, XINT (o_beg), XINT (o_end));
+ }
+ }
+
+ if (!NILP (obuffer))
+ {
+ ob->overlays_before = Fdelq (overlay, ob->overlays_before);
+ ob->overlays_after = Fdelq (overlay, ob->overlays_after);
+ }
+
+ Fset_marker (OVERLAY_START (overlay), beg, buffer);
+ Fset_marker (OVERLAY_END (overlay), end, buffer);
+
+ /* Put the overlay on the wrong list. */
+ end = OVERLAY_END (overlay);
+ if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
+ b->overlays_after = Fcons (overlay, b->overlays_after);
+ else
+ b->overlays_before = Fcons (overlay, b->overlays_before);
+
+ /* This puts it in the right list, and in the right order. */
+ recenter_overlay_lists (b, XINT (b->overlay_center));
+
+ return unbind_to (count, overlay);
+}
+
+DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
+ "Delete the overlay OVERLAY from its buffer.")
+ (overlay)
+ Lisp_Object overlay;
+{
+ Lisp_Object buffer;
+ struct buffer *b;
+ int count = specpdl_ptr - specpdl;
+
+ CHECK_OVERLAY (overlay, 0);
+
+ buffer = Fmarker_buffer (OVERLAY_START (overlay));
+ if (NILP (buffer))
+ return Qnil;
+
+ b = XBUFFER (buffer);
+
+ specbind (Qinhibit_quit, Qt);
+
+ b->overlays_before = Fdelq (overlay, b->overlays_before);
+ b->overlays_after = Fdelq (overlay, b->overlays_after);
+
+ redisplay_region (b,
+ marker_position (OVERLAY_START (overlay)),
+ marker_position (OVERLAY_END (overlay)));
+
+ Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
+ Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
+
+ return unbind_to (count, Qnil);
+}
+\f
+/* Overlay dissection functions. */
+
+DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
+ "Return the position at which OVERLAY starts.")
+ (overlay)
+ Lisp_Object overlay;
+{
+ CHECK_OVERLAY (overlay, 0);
+
+ return (Fmarker_position (OVERLAY_START (overlay)));
+}
+
+DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
+ "Return the position at which OVERLAY ends.")
+ (overlay)
+ Lisp_Object overlay;
+{
+ CHECK_OVERLAY (overlay, 0);
+
+ return (Fmarker_position (OVERLAY_END (overlay)));
+}
+
+DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
+ "Return the buffer OVERLAY belongs to.")
+ (overlay)
+ Lisp_Object overlay;
+{
+ CHECK_OVERLAY (overlay, 0);
+
+ return Fmarker_buffer (OVERLAY_START (overlay));
+}
+
+DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
+ "Return a list of the properties on OVERLAY.\n\
+This is a copy of OVERLAY's plist; modifying its conses has no effect on\n\
+OVERLAY.")
+ (overlay)
+ Lisp_Object overlay;
+{
+ CHECK_OVERLAY (overlay, 0);
+
+ return Fcopy_sequence (Fcdr_safe (XCONS (overlay)->cdr));
+}
+
+\f
+DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
+ "Return a list of the overlays that contain position POS.")
+ (pos)
+ Lisp_Object pos;
+{
+ int noverlays;
+ int endpos;
+ Lisp_Object *overlay_vec;
+ int len;
+ Lisp_Object result;
+
+ CHECK_NUMBER_COERCE_MARKER (pos, 0);
+
+ len = 10;
+ overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
+
+ /* Put all the overlays we want in a vector in overlay_vec.
+ Store the length in len. */
+ noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &endpos);
+
+ /* Make a list of them all. */
+ result = Flist (noverlays, overlay_vec);
+
+ xfree (overlay_vec);
+ return result;
+}
+
+DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
+ 1, 1, 0,
+ "Return the next position after POS where an overlay starts or ends.")
+ (pos)
+ Lisp_Object pos;
+{
+ int noverlays;
+ int endpos;
+ Lisp_Object *overlay_vec;
+ int len;
+ Lisp_Object result;
+ int i;
+
+ CHECK_NUMBER_COERCE_MARKER (pos, 0);
+
+ len = 10;
+ overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
+
+ /* Put all the overlays we want in a vector in overlay_vec.
+ Store the length in len.
+ endpos gets the position where the next overlay starts. */
+ noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &endpos);
+
+ /* If any of these overlays ends before endpos,
+ use its ending point instead. */
+ for (i = 0; i < noverlays; i++)
+ {
+ Lisp_Object oend;
+ int oendpos;
+
+ oend = OVERLAY_END (overlay_vec[i]);
+ oendpos = OVERLAY_POSITION (oend);
+ if (oendpos < endpos)
+ endpos = oendpos;
+ }
+
+ xfree (overlay_vec);
+ return make_number (endpos);
+}
+\f
+/* These functions are for debugging overlays. */
+
+DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
+ "Return a pair of lists giving all the overlays of the current buffer.\n\
+The car has all the overlays before the overlay center;\n\
+the cdr has all the overlays before the overlay center.\n\
+Recentering overlays moves overlays between these lists.\n\
+The lists you get are copies, so that changing them has no effect.\n\
+However, the overlays you get are the real objects that the buffer uses.")
+ ()
+{
+ Lisp_Object before, after;
+ before = current_buffer->overlays_before;
+ if (CONSP (before))
+ before = Fcopy_sequence (before);
+ after = current_buffer->overlays_after;
+ if (CONSP (after))
+ after = Fcopy_sequence (after);
+
+ return Fcons (before, after);
+}
+
+DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
+ "Recenter the overlays of the current buffer around position POS.")
+ (pos)
+ Lisp_Object pos;
+{
+ CHECK_NUMBER_COERCE_MARKER (pos, 0);
+
+ recenter_overlay_lists (current_buffer, XINT (pos));
+ return Qnil;
+}
+\f
+DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
+ "Get the property of overlay OVERLAY with property name NAME.")
+ (overlay, prop)
+ Lisp_Object overlay, prop;
+{
+ Lisp_Object plist;
+
+ CHECK_OVERLAY (overlay, 0);
+
+ for (plist = Fcdr_safe (XCONS (overlay)->cdr);
+ CONSP (plist) && CONSP (XCONS (plist)->cdr);
+ plist = XCONS (XCONS (plist)->cdr)->cdr)
+ {
+ if (EQ (XCONS (plist)->car, prop))
+ return XCONS (XCONS (plist)->cdr)->car;
+ }
+
+ return Qnil;
+}
+
+DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
+ "Set one property of overlay OVERLAY: give property PROP value VALUE.")
+ (overlay, prop, value)
+ Lisp_Object overlay, prop, value;
+{
+ Lisp_Object plist, tail;
+
+ CHECK_OVERLAY (overlay, 0);
+
+ tail = Fmarker_buffer (OVERLAY_START (overlay));
+ if (! NILP (tail))
+ redisplay_region (XMARKER (OVERLAY_START (overlay))->buffer,
+ marker_position (OVERLAY_START (overlay)),
+ marker_position (OVERLAY_END (overlay)));