elisp: Changing Properties

 
 31.19.2 Changing Text Properties
 --------------------------------
 
 The primitives for changing properties apply to a specified range of
 text in a buffer or string.  The function ‘set-text-properties’ (see end
 of section) sets the entire property list of the text in that range;
 more often, it is useful to add, change, or delete just certain
 properties specified by name.
 
    Since text properties are considered part of the contents of the
 buffer (or string), and can affect how a buffer looks on the screen, any
 change in buffer text properties marks the buffer as modified.  Buffer
 text property changes are undoable also (SeeUndo).  Positions in a
 string start from 0, whereas positions in a buffer start from 1.
 
  -- Function: put-text-property start end prop value &optional object
      This function sets the PROP property to VALUE for the text between
      START and END in the string or buffer OBJECT.  If OBJECT is ‘nil’,
      it defaults to the current buffer.
 
  -- Function: add-text-properties start end props &optional object
      This function adds or overrides text properties for the text
      between START and END in the string or buffer OBJECT.  If OBJECT is
      ‘nil’, it defaults to the current buffer.
 
      The argument PROPS specifies which properties to add.  It should
      have the form of a property list (SeeProperty Lists): a list
      whose elements include the property names followed alternately by
      the corresponding values.
 
      The return value is ‘t’ if the function actually changed some
      property’s value; ‘nil’ otherwise (if PROPS is ‘nil’ or its values
      agree with those in the text).
 
      For example, here is how to set the ‘comment’ and ‘face’ properties
      of a range of text:
 
           (add-text-properties START END
                                '(comment t face highlight))
 
  -- Function: remove-text-properties start end props &optional object
      This function deletes specified text properties from the text
      between START and END in the string or buffer OBJECT.  If OBJECT is
      ‘nil’, it defaults to the current buffer.
 
      The argument PROPS specifies which properties to delete.  It should
      have the form of a property list (SeeProperty Lists): a list
      whose elements are property names alternating with corresponding
      values.  But only the names matter—the values that accompany them
      are ignored.  For example, here’s how to remove the ‘face’
      property.
 
           (remove-text-properties START END '(face nil))
 
      The return value is ‘t’ if the function actually changed some
      property’s value; ‘nil’ otherwise (if PROPS is ‘nil’ or if no
      character in the specified text had any of those properties).
 
      To remove all text properties from certain text, use
      ‘set-text-properties’ and specify ‘nil’ for the new property list.
 
  -- Function: remove-list-of-text-properties start end
           list-of-properties &optional object
      Like ‘remove-text-properties’ except that LIST-OF-PROPERTIES is a
      list of property names only, not an alternating list of property
      names and values.
 
  -- Function: set-text-properties start end props &optional object
      This function completely replaces the text property list for the
      text between START and END in the string or buffer OBJECT.  If
      OBJECT is ‘nil’, it defaults to the current buffer.
 
      The argument PROPS is the new property list.  It should be a list
      whose elements are property names alternating with corresponding
      values.
 
      After ‘set-text-properties’ returns, all the characters in the
      specified range have identical properties.
 
      If PROPS is ‘nil’, the effect is to get rid of all properties from
      the specified range of text.  Here’s an example:
 
           (set-text-properties START END nil)
 
      Do not rely on the return value of this function.
 
  -- Function: add-face-text-property start end face &optional appendp
           object
      This function acts on the text between START and END, adding the
      face FACE to the ‘face’ text property.  FACE should be a valid
      value for the ‘face’ property (SeeSpecial Properties), such as
      a face name or an anonymous face (SeeFaces).
 
      If any text in the region already has a non-‘nil’ ‘face’ property,
      those face(s) are retained.  This function sets the ‘face’ property
      to a list of faces, with FACE as the first element (by default) and
      the pre-existing faces as the remaining elements.  If the optional
      argument APPEND is non-‘nil’, FACE is appended to the end of the
      list instead.  Note that in a face list, the first occurring value
      for each attribute takes precedence.
 
      For example, the following code would assign a italicized green
      face to the text between START and END:
 
           (add-face-text-property START END 'italic)
           (add-face-text-property START END '(:foreground "red"))
           (add-face-text-property START END '(:foreground "green"))
 
      The optional argument OBJECT, if non-‘nil’, specifies a buffer or
      string to act on, rather than the current buffer.  If OBJECT is a
      string, then START and END are zero-based indices into the string.
 
    The easiest way to make a string with text properties is with
 ‘propertize’:
 
  -- Function: propertize string &rest properties
      This function returns a copy of STRING with the text properties
      PROPERTIES added.  These properties apply to all the characters in
      the string that is returned.  Here is an example that constructs a
      string with a ‘face’ property and a ‘mouse-face’ property:
 
           (propertize "foo" 'face 'italic
                       'mouse-face 'bold-italic)
                ⇒ #("foo" 0 3 (mouse-face bold-italic face italic))
 
      To put different properties on various parts of a string, you can
      construct each part with ‘propertize’ and then combine them with
      ‘concat’:
 
           (concat
            (propertize "foo" 'face 'italic
                        'mouse-face 'bold-italic)
            " and "
            (propertize "bar" 'face 'italic
                        'mouse-face 'bold-italic))
                ⇒ #("foo and bar"
                            0 3 (face italic mouse-face bold-italic)
                            3 8 nil
                            8 11 (face italic mouse-face bold-italic))
 
    SeeBuffer Contents, for the function
 ‘buffer-substring-no-properties’, which copies text from the buffer but
 does not copy its properties.
 
    If you wish to add or remove text properties to a buffer without
 marking the buffer as modified, you can wrap the calls above in the
 ‘with-silent-modifications’ macro.