Lisp_Object Qoverlayp;
-Lisp_Object Qpriority, Qwindow, Qevaporate;
+Lisp_Object Qpriority, Qwindow, Qevaporate, Qbefore_string, Qafter_string;
Lisp_Object Qmodification_hooks;
Lisp_Object Qinsert_in_front_hooks;
}
/* Switch to buffer B temporarily for redisplay purposes.
- This avoids certain things thatdon't need to be done within redisplay. */
+ This avoids certain things that don't need to be done within redisplay. */
void
set_buffer_temp (b)
Store in *LEN_PTR the size allocated for the vector.
Store in *NEXT_PTR the next position after POS where an overlay starts,
or ZV if there are no more overlays.
- Store in *PREV_PTR the previous position after POS where an overlay ends,
+ Store in *PREV_PTR the previous position before POS where an overlay ends,
or BEGV if there are no previous overlays.
NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
return (noverlays);
}
\f
+struct sortstr
+{
+ Lisp_Object string;
+ int size;
+ int priority;
+};
+
+/* A comparison function suitable for passing to qsort. */
+static int
+cmp_for_strings (as1, as2)
+ char *as1, *as2;
+{
+ struct sortstr *s1 = (struct sortstr *)as1;
+ struct sortstr *s2 = (struct sortstr *)as2;
+ if (s1->size != s2->size)
+ return s2->size - s1->size;
+ if (s1->priority != s2->priority)
+ return s1->priority - s2->priority;
+ return 0;
+}
+
+/* Buffers for storing the overlays touching a given position.
+ These are expanded as needed, but never freed. */
+static struct sortstr *overlay_heads, *overlay_tails;
+static char *overlay_str_buf;
+
+/* Allocated length of those buffers. */
+static int overlay_heads_len, overlay_tails_len, overlay_str_len;
+
+/* Return the concatenation of the strings associated with overlays that
+ begin or end at POS, ignoring overlays that are specific to a window
+ other than W. The strings are concatenated in the appropriate order:
+ shorter overlays nest inside longer ones, and higher priority inside
+ lower. Returns the string length, and stores the contents indirectly
+ through PSTR, if that variable is non-null. The string may be
+ overwritten by subsequent calls. */
+int
+overlay_strings (pos, w, pstr)
+ int pos;
+ struct window *w;
+ char **pstr;
+{
+ Lisp_Object ov, overlay, window, str, tem;
+ int ntail = 0, nhead = 0;
+ int total = 0;
+ int startpos, endpos;
+
+ for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCONS (ov)->cdr)
+ {
+ overlay = XCONS (ov)->car;
+ if (!OVERLAYP (overlay))
+ abort ();
+
+ startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ if (endpos < pos)
+ break;
+ if (endpos != pos && startpos != pos)
+ continue;
+ window = Foverlay_get (overlay, Qwindow);
+ if (WINDOWP (window) && XWINDOW (window) != w)
+ continue;
+ if (endpos == pos)
+ {
+ str = Foverlay_get (overlay, Qafter_string);
+ if (STRINGP (str))
+ {
+ if (ntail == overlay_tails_len)
+ {
+ if (! overlay_tails)
+ {
+ overlay_tails_len = 5;
+ overlay_tails = ((struct sortstr *)
+ xmalloc (5 * sizeof (struct sortstr)));
+ }
+ else
+ {
+ overlay_tails_len *= 2;
+ overlay_tails = ((struct sortstr *)
+ xrealloc ((overlay_tails_len
+ * sizeof (struct sortstr))));
+ }
+ }
+ overlay_tails[ntail].string = str;
+ overlay_tails[ntail].size = endpos - startpos;
+ tem = Foverlay_get (overlay, Qpriority);
+ overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+ ntail++;
+ total += XSTRING (str)->size;
+ }
+ }
+ if (startpos == pos)
+ {
+ str = Foverlay_get (overlay, Qbefore_string);
+ if (STRINGP (str))
+ {
+ if (nhead == overlay_heads_len)
+ {
+ if (! overlay_heads)
+ {
+ overlay_heads_len = 5;
+ overlay_heads = ((struct sortstr *)
+ xmalloc (5 * sizeof (struct sortstr)));
+ }
+ else
+ {
+ overlay_heads_len *= 2;
+ overlay_heads = ((struct sortstr *)
+ xrealloc ((overlay_heads_len
+ * sizeof (struct sortstr))));
+ }
+ }
+ overlay_heads[nhead].string = str;
+ overlay_heads[nhead].size = endpos - startpos;
+ tem = Foverlay_get (overlay, Qpriority);
+ overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+ nhead++;
+ total += XSTRING (str)->size;
+ }
+ }
+ }
+ for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCONS (ov)->cdr)
+ {
+ overlay = XCONS (ov)->car;
+ if (!OVERLAYP (overlay))
+ abort ();
+
+ startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ if (startpos > pos)
+ break;
+ if (endpos == pos)
+ {
+ str = Foverlay_get (overlay, Qafter_string);
+ if (STRINGP (str))
+ {
+ if (ntail == overlay_tails_len)
+ {
+ if (! overlay_tails)
+ {
+ overlay_tails_len = 5;
+ overlay_tails = ((struct sortstr *)
+ xmalloc (5 * sizeof (struct sortstr)));
+ }
+ else
+ {
+ overlay_tails_len *= 2;
+ overlay_tails = ((struct sortstr *)
+ xrealloc ((overlay_tails_len
+ * sizeof (struct sortstr))));
+ }
+ }
+ overlay_tails[ntail].string = str;
+ overlay_tails[ntail].size = endpos - startpos;
+ tem = Foverlay_get (overlay, Qpriority);
+ overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+ ntail++;
+ total += XSTRING (str)->size;
+ }
+ }
+ if (startpos == pos)
+ {
+ str = Foverlay_get (overlay, Qbefore_string);
+ if (STRINGP (str))
+ {
+ if (nhead == overlay_heads_len)
+ {
+ if (! overlay_heads)
+ {
+ overlay_heads_len = 5;
+ overlay_heads = ((struct sortstr *)
+ xmalloc (5 * sizeof (struct sortstr)));
+ }
+ else
+ {
+ overlay_heads_len *= 2;
+ overlay_heads = ((struct sortstr *)
+ xrealloc ((overlay_heads_len
+ * sizeof (struct sortstr))));
+ }
+ }
+ overlay_heads[nhead].string = str;
+ overlay_heads[nhead].size = endpos - startpos;
+ tem = Foverlay_get (overlay, Qpriority);
+ overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0);
+ nhead++;
+ total += XSTRING (str)->size;
+ }
+ }
+ }
+ if (ntail > 1)
+ qsort (overlay_tails, ntail, sizeof (struct sortstr), cmp_for_strings);
+ if (nhead > 1)
+ qsort (overlay_heads, nhead, sizeof (struct sortstr), cmp_for_strings);
+ if (total)
+ {
+ int i;
+ char *p;
+
+ if (total > overlay_str_len)
+ {
+ if (! overlay_str_buf)
+ overlay_str_buf = (char *)xmalloc (total);
+ else
+ overlay_str_buf = (char *)xrealloc (overlay_str_buf, total);
+ overlay_str_len = total;
+ }
+ p = overlay_str_buf;
+ for (i = ntail; --i >= 0;)
+ {
+ tem = overlay_tails[i].string;
+ bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
+ p += XSTRING (tem)->size;
+ }
+ for (i = 0; i < nhead; ++i)
+ {
+ tem = overlay_heads[i].string;
+ bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
+ p += XSTRING (tem)->size;
+ }
+ if (pstr)
+ *pstr = overlay_str_buf;
+ }
+ return total;
+}
+\f
/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
void
buffer_defaults.file_format = Qnil;
buffer_defaults.overlays_before = Qnil;
buffer_defaults.overlays_after = Qnil;
- XSETFASTINT (buffer_defaults.overlay_center, 1);
+ XSETFASTINT (buffer_defaults.overlay_center, BEG);
XSETFASTINT (buffer_defaults.tab_width, 8);
buffer_defaults.truncate_lines = Qnil;
staticpro (&Qpriority);
Qwindow = intern ("window");
staticpro (&Qwindow);
+ Qbefore_string = intern ("before-string");
+ staticpro (&Qbefore_string);
+ Qafter_string = intern ("after-string");
+ staticpro (&Qafter_string);
Qoverlayp = intern ("overlayp");