/* Interface code for dealing with text properties.
- Copyright (C) 1993 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "intervals.h"
#include "buffer.h"
#include "window.h"
+
+#ifndef NULL
+#define NULL (void *)0
+#endif
\f
/* NOTES: previous- and next- property change will have to skip
/* Visual properties text (including strings) may have. */
Lisp_Object Qforeground, Qbackground, Qfont, Qunderline, Qstipple;
-Lisp_Object Qinvisible, Qread_only, Qhidden;
+Lisp_Object Qinvisible, Qread_only, Qintangible;
/* Sticky properties */
Lisp_Object Qfront_sticky, Qrear_nonsticky;
/* If we are asked for a point, but from a subr which operates
on a range, then return nothing. */
- if (*begin == *end && begin != end)
+ if (EQ (*begin, *end) && begin != end)
return NULL_INTERVAL;
if (XINT (*begin) > XINT (*end))
*end = n;
}
- if (XTYPE (object) == Lisp_Buffer)
+ if (BUFFERP (object))
{
register struct buffer *b = XBUFFER (object);
args_out_of_range (*begin, *end);
/* User-level Positions in strings start with 0,
but the interval code always wants positions starting with 1. */
- XFASTINT (*begin) += 1;
+ XSETFASTINT (*begin, XFASTINT (*begin) + 1);
if (begin != end)
- XFASTINT (*end) += 1;
+ XSETFASTINT (*end, XFASTINT (*end) + 1);
i = s->intervals;
if (s->size == 0)
/* Return the value of PROP in property-list PLIST, or Qunbound if it
has none. */
-static int
+static Lisp_Object
property_value (plist, prop)
+ Lisp_Object plist, prop;
{
Lisp_Object value;
break;
/* Record this change in the buffer, for undo purposes. */
- if (XTYPE (object) == Lisp_Buffer)
+ if (BUFFERP (object))
{
modify_region (XBUFFER (object),
make_number (i->position),
if (! found)
{
/* Record this change in the buffer, for undo purposes. */
- if (XTYPE (object) == Lisp_Buffer)
+ if (BUFFERP (object))
{
modify_region (XBUFFER (object),
make_number (i->position),
/* First, remove the symbol if its at the head of the list */
while (! NILP (current_plist) && EQ (sym, Fcar (current_plist)))
{
- if (XTYPE (object) == Lisp_Buffer)
+ if (BUFFERP (object))
{
modify_region (XBUFFER (object),
make_number (i->position),
this = Fcdr (Fcdr (tail2));
if (EQ (sym, Fcar (this)))
{
- if (XTYPE (object) == Lisp_Buffer)
+ if (BUFFERP (object))
{
modify_region (XBUFFER (object),
make_number (i->position),
register INTERVAL i;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
i = validate_interval_range (object, &pos, &pos, soft);
if (NULL_INTERVAL_P (i))
If POSITION is at the end of OBJECT, the value is nil.")
(pos, prop, object)
Lisp_Object pos, object;
- register Lisp_Object prop;
+ Lisp_Object prop;
{
- register INTERVAL i;
- register Lisp_Object tail;
-
- if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
- i = validate_interval_range (object, &pos, &pos, soft);
- if (NULL_INTERVAL_P (i))
- return Qnil;
-
- /* If POS is at the end of the interval,
- it means it's the end of OBJECT.
- There are no properties at the very end,
- since no character follows. */
- if (XINT (pos) == LENGTH (i) + i->position)
- return Qnil;
-
- return textget (i->plist, prop);
+ return textget (Ftext_properties_at (pos, object), prop);
}
DEFUN ("get-char-property", Fget_char_property, Sget_char_property, 2, 3, 0,
CHECK_NUMBER_COERCE_MARKER (pos, 0);
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
if (WINDOWP (object))
{
w = XWINDOW (object);
- XSET (object, Lisp_Buffer, w->buffer);
+ object = w->buffer;
}
if (BUFFERP (object))
{
len = 40;
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
- noverlays = overlays_at (posn, 0, &overlay_vec, &len, &next_overlay);
+ noverlays = overlays_at (posn, 0, &overlay_vec, &len,
+ &next_overlay, NULL);
/* If there are more than 40,
make enough space for all, and try again. */
{
len = noverlays;
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
- noverlays = overlays_at (posn, 0, &overlay_vec, &len, &next_overlay);
+ noverlays = overlays_at (posn, 0, &overlay_vec, &len,
+ &next_overlay, NULL);
}
noverlays = sort_overlays (overlay_vec, noverlays, w);
register INTERVAL i, next;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
+
+ if (!NILP (limit))
+ CHECK_NUMBER_COERCE_MARKER (limit, 0);
i = validate_interval_range (object, &pos, &pos, soft);
if (NULL_INTERVAL_P (i))
if (! NILP (limit) && !(next->position < XFASTINT (limit)))
return limit;
- return next->position - (XTYPE (object) == Lisp_String);
+ XSETFASTINT (pos, next->position - (STRINGP (object)));
+ return pos;
}
/* Return 1 if there's a change in some property between BEG and END. */
register INTERVAL i, next;
Lisp_Object object, pos;
- XSET (object, Lisp_Buffer, current_buffer);
- XFASTINT (pos) = beg;
+ XSETBUFFER (object, current_buffer);
+ XSETFASTINT (pos, beg);
i = validate_interval_range (object, &pos, &pos, soft);
if (NULL_INTERVAL_P (i))
register Lisp_Object here_val;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
+
+ if (!NILP (limit))
+ CHECK_NUMBER_COERCE_MARKER (limit, 0);
i = validate_interval_range (object, &pos, &pos, soft);
if (NULL_INTERVAL_P (i))
if (! NILP (limit) && !(next->position < XFASTINT (limit)))
return limit;
- return next->position - (XTYPE (object) == Lisp_String);
+ XSETFASTINT (pos, next->position - (STRINGP (object)));
+ return pos;
}
DEFUN ("previous-property-change", Fprevious_property_change,
register INTERVAL i, previous;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
+
+ if (!NILP (limit))
+ CHECK_NUMBER_COERCE_MARKER (limit, 0);
i = validate_interval_range (object, &pos, &pos, soft);
if (NULL_INTERVAL_P (i))
&& !(previous->position + LENGTH (previous) > XFASTINT (limit)))
return limit;
- return (previous->position + LENGTH (previous)
- - (XTYPE (object) == Lisp_String));
+ XSETFASTINT (pos, (previous->position + LENGTH (previous)
+ - (STRINGP (object))));
+ return pos;
}
DEFUN ("previous-single-property-change", Fprevious_single_property_change,
register Lisp_Object here_val;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
+
+ if (!NILP (limit))
+ CHECK_NUMBER_COERCE_MARKER (limit, 0);
i = validate_interval_range (object, &pos, &pos, soft);
- if (NULL_INTERVAL_P (i))
- return limit;
/* Start with the interval containing the char before point. */
- if (i->position == XFASTINT (pos))
+ if (! NULL_INTERVAL_P (i) && i->position == XFASTINT (pos))
i = previous_interval (i);
+ if (NULL_INTERVAL_P (i))
+ return limit;
+
here_val = textget (i->plist, prop);
previous = previous_interval (i);
while (! NULL_INTERVAL_P (previous)
&& !(previous->position + LENGTH (previous) > XFASTINT (limit)))
return limit;
- return (previous->position + LENGTH (previous)
- - (XTYPE (object) == Lisp_String));
+ XSETFASTINT (pos, (previous->position + LENGTH (previous)
+ - (STRINGP (object))));
+ return pos;
}
DEFUN ("add-text-properties", Fadd_text_properties,
return Qnil;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
i = validate_interval_range (object, &start, &end, hard);
if (NULL_INTERVAL_P (i))
register INTERVAL i, unchanged;
register INTERVAL prev_changed = NULL_INTERVAL;
register int s, len;
+ Lisp_Object ostart, oend;
+
+ ostart = start;
+ oend = end;
props = validate_plist (props);
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
+
+ /* If we want no properties for a whole string,
+ get rid of its intervals. */
+ if (NILP (props) && STRINGP (object)
+ && XFASTINT (start) == 0
+ && XFASTINT (end) == XSTRING (object)->size)
+ {
+ XSTRING (object)->intervals = 0;
+ return Qt;
+ }
+
+ i = validate_interval_range (object, &start, &end, soft);
- i = validate_interval_range (object, &start, &end, hard);
if (NULL_INTERVAL_P (i))
- return Qnil;
+ {
+ /* If buffer has no props, and we want none, return now. */
+ if (NILP (props))
+ return Qnil;
+
+ /* Restore the original START and END values
+ because validate_interval_range increments them for strings. */
+ start = ostart;
+ end = oend;
+
+ i = validate_interval_range (object, &start, &end, hard);
+ /* This can return if start == end. */
+ if (NULL_INTERVAL_P (i))
+ return Qnil;
+ }
s = XINT (start);
len = XINT (end) - s;
register int s, len, modified = 0;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
i = validate_interval_range (object, &start, &end, soft);
if (NULL_INTERVAL_P (i))
register int e, pos;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
i = validate_interval_range (object, &start, &end, soft);
e = XINT (end);
pos = i->position;
if (pos < XINT (start))
pos = XINT (start);
- return make_number (pos - (XTYPE (object) == Lisp_String));
+ return make_number (pos - (STRINGP (object)));
}
i = next_interval (i);
}
register int s, e;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
i = validate_interval_range (object, &start, &end, soft);
if (NULL_INTERVAL_P (i))
return (NILP (value) || EQ (start, end)) ? Qnil : start;
{
if (i->position > s)
s = i->position;
- return make_number (s - (XTYPE (object) == Lisp_String));
+ return make_number (s - (STRINGP (object)));
}
i = next_interval (i);
}
register int s, len, modified;
if (NILP (object))
- XSET (object, Lisp_Buffer, current_buffer);
+ XSETBUFFER (object, current_buffer);
i = validate_interval_range (object, &start, &end, soft);
if (NULL_INTERVAL_P (i))
Lisp_Object dest_start, dest_end;
dest_start = pos;
- XFASTINT (dest_end) = XINT (dest_start) + (XINT (end) - XINT (start));
+ XSETFASTINT (dest_end, XINT (dest_start) + (XINT (end) - XINT (start)));
/* Apply this to a copy of pos; it will try to increment its arguments,
which we don't want. */
validate_interval_range (dest, &dest_start, &dest_end, soft);
void
syms_of_textprop ()
{
- DEFVAR_INT ("interval-balance-threshold", &interval_balance_threshold,
- "Threshold for rebalancing interval trees, expressed as the\n\
-percentage by which the left interval tree should not differ from the right.");
- interval_balance_threshold = 8;
-
DEFVAR_LISP ("inhibit-point-motion-hooks", &Vinhibit_point_motion_hooks,
- "If non-nil, don't call the text property values of\n\
-`point-left' and `point-entered'.");
+ "If non-nil, don't run `point-left' and `point-entered' text properties.\n\
+This also inhibits the use of the `intangible' text property.");
Vinhibit_point_motion_hooks = Qnil;
/* Common attributes one might give text */
Qread_only = intern ("read-only");
staticpro (&Qinvisible);
Qinvisible = intern ("invisible");
- staticpro (&Qhidden);
- Qhidden = intern ("hidden");
+ staticpro (&Qintangible);
+ Qintangible = intern ("intangible");
staticpro (&Qcategory);
Qcategory = intern ("category");
staticpro (&Qlocal_map);
defsubr (&Stext_properties_at);
defsubr (&Sget_text_property);
+ defsubr (&Sget_char_property);
defsubr (&Snext_property_change);
defsubr (&Snext_single_property_change);
defsubr (&Sprevious_property_change);