Each character in a buffer or a string can have a text property list, much like the property list of a symbol. The properties belong to a particular character at a particular place, such as, the letter `T' at the beginning of this sentence. Each property has a name, which is usually a symbol, and an associated value, which can be any Lisp object--just as for properties of symbols.
You can use the property face
to control the font and
color of text. Several other property names have special meanings. You
can create properties of any name and examine them later for your own
purposes.
Copying text between strings and buffers preserves the properties
along with the characters; this includes such diverse functions as
substring
, insert
, and buffer-substring
.
Since text properties are considered part of the buffer contents, changing properties in a buffer "modifies" the buffer, and you can also undo such changes.
Strings with text properties have a special printed representation which describes all the properties. This representation is also the read syntax for such a string. It looks like this:
#("characters" property-data...)
where property-data is zero or more elements in groups of three as follows:
beg end plist
The elements beg and end are integers, and together specify a portion of the string; plist is the property list for that portion.
The simplest way to examine text properties is to ask for the value of
a particular property of a particular character. For that, use
get-text-property
. Use text-properties-at
to get the
entire property list of a character.
(get-text-property pos prop object)
returns the
prop property of the character after pos in object (a
buffer or string). The argument object is optional and defaults
to the current buffer.
(text-properties-at pos object)
returns the entire
property list of the character after pos in the string or buffer
object (which defaults to the current buffer).
There are four primitives for changing properties of a specified range of text:
add-text-properties
put-text-property
remove-text-properties
set-text-properties
All these functions take four arguments: start, end, props, and object. The last argument is optional and defaults to the current buffer. The argument props has the form of a property list.
In typical use of text properties, most of the time several or many consecutive characters have the same value for a property. Rather than writing your programs to examine characters one by one, it is much faster to process chunks of text that have the same property value.
The functions next-property-change
and
previous-property-change
scan forward or backward from position
pos in object, looking for a change in any property between
two characters scanned. They returns the position between those two
characters, or nil
if no change is found.
The functions next-single-property-change
and
previous-single-property-change
are similar except that you
specify a particular property and they look for changes in the value of
that property only. The property is the second argument, and
object is third.
If a character has a category
property, we call it the
category of the character. It should be a symbol. The properties
of the symbol serve as defaults for the properties of the character.
You can use the property face
to control the font and
color of text.
You can specify a different keymap for a portion of the text by means
of a local-map
property. The property's value, for the character
after point, replaces the buffer's local map.
If a character has the property read-only
, then modifying that
character is not allowed. Any command that would do so gets an error.
If a character has the property modification-hooks
, then its
value should be a list of functions; modifying that character calls all
of those functions. Each function receives two arguments: the beginning
and end of the part of the buffer being modified. Note that if a
particular modification hook function appears on several characters
being modified by a single primitive, you can't predict how many times
the function will be called.
Insertion of text does not, strictly speaking, change any existing
character, so there is a special rule for insertion. It compares the
read-only
properties of the two surrounding characters; if they
are eq
, then the insertion is not allowed. Assuming insertion is
allowed, it then gets the modification-hooks
properties of those
characters and calls all the functions in each of them. (If a function
appears on both characters, it may be called once or twice.)
The special properties point-entered
and point-left
record hook functions that report motion of point. Each time point
moves, Emacs compares these two property values:
point-left
property of the character after the old location,
and
point-entered
property of the character after the new
location.
If these two values differ, each of them is called (if not nil
)
with two arguments: the old value of point, and the new one.
The same comparison is made for the characters before the old and new
locations. The result may be to execute two point-left
functions
(which may be the same function) and/or two point-entered
functions (which may be the same function). The point-left
functions are always called before the point-entered
functions.
A primitive function may examine characters at various positions without moving point to those positions. Only an actual change in the value of point runs these hook functions.