summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorKarl Heuer <kwzh@gnu.org>1995-05-05 00:34:00 +0000
committerKarl Heuer <kwzh@gnu.org>1995-05-05 00:34:00 +0000
commit02bfb731a5b7dc848d4f84fd8e22eee5cb0a0fac (patch)
tree2e062b7bdee558b8ee847b44e940fc4bfcaaee2e /src/buffer.c
parent638dfd0940e4bfc91e1787c290d67b10f5d39363 (diff)
downloademacs-02bfb731a5b7dc848d4f84fd8e22eee5cb0a0fac.tar.gz
(Qbefore_string, Qafter_string): New vars.
(syms_of_buffer): Initialize and staticpro them. (cmp_for_strings, overlay_strings): New functions.
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c238
1 files changed, 234 insertions, 4 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 6ba82668549..6cf2aea4b9d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -141,7 +141,7 @@ Lisp_Object Qget_file_buffer;
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;
@@ -1274,7 +1274,7 @@ set_buffer_internal (b)
}
/* 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)
@@ -1534,7 +1534,7 @@ swap_out_buffer_local_variables (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.
@@ -1776,6 +1776,232 @@ sort_overlays (overlay_vec, noverlays, w)
return (noverlays);
}
+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;
+}
+
/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
void
@@ -2796,7 +3022,7 @@ init_buffer_once ()
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;
@@ -2948,6 +3174,10 @@ syms_of_buffer ()
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");