9. Character Attributes
Character attributes provide a global database of information about characters. This facility is similar to, but more general than, the syntax tables of other editors such as Emacs. For example, you should use character attributes for commands that need information regarding whether a character is whitespace or not. Use character attributes for these reasons:
- If this information is all in one place, then it is easy the change the behavior of the editor by changing the syntax table, much easier than it would be if character constants were wired into commands.
- This centralization of information avoids needless duplication of effort.
- The syntax table primitives are probably faster than anything that can be written above the primitive level.
Note that an essential part of the character attribute scheme is that character attributes are global and are there for the user to change. Information about characters which is internal to some set of commands (and which the user should not know about) should not be maintained as a character attribute. For such uses various character searching abilities are provided by the function find-pattern (page 20).
9.2. Character Attribute Names
As for Hemlock variables, character attributes have a user visible string name, but are referred to in Lisp code as a symbol. The string name, which is typically composed of capitalized words separated by spaces, is translated into a keyword by replacing all spaces with hyphens and interning this string in the keyword package. The attribute named "Ada Syntax" would thus become :ada-syntax.
Whenever a character attribute is defined, its name is entered in this string table (page 69), with the corresponding keyword as the value.
9.3. Character Attribute Functions
defattribute name documentation &optional type initial-value [Function]
This function defines a new character attribute with name, a string. Character attribute operations take attribute arguments as a keyword whose name is name uppercased with spaces replaced by hyphens.
Documentation describes the uses of the character attribute.
Type, which defaults to (mod 2), specifies what type the values of the character attribute are. Values of a character attribute may be of any type which may be specified to make-array. Initial-value (default 0) is the value which all characters will initially have for this attribute.
character-attribute-name attribute [Function]
character-attribute-documentation attribute [Function]
These functions return the name or documentation for attribute.
character-attribute attribute character [Function]
Character Attribute Hook [Hemlock Variable]
character-attribute returns the value of attribute for character. This signals an error if attribute is undefined.
setf will set a character's attributes. This setf method invokes the functions in Character Attribute Hook on the attribute and character before it makes the change.
If character is nil, then the value of the attribute for the beginning or end of the buffer can be accessed or set. The buffer beginning and end thus become a sort of fictitious character, which simplifies the use of character attributes in many cases.
character-attribute-p symbol [Function]
This function returns t if symbolis the name of a character attribute, nil otherwise.
shadow-attribute attribute character value mode [Function]
Shadow Attribute Hook [Hemlock Variable]
This function establishes value as the value of character's attribute attribute when in the mode mode. Mode must be the name of a major mode. Shadow Attribute Hook is invoked with the same arguments when this function is called. If the value for an attribute is set while the value is shadowed, then only the shadowed value is affected, not the global one.
unshadow-attribute attribute character mode [Function]
Unshadow Attribute Hook [Hemlock Variable]
Make the value of attribute for character no longer be shadowed in mode. Unshadow Attribute Hook is invoked with the same arguments when this function is called.
find-attribute mark attribute &optional test [Function]
reverse-find-attribute mark attribute &optional test [Function]
These functions find the next (or previous) character with some value for the character attribute attribute starting at mark. They pass test one argument, the value of attribute for the character tested. If the test succeeds, then these routines modify mark to point before (after for reverse-find-attribute) the character which satisfied the test. If no characters satisfy the test, then these return nil, and mark remains unmodified. Test defaults to #'not-zerop. There is no guarantee that the test is applied in any particular fashion, so it should have no side effects and depend only on its argument.
find-not-attribute mark attribute [Function]
reverse-find-not-attribute mark attribute [Function]
These are equivalent to (find-attribute mark attribute #'zerop) and (reverse-find-attribute mark attribute #'zerop), respectively.
9.4. Character Attribute Hooks
It is often useful to use the character attribute mechanism as an abstract interface to other information about characters which in fact is stored elsewhere. For example, some implementation of Hemlock might decide to define a Print Representation attribute which controls how a character is displayed on an output device.
To make this easy to do, each attribute has a list of hook functions which are invoked with the attribute, character and new value whenever the current value changes for any reason.
character-attribute-hooks attribute [Function]
Return the current hook list for attribute. This may be set with setf. The add-hook and remove-hook (page 25) macros should be used to manipulate these lists.
9.5. System Defined Character Attributes
These are predefined in Hemlock:
- A value of 1 indicates the character is whitespace.
- "Word Delimiter"
- A value of 1 indicates the character separates words (see section 15.3).
- This is like Whitespace, but it should not include Newline. Hemlock uses this primarily for handling indentation on a line.
- "Sentence Terminator"
- A value of 1 indicates these characters terminate sentences (see section 15.3).
- "Sentence Closing Char"
- A value of 1 indicates these delimiting characters, such as " or ), may follow a Sentence Terminator (see section 15.3).
- "Paragraph Delimiter"
- A value of 1 indicates these characters delimit paragraphs when they begin a line (see section 15.3).
- "Page Delimiter"
- A value of 1 indicates this character separates logical pages (see section 15.4) when it begins a line.
- "Lisp Syntax"
- This uses symbol values from the following:
- nil These characters have no interesting properties.
- :space These characters act like whitespace and should not include Newline.
- :newline This is the Newline character.
- :open-paren This is ( character.
- :close-paren This is ) character.
- :prefix This is a character that is a part of any form it precedes for example, the single quote, '.
- :string-quote This is the character that quotes a string literal, ".
- :char-quote This is the character that escapes a single character, \.
- :comment This is the character that makes a comment with the rest of the line,;.
- :constituent These characters are constitute symbol names.