/* Interface code for dealing with text properties.
- Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002
+ Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GNU Emacs.
to capture that error in GDB by putting a breakpoint on it. */
static void
-text_read_only ()
+text_read_only (propval)
+ Lisp_Object propval;
{
- Fsignal (Qtext_read_only, Qnil);
+ Fsignal (Qtext_read_only, STRINGP (propval) ? Fcons (propval, Qnil) : Qnil);
}
}
else
{
- register struct Lisp_String *s = XSTRING (object);
+ int len = SCHARS (object);
if (! (0 <= XINT (*begin) && XINT (*begin) <= XINT (*end)
- && XINT (*end) <= s->size))
+ && XINT (*end) <= len))
args_out_of_range (*begin, *end);
XSETFASTINT (*begin, XFASTINT (*begin));
if (begin != end)
XSETFASTINT (*end, XFASTINT (*end));
- i = s->intervals;
+ i = STRING_INTERVALS (object);
- if (s->size == 0)
+ if (len == 0)
return NULL_INTERVAL;
searchpos = XINT (*begin);
if (NULL_INTERVAL_P (i))
return (force ? create_root_interval (object) : i);
-
+
return find_interval (i, searchpos);
}
}
#endif
\f
-/* Returns the interval of POSITION in OBJECT.
+/* Returns the interval of POSITION in OBJECT.
POSITION is BEG-based. */
INTERVAL
}
else
{
- register struct Lisp_String *s = XSTRING (object);
-
beg = 0;
- end = s->size;
- i = s->intervals;
+ end = SCHARS (object);
+ i = STRING_INTERVALS (object);
}
if (!(beg <= position && position <= end))
args_out_of_range (make_number (position), make_number (position));
if (beg == end || NULL_INTERVAL_P (i))
return NULL_INTERVAL;
-
+
return find_interval (i, position);
}
\f
DEFUN ("text-properties-at", Ftext_properties_at,
Stext_properties_at, 1, 2, 0,
doc: /* Return the list of properties of the character at POSITION in OBJECT.
-OBJECT is the string or buffer to look for the properties in;
-nil means the current buffer.
+If the optional second argument OBJECT is a buffer (or nil, which means
+the current buffer), POSITION is a buffer position (integer or marker).
+If OBJECT is a string, POSITION is a 0-based index into it.
If POSITION is at the end of OBJECT, the value is nil. */)
(position, object)
Lisp_Object position, object;
return textget (Ftext_properties_at (position, object), prop);
}
-/* Return the value of POSITION's property PROP, in OBJECT.
+/* Return the value of char's property PROP, in OBJECT at POSITION.
OBJECT is optional and defaults to the current buffer.
If OVERLAY is non-0, then in the case that the returned property is from
an overlay, the overlay found is returned in *OVERLAY, otherwise nil is
}
if (BUFFERP (object))
{
- int posn = XINT (position);
int noverlays;
- Lisp_Object *overlay_vec, tem;
- int next_overlay;
- int len;
+ Lisp_Object *overlay_vec;
struct buffer *obuf = current_buffer;
set_buffer_temp (XBUFFER (object));
- /* First try with room for 40 overlays. */
- len = 40;
- overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
-
- noverlays = overlays_at (posn, 0, &overlay_vec, &len,
- &next_overlay, NULL, 0);
-
- /* If there are more than 40,
- make enough space for all, and try again. */
- if (noverlays > len)
- {
- len = noverlays;
- overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
- noverlays = overlays_at (posn, 0, &overlay_vec, &len,
- &next_overlay, NULL, 0);
- }
+ GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, 0);
noverlays = sort_overlays (overlay_vec, noverlays, w);
set_buffer_temp (obuf);
/* Now check the overlays in order of decreasing priority. */
while (--noverlays >= 0)
{
- tem = Foverlay_get (overlay_vec[noverlays], prop);
+ Lisp_Object tem = Foverlay_get (overlay_vec[noverlays], prop);
if (!NILP (tem))
{
if (overlay)
{
return get_char_property_and_overlay (position, prop, object, 0);
}
+
+DEFUN ("get-char-property-and-overlay", Fget_char_property_and_overlay,
+ Sget_char_property_and_overlay, 2, 3, 0,
+ doc: /* Like `get-char-property', but with extra overlay information.
+Return a cons whose car is the return value of `get-char-property'
+with the same arguments, that is, the value of POSITION's property
+PROP in OBJECT, and whose cdr is the overlay in which the property was
+found, or nil, if it was found as a text property or not found at all.
+OBJECT is optional and defaults to the current buffer. OBJECT may be
+a string, a buffer or a window. For strings, the cdr of the return
+value is always nil, since strings do not have overlays. If OBJECT is
+a window, then that window's buffer is used, but window-specific
+overlays are considered only if they are associated with OBJECT. If
+POSITION is at the end of OBJECT, both car and cdr are nil. */)
+ (position, prop, object)
+ Lisp_Object position, object;
+ register Lisp_Object prop;
+{
+ Lisp_Object overlay;
+ Lisp_Object val
+ = get_char_property_and_overlay (position, prop, object, &overlay);
+ return Fcons(val, overlay);
+}
+
\f
DEFUN ("next-char-property-change", Fnext_char_property_change,
Snext_char_property_change, 1, 2, 0,
doc: /* Return the position of next text property or overlay change.
-This scans characters forward from POSITION till it finds a change in
-some text property, or the beginning or end of an overlay, and returns
-the position of that.
+This scans characters forward in the current buffer from POSITION till
+it finds a change in some text property, or the beginning or end of an
+overlay, and returns the position of that.
If none is found, the function returns (point-max).
If the optional third argument LIMIT is non-nil, don't search
DEFUN ("previous-char-property-change", Fprevious_char_property_change,
Sprevious_char_property_change, 1, 2, 0,
doc: /* Return the position of previous text property or overlay change.
-Scans characters backward from POSITION till it finds a change in some
-text property, or the beginning or end of an overlay, and returns the
-position of that.
+Scans characters backward in the current buffer from POSITION till it
+finds a change in some text property, or the beginning or end of an
+overlay, and returns the position of that.
If none is found, the function returns (point-max).
If the optional third argument LIMIT is non-nil, don't search
doc: /* Return the position of next text property or overlay change for a specific property.
Scans characters forward from POSITION till it finds
a change in the PROP property, then returns the position of the change.
-The optional third argument OBJECT is the string or buffer to scan.
+If the optional third argument OBJECT is a buffer (or nil, which means
+the current buffer), POSITION is a buffer position (integer or marker).
+If OBJECT is a string, POSITION is a 0-based index into it.
+
The property values are compared with `eq'.
If the property is constant all the way to the end of OBJECT, return the
last valid position in OBJECT.
if (! NILP (object))
CHECK_BUFFER (object);
-
+
if (BUFFERP (object) && current_buffer != XBUFFER (object))
{
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
}
initial_value = Fget_char_property (position, prop, object);
-
+
if (NILP (limit))
XSETFASTINT (limit, BUF_ZV (current_buffer));
else
doc: /* Return the position of previous text property or overlay change for a specific property.
Scans characters backward from POSITION till it finds
a change in the PROP property, then returns the position of the change.
-The optional third argument OBJECT is the string or buffer to scan.
+If the optional third argument OBJECT is a buffer (or nil, which means
+the current buffer), POSITION is a buffer position (integer or marker).
+If OBJECT is a string, POSITION is a 0-based index into it.
+
The property values are compared with `eq'.
If the property is constant all the way to the start of OBJECT, return the
first valid position in OBJECT.
if (! NILP (object))
CHECK_BUFFER (object);
-
+
if (BUFFERP (object) && current_buffer != XBUFFER (object))
{
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
Fset_buffer (object);
}
-
+
if (NILP (limit))
XSETFASTINT (limit, BUF_BEGV (current_buffer));
else
Lisp_Object initial_value =
Fget_char_property (make_number (XFASTINT (position) - 1),
prop, object);
-
+
for (;;)
{
position = Fprevious_char_property_change (position, limit);
doc: /* Return the position of next property change.
Scans characters forward from POSITION in OBJECT till it finds
a change in some text property, then returns the position of the change.
-The optional second argument OBJECT is the string or buffer to scan.
+If the optional second argument OBJECT is a buffer (or nil, which means
+the current buffer), POSITION is a buffer position (integer or marker).
+If OBJECT is a string, POSITION is a 0-based index into it.
Return nil if the property is constant all the way to the end of OBJECT.
If the value is non-nil, it is a position greater than POSITION, never equal.
next = i;
else
next = next_interval (i);
-
+
if (NULL_INTERVAL_P (next))
XSETFASTINT (position, (STRINGP (object)
? SCHARS (object)
doc: /* Return the position of next property change for a specific property.
Scans characters forward from POSITION till it finds
a change in the PROP property, then returns the position of the change.
-The optional third argument OBJECT is the string or buffer to scan.
+If the optional third argument OBJECT is a buffer (or nil, which means
+the current buffer), POSITION is a buffer position (integer or marker).
+If OBJECT is a string, POSITION is a 0-based index into it.
The property values are compared with `eq'.
Return nil if the property is constant all the way to the end of OBJECT.
If the value is non-nil, it is a position greater than POSITION, never equal.
here_val = textget (i->plist, prop);
next = next_interval (i);
- while (! NULL_INTERVAL_P (next)
+ while (! NULL_INTERVAL_P (next)
&& EQ (here_val, textget (next->plist, prop))
&& (NILP (limit) || next->position < XFASTINT (limit)))
next = next_interval (next);
doc: /* Return the position of previous property change.
Scans characters backwards from POSITION in OBJECT till it finds
a change in some text property, then returns the position of the change.
-The optional second argument OBJECT is the string or buffer to scan.
+If the optional second argument OBJECT is a buffer (or nil, which means
+the current buffer), POSITION is a buffer position (integer or marker).
+If OBJECT is a string, POSITION is a 0-based index into it.
Return nil if the property is constant all the way to the start of OBJECT.
If the value is non-nil, it is a position less than POSITION, never equal.
doc: /* Return the position of previous property change for a specific property.
Scans characters backward from POSITION till it finds
a change in the PROP property, then returns the position of the change.
-The optional third argument OBJECT is the string or buffer to scan.
+If the optional third argument OBJECT is a buffer (or nil, which means
+the current buffer), POSITION is a buffer position (integer or marker).
+If OBJECT is a string, POSITION is a 0-based index into it.
The property values are compared with `eq'.
Return nil if the property is constant all the way to the start of OBJECT.
If the value is non-nil, it is a position less than POSITION, never equal.
Sadd_text_properties, 3, 4, 0,
doc: /* Add properties to the text from START to END.
The third argument PROPERTIES is a property list
-specifying the property values to add.
-The optional fourth argument, OBJECT,
-is the string or buffer containing the text.
+specifying the property values to add. If the optional fourth argument
+OBJECT is a buffer (or nil, which means the current buffer),
+START and END are buffer positions (integers or markers).
+If OBJECT is a string, START and END are 0-based indices into it.
Return t if any property value actually changed, nil otherwise. */)
(start, end, properties, object)
Lisp_Object start, end, properties, object;
doc: /* Set one property of the text from START to END.
The third and fourth arguments PROPERTY and VALUE
specify the property to add.
-The optional fifth argument, OBJECT,
-is the string or buffer containing the text. */)
+If the optional fifth argument OBJECT is a buffer (or nil, which means
+the current buffer), START and END are buffer positions (integers or
+markers). If OBJECT is a string, START and END are 0-based indices into it. */)
(start, end, property, value, object)
Lisp_Object start, end, property, value, object;
{
Sset_text_properties, 3, 4, 0,
doc: /* Completely replace properties of text from START to END.
The third argument PROPERTIES is the new property list.
-The optional fourth argument, OBJECT,
-is the string or buffer containing the text.
-If OBJECT is omitted or nil, it defaults to the current buffer.
+If the optional fourth argument OBJECT is a buffer (or nil, which means
+the current buffer), START and END are buffer positions (integers or
+markers). If OBJECT is a string, START and END are 0-based indices into it.
If PROPERTIES is nil, the effect is to remove all properties from
the designated part of OBJECT. */)
(start, end, properties, object)
The third argument PROPERTIES is a property list
whose property names specify the properties to remove.
\(The values stored in PROPERTIES are ignored.)
-The optional fourth argument, OBJECT,
-is the string or buffer containing the text.
-Return t if any property was actually removed, nil otherwise. */)
+If the optional fourth argument OBJECT is a buffer (or nil, which means
+the current buffer), START and END are buffer positions (integers or
+markers). If OBJECT is a string, START and END are 0-based indices into it.
+Return t if any property was actually removed, nil otherwise.
+
+Use set-text-properties if you want to remove all text properties. */)
(start, end, properties, object)
Lisp_Object start, end, properties, object;
{
Sremove_list_of_text_properties, 3, 4, 0,
doc: /* Remove some properties from text from START to END.
The third argument LIST-OF-PROPERTIES is a list of property names to remove.
-The optional fourth argument, OBJECT,
-is the string or buffer containing the text, defaulting to the current buffer.
+If the optional fourth argument OBJECT is a buffer (or nil, which means
+the current buffer), START and END are buffer positions (integers or
+markers). If OBJECT is a string, START and END are 0-based indices into it.
Return t if any property was actually removed, nil otherwise. */)
(start, end, list_of_properties, object)
Lisp_Object start, end, list_of_properties, object;
doc: /* Check text from START to END for property PROPERTY equalling VALUE.
If so, return the position of the first character whose property PROPERTY
is `eq' to VALUE. Otherwise return nil.
-The optional fifth argument, OBJECT, is the string or buffer
-containing the text. */)
+If the optional fifth argument OBJECT is a buffer (or nil, which means
+the current buffer), START and END are buffer positions (integers or
+markers). If OBJECT is a string, START and END are 0-based indices into it. */)
(start, end, property, value, object)
Lisp_Object start, end, property, value, object;
{
doc: /* Check text from START to END for property PROPERTY not equalling VALUE.
If so, return the position of the first character whose property PROPERTY
is not `eq' to VALUE. Otherwise, return nil.
-The optional fifth argument, OBJECT, is the string or buffer
-containing the text. */)
+If the optional fifth argument OBJECT is a buffer (or nil, which means
+the current buffer), START and END are buffer positions (integers or
+markers). If OBJECT is a string, START and END are 0-based indices into it. */)
(start, end, property, value, object)
Lisp_Object start, end, property, value, object;
{
/* Return the direction from which the text-property PROP would be
inherited by any new text inserted at POS: 1 if it would be
inherited from the char after POS, -1 if it would be inherited from
- the char before POS, and 0 if from neither. */
+ the char before POS, and 0 if from neither.
+ BUFFER can be either a buffer or nil (meaning current buffer). */
int
-text_property_stickiness (prop, pos)
- Lisp_Object prop;
- Lisp_Object pos;
+text_property_stickiness (prop, pos, buffer)
+ Lisp_Object prop, pos, buffer;
{
Lisp_Object prev_pos, front_sticky;
int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */
- if (XINT (pos) > BEGV)
+ if (NILP (buffer))
+ XSETBUFFER (buffer, current_buffer);
+
+ if (XINT (pos) > BUF_BEGV (XBUFFER (buffer)))
/* Consider previous character. */
{
Lisp_Object rear_non_sticky;
prev_pos = make_number (XINT (pos) - 1);
- rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, Qnil);
+ rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, buffer);
if (!NILP (CONSP (rear_non_sticky)
? Fmemq (prop, rear_non_sticky)
}
/* Consider following character. */
- front_sticky = Fget_text_property (pos, Qfront_sticky, Qnil);
+ front_sticky = Fget_text_property (pos, Qfront_sticky, buffer);
if (EQ (front_sticky, Qt)
|| (CONSP (front_sticky)
disambiguate. Basically, rear-sticky wins, _except_ if the
property that would be inherited has a value of nil, in which case
front-sticky wins. */
- if (XINT (pos) == BEGV || NILP (Fget_text_property (prev_pos, prop, Qnil)))
+ if (XINT (pos) == BUF_BEGV (XBUFFER (buffer))
+ || NILP (Fget_text_property (prev_pos, prop, buffer)))
return 1;
else
return -1;
Lisp_Object result;
result = Qnil;
-
+
i = validate_interval_range (object, &start, &end, soft);
if (!NULL_INTERVAL_P (i))
{
int s = XINT (start);
int e = XINT (end);
-
+
while (s < e)
{
int interval_end, len;
Lisp_Object plist;
-
+
interval_end = i->position + LENGTH (i);
if (interval_end > e)
interval_end = e;
len = interval_end - s;
-
+
plist = i->plist;
if (!NILP (prop))
Fcons (make_number (s + len),
Fcons (plist, Qnil))),
result);
-
+
i = next_interval (i);
if (NULL_INTERVAL_P (i))
break;
s = i->position;
}
}
-
+
return result;
}
{
struct gcpro gcpro1, gcpro2;
int modified_p = 0;
-
+
GCPRO2 (list, object);
-
+
for (; CONSP (list); list = XCDR (list))
{
Lisp_Object item, start, end, plist, tem;
-
+
item = XCAR (list);
start = make_number (XINT (XCAR (item)) + XINT (delta));
end = make_number (XINT (XCAR (XCDR (item))) + XINT (delta));
plist = XCAR (XCDR (XCDR (item)));
-
+
tem = Fadd_text_properties (start, end, plist, object);
if (!NILP (tem))
modified_p = 1;
for (; CONSP (list); list = XCDR (list))
{
Lisp_Object item, end;
-
+
item = XCAR (list);
end = XCAR (XCDR (item));
if (! NULL_INTERVAL_P (i))
{
after = textget (i->plist, Qread_only);
-
+
/* If interval I is read-only and read-only is
front-sticky, inhibit insertion.
Check for read-only as well as category. */
if (TMEM (Qread_only, tem)
|| (NILP (Fplist_get (i->plist, Qread_only))
&& TMEM (Qcategory, tem)))
- text_read_only ();
+ text_read_only (after);
}
}
if (! NULL_INTERVAL_P (prev))
{
before = textget (prev->plist, Qread_only);
-
+
/* If interval PREV is read-only and read-only isn't
rear-nonsticky, inhibit insertion.
Check for read-only as well as category. */
if (! TMEM (Qread_only, tem)
&& (! NILP (Fplist_get (prev->plist,Qread_only))
|| ! TMEM (Qcategory, tem)))
- text_read_only ();
+ text_read_only (before);
}
}
}
else if (! NULL_INTERVAL_P (i))
{
after = textget (i->plist, Qread_only);
-
+
/* If interval I is read-only and read-only is
front-sticky, inhibit insertion.
Check for read-only as well as category. */
if (TMEM (Qread_only, tem)
|| (NILP (Fplist_get (i->plist, Qread_only))
&& TMEM (Qcategory, tem)))
- text_read_only ();
+ text_read_only (after);
tem = textget (prev->plist, Qrear_nonsticky);
if (! TMEM (Qread_only, tem)
&& (! NILP (Fplist_get (prev->plist, Qread_only))
|| ! TMEM (Qcategory, tem)))
- text_read_only ();
+ text_read_only (after);
}
}
}
do
{
if (! INTERVAL_WRITABLE_P (i))
- text_read_only ();
+ text_read_only (textget (i->plist, Qread_only));
if (!inhibit_modification_hooks)
{
the character doesn't inherit PROPERTY if NONSTICKINESS is non-nil,
inherits it if NONSTICKINESS is nil. The front-sticky and
rear-nonsticky properties of the character overrides NONSTICKINESS. */);
- Vtext_property_default_nonsticky = Qnil;
+ /* Text property `syntax-table' should be nonsticky by default. */
+ Vtext_property_default_nonsticky
+ = Fcons (Fcons (intern ("syntax-table"), Qt), Qnil);
staticpro (&interval_insert_behind_hooks);
staticpro (&interval_insert_in_front_hooks);
interval_insert_behind_hooks = Qnil;
interval_insert_in_front_hooks = Qnil;
-
+
/* Common attributes one might give text */
staticpro (&Qforeground);
defsubr (&Stext_properties_at);
defsubr (&Sget_text_property);
defsubr (&Sget_char_property);
+ defsubr (&Sget_char_property_and_overlay);
defsubr (&Snext_char_property_change);
defsubr (&Sprevious_char_property_change);
defsubr (&Snext_single_char_property_change);
/* defsubr (&Scopy_text_properties); */
}
+/* arch-tag: 454cdde8-5f86-4faa-a078-101e3625d479
+ (do not change this comment) */