# HG changeset patch # User Karl Heuer # Date 799634040 0 # Node ID efef31f1c42dc9074680c1359c89656bc41073fa # Parent b7c7710644d3157e6c692a2238e3911ab69448ed (Qbefore_string, Qafter_string): New vars. (syms_of_buffer): Initialize and staticpro them. (cmp_for_strings, overlay_strings): New functions. diff -r b7c7710644d3 -r efef31f1c42d src/buffer.c --- a/src/buffer.c Thu May 04 22:36:05 1995 +0000 +++ b/src/buffer.c Fri May 05 00:34:00 1995 +0000 @@ -141,7 +141,7 @@ 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 @@ } /* 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 @@ 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 @@ 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 @@ 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 @@ 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");