Function: remove-text-properties
remove-text-properties is a function defined in textprop.c.
Signature
(remove-text-properties START END PROPERTIES &optional OBJECT)
Documentation
Remove some properties from text from START to END.
The third argument PROPERTIES is a property list
whose property names specify the properties to remove.
(The values stored in PROPERTIES are ignored.)
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.
Other relevant functions are documented in the text-properties group.
Probably introduced at or before Emacs version 22.1.
Shortdoc
;; text-properties
(remove-text-properties (point) (1+ (point)) '(face nil))
Source Code
// Defined in /usr/src/emacs/src/textprop.c
{
/* Ensure we run the modification hooks for the right buffer,
without switching buffers twice (bug 36190). FIXME: Switching
buffers is slow and often unnecessary. */
if (BUFFERP (object) && XBUFFER (object) != current_buffer)
{
specpdl_ref count = SPECPDL_INDEX ();
record_unwind_current_buffer ();
set_buffer_internal (XBUFFER (object));
return unbind_to (count,
Fremove_text_properties (start, end, properties,
object));
}
INTERVAL i, unchanged;
ptrdiff_t s, len;
bool modified = false;
bool first_time = true;
if (NILP (object))
XSETBUFFER (object, current_buffer);
retry:
i = validate_interval_range (object, &start, &end, soft);
if (!i)
return Qnil;
s = XFIXNUM (start);
len = XFIXNUM (end) - s;
/* If there are no properties on this entire interval, return. */
if (! interval_has_some_properties (properties, i))
{
ptrdiff_t got = LENGTH (i) - (s - i->position);
do
{
if (got >= len)
return Qnil;
len -= got;
i = next_interval (i);
got = LENGTH (i);
}
while (! interval_has_some_properties (properties, i));
}
/* Split away the beginning of this interval; what we don't
want to modify. */
else if (i->position != s)
{
unchanged = i;
i = split_interval_right (unchanged, s - unchanged->position);
copy_properties (unchanged, i);
}
if (BUFFERP (object) && first_time)
{
ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
ptrdiff_t prev_pos = i->position;
modify_text_properties (object, start, end);
/* If someone called us recursively as a side effect of
modify_text_properties, and changed the intervals behind our back
(could happen if lock_file, called by prepare_to_modify_buffer,
triggers redisplay, and that calls add-text-properties again
in the same buffer), we cannot continue with I, because its
data changed. So we restart the interval analysis anew. */
if (TOTAL_LENGTH (i) != prev_total_length
|| i->position != prev_pos)
{
first_time = false;
goto retry;
}
}
/* We are at the beginning of an interval, with len to scan */
for (;;)
{
eassert (i != 0);
if (LENGTH (i) >= len)
{
if (! interval_has_some_properties (properties, i))
{
eassert (modified);
if (BUFFERP (object))
signal_after_change (XFIXNUM (start), XFIXNUM (end) - XFIXNUM (start),
XFIXNUM (end) - XFIXNUM (start));
return Qt;
}
if (LENGTH (i) == len)
{
remove_properties (properties, Qnil, i, object);
if (BUFFERP (object))
signal_after_change (XFIXNUM (start), XFIXNUM (end) - XFIXNUM (start),
XFIXNUM (end) - XFIXNUM (start));
return Qt;
}
/* i has the properties, and goes past the change limit */
unchanged = i;
i = split_interval_left (i, len);
copy_properties (unchanged, i);
remove_properties (properties, Qnil, i, object);
if (BUFFERP (object))
signal_after_change (XFIXNUM (start), XFIXNUM (end) - XFIXNUM (start),
XFIXNUM (end) - XFIXNUM (start));
return Qt;
}
len -= LENGTH (i);
modified |= remove_properties (properties, Qnil, i, object);
i = next_interval (i);
}
}