Commit bbbe9545 authored by Karl Heuer's avatar Karl Heuer

(Qbefore_string, Qafter_string): New vars.

(syms_of_buffer): Initialize and staticpro them.
(cmp_for_strings, overlay_strings): New functions.
parent 635389e4
......@@ -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");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment