# Hemlock Programming

## Introduction

Hemlock is the text editor used in &CCL;. It was originally based on the CMU Hemlock editor, but has since diverged from it in various ways. We continue to call the editor part of our IDE `Hemlock` to give credit where credit is due, but we make no attempt at source or API compatibility with the original Hemlock.

Like the code, this documentation is based on the original Hemlock documentation, modified as necessary.

Hemlock follows in the tradition of Emacs-compatible editors, with a rich set of extensible commands. This document describes the API for implementing new commands. The basic editor consists of a set of Lisp utility functions for manipulating buffers and the other data structures of the editor. All user level commands are written in terms of these functions. To find out how to define commands see Commands.

## Representation of Text

In Hemlock, text is represented as a sequence of lines. Newline characters are never stored but are implicit between lines. The implicit newline character is treated as the single character `#\Newline` by the text primitives.

Text is broken into lines when it is first introduced into Hemlock. Text enters Hemlock from the outside world in two ways: reading a file, or pasting text from the system clipboard. Hemlock uses heuristics (which should be documented here!) to decide what newline convention to use to convert the incoming text into its internal representation as a sequence of lines. Similarly it uses heuristics (which should be documented here!) to convert the internal representation into a string with embedded newlines in order to write a file or paste a region into the clipboard.

### Lines

A `line` is an object representing a sequence of characters with no line breaks.

#### linep

Function

                            linep line

##### Description

This function returns t if line is a line object, otherwise nil.

#### line-string

Function

                            line-string line

##### Description

Given a line, this function returns as a simple string the characters in the line. This is setf'able to set the line-string to any string that does not contain newline characters. It is an error to destructively modify the result of line-string or to destructively modify any string after the line-string of some line has been set to that string.

#### line-previous

Function

                            line-previous line

##### Description

#### line-next

Function

                            line-next line

##### Description

Given a line, line-previous returns the previous line or nil if there is no previous line. Similarly, line-next returns the line following line or nil.

#### line-buffer

Function

                            line-buffer line

##### Description

This function returns the buffer which contains this line. Since a line may not be associated with any buffer, in which case line-buffer returns nil.

#### line-length

Function

                            line-length line

##### Description

This function returns the number of characters in the line. This excludes the newline character at the end.

#### line-character

Function

                            line-character line index

##### Description

This function returns the character at position index within line. It is an error for index to be greater than the length of the line or less than zero. If index is equal to the length of the line, this returns a #\newline character.

#### line-plist

Function

                            line-plist line

##### Description

This function returns the property-list for line. setf, getf, putf and remf can be used to change properties. This is typically used in conjunction with line-signature to cache information about the line's contents.

#### line-signature

Function

                            line-signature line

##### Description

This function returns an object that serves as a signature for a line's contents. It is guaranteed that any modification of text on the line will result in the signature changing so that it is not eql to any previous value. The signature may change even when the text remains unmodified, but this does not happen often.

### Marks

A `mark` indicates a specific position within the text represented by a line and a character position within that line. Although a mark is sometimes loosely referred to as pointing to some character, it in fact points between characters. If the charpos is zero, the previous character is the newline character separating the previous line from the mark's line. If the charpos is equal to the number of characters in the line, the next character is the newline character separating the current line from the next. If the mark's line has no previous line, a mark with charpos of zero has no previous character; if the mark's line has no next line, a mark with charpos equal to the length of the line has no next character.

This section discusses the very basic operations involving marks, but a lot of Hemlock programming is built on altering some text at a mark. For more extended uses of marks see Altering And Searching Text.

#### Kinds of Marks

A mark may have one of two lifetimes: temporary or permanent. Permanent marks remain valid after arbitrary operations on the text; temporary marks do not. Temporary marks are used because less bookkeeping overhead is involved in their creation and use. If a temporary mark is used after the text it points to has been modified results will be unpredictable. Permanent marks continue to point between the same two characters regardless of insertions and deletions made before or after them.

There are two different kinds of permanent marks which differ only in their behavior when text is inserted at the position of the mark; text is inserted to the left of a left-inserting mark and to the right of right-inserting mark.

#### Mark Functions

##### markp

Function

                                markp mark

###### Description

This function returns t if mark is a mark object, otherwise nil.

##### mark-line

Function

                                mark-line mark

###### Description

This function returns the line to which mark points.

##### mark-charpos

Function

                                mark-charpos mark

###### Description

This function returns the character position in the line of the character after mark, i.e. the number of characters before the mark in the mark's line.

##### mark-buffer

Function

                                mark-buffer mark

###### Description

Returns the buffer containing this mark.

##### mark-absolute-position

Function

                                mark-absolute-position mark

###### Description

This function returns the character position in the buffer of the character after the mark, i.e. the number of characters before the mark in the mark's buffer.

##### mark-kind

Function

                                mark-kind mark

###### Description

This function returns one of `:right-inserting`, `:left-inserting` or `:temporary` depending on the mark's kind. A corresponding setf form changes the mark's kind.

##### previous-character

Function

                                previous-character mark

###### Description

##### next-character

Function

                                next-character mark

###### Description

This function returns the character immediately before (after) the position of the mark, or nil if there is no previous (next) character. These characters may be set with setf when they exist; the setf methods for these forms signal errors when there is no previous or next character.

#### Making Marks

##### mark

Function

                                mark line charpos &optional; kind

###### Description

This function returns a mark object that points to the charpos'th character of the line. Kind is the kind of mark to create, one of `:temporary`, `:left-inserting`, or `:right-inserting`. The default is :temporary.

##### copy-mark

Function

                                copy-mark mark &optional; kind

###### Description

This function returns a new mark pointing to the same position and of the same kind, or of kind kind if it is supplied.

##### delete-mark

Function

                                delete-mark mark

###### Description

This function deletes mark. Delete any permanent marks when you are finished using it.

##### with-mark

Macro

                                with-mark ({(mark pos [kind])}*) {form}*

###### Description

This macro binds to each variable mark a mark of kind kind, which defaults to `:temporary`, pointing to the same position as the markpos. On exit from the scope the mark is deleted. The value of the last form is the value returned.

#### Moving Marks

These functions destructively modify marks to point to new positions. Other sections of this document describe mark moving routines specific to higher level text forms than characters and lines, such as words, sentences, paragraphs, Lisp forms, etc.

##### move-to-position

Function

                                move-to-position mark charpos &optional; line

###### Description

This function changes the mark to point to the given character position on the line line. Line defaults to mark's line.

##### move-to-absolute-position

Function

                                move-to-absolute-position mark position

###### Description

This function changes the mark to point to the given character position in the buffer.

##### move-mark

Function

                                move-mark mark new-position

###### Description

This function moves mark to the same position as the mark new-position and returns it.

##### line-start

Function

                                line-start mark &optional; line

###### Description

##### line-end

Function

                                line-end mark &optional; line

###### Description

This function changes mark to point to the beginning or the end of line and returns it. Line defaults to mark's line.

##### buffer-start

Function

                                buffer-start mark &optional; buffer

###### Description

##### buffer-end

Function

                                buffer-end mark &optional; buffer

###### Description

These functions change mark to point to the beginning or end of buffer, which defaults to the buffer mark currently points into. If buffer is unsupplied, then it is an error for mark to be disassociated from any buffer.

##### mark-before

Function

                                mark-before mark

###### Description

##### mark-after

Function

                                mark-after mark

###### Description

These functions change mark to point one character before or after the current position. If there is no character before/after the current position, then they return nil and leave mark unmodified.

##### character-offset

Function

                                character-offset mark n

###### Description

This function changes mark to point n characters after (n before if n is negative) the current position. If there are less than n characters after (before) the mark, then this returns nil and mark is unmodified.

##### line-offset

Function

                                line-offset mark n &optional; charpos

###### Description

This function changes mark to point n lines after (n before if n is negative) the current position. The character position of the resulting mark is (min (line-length resulting-line) (mark-charpos mark)) if charpos is unspecified, or (min (line-length resulting-line) charpos) if it is. As with character-offset, if there are not n lines then nil is returned and mark is not modified.

### Regions

A `region` is simply a pair of marks: a starting mark and an ending mark. The text in a region consists of the characters following the starting mark and preceding the ending mark (keep in mind that a mark points between characters on a line, not at them). By modifying the starting or ending mark in a region it is possible to produce regions with a start and end which are out of order or even in different buffers. The use of such regions is undefined and may result in arbitrarily bad behavior.

#### Region Functions

##### region

Function

                                region start end

###### Description

This function returns a region constructed from the marks start and end. It is an error for the marks to point to non-contiguous lines or for start to come after end.

##### regionp

Function

                                regionp region

###### Description

This function returns t if region is a region object, otherwise nil.

##### make-empty-region

Function

                                make-empty-region

###### Description

This function returns a region with start and end marks pointing to the start of one empty line. The start mark is a `:right-inserting` mark, and the end is a `:left-inserting` mark.

##### copy-region

Function

                                copy-region region

###### Description

This function returns a region containing a copy of the text in the specified region. The resulting region is completely disjoint from region with respect to data references --- marks, lines, text, etc.

##### region-to-string

Function

                                region-to-string region

###### Description

##### string-to-region

Function

                                string-to-region string

###### Description

These functions coerce regions to Lisp strings and vice versa. Within the string, lines are delimited by newline characters.

##### line-to-region

Function

                                line-to-region line

###### Description

This function returns a region containing all the characters on line. The first mark is `:right-inserting` and the last is `:left-inserting`.

##### region-start

Function

                                region-start region

###### Description

##### region-end

Function

                                region-end region

###### Description

This function returns the start or end mark of region.

##### region-bounds

Function

                                region-bounds region

###### Description

This function returns as multiple-values the starting and ending marks of region.

##### set-region-bounds

Function

                                set-region-bounds region start end

###### Description

This function sets the start and end of region to start and end. It is an error for start to be after or in a different buffer from end.

##### count-lines

Function

                                count-lines region

###### Description

This function returns the number of lines in the region, first and last lines inclusive. A newline is associated with the line it follows, thus a region containing some number of non-newline characters followed by one newline is one line, but if a newline were added at the beginning, it would be two lines.

##### count-characters

Function

                                count-characters region

###### Description

This function returns the number of characters in a given region. This counts line breaks as one character.

## Buffers

A buffer is an object consisting of:

1. A name.

2. A piece of text.

3. The insertion point.

4. An associated file (optional).

5. A write protect flag.

6. Some variables.

7. Some key bindings.

8. A collection of modes.

9. A list of modeline fields (optional).

Because of the way Hemlock is currently integrated in Cocoa, all modifications to buffer contents must take place in the GUI thread. Hemlock commands always run in the GUI thread, so most of the time you do not need to worry about it. If you are running code in another thread that needs to modify a buffer, you should perform that action using `gui::execute-in-gui` or `gui::queue-for-gui`.

There are no intrinsic limitations on examining buffers from any thread, however, Hemlock currently does no locking, so you risk seeing the buffer in an inconsistent state if you look at it outside the GUI thread.

### The Current Buffer

Hemlock has the concept of the "current buffer". The current buffer is defined during Hemlock commands as the buffer of the hemlock view that received the key events that invoked the command. Many hemlock function operate on the current buffer rather than taking an explicit buffer argument. In effect, the current buffer is an implicit argument to many text manipulation functions.

#### current-buffer

Function

                            current-buffer

##### Description

Returns the current buffer, which, during command execution, is the buffer that is the target of the command.

#### current-point

Function

                            current-point

##### Description

This function returns the buffer-point of the current buffer . This is such a common idiom in commands that it is defined despite its trivial implementation.

#### current-point-collapsing-selection

Function

                            current-point-collapsing-selection

##### Description

This function returns the buffer-point of the current buffer, after first deactivating any active region.

#### current-point-extending-selection

Function

                            current-point-extending-selection

##### Description

This function returns the buffer-point of the current buffer, after first making sure there is an active region - if the region is already active, keeps it active, otherwise it establishes a new (empty) region at point.

#### current-point-for-insertion

Function

                            current-point-for-insertion

##### Description

This function checks to see if the current buffer can be modified at its current point, and errors if not. Otherwise, it deletes the current selection if any, and returns the current point.

#### current-point-for-deletion

Function

                            current-point-for-deletion

##### Description

This function checks to see if the current buffer can be modified at its current point and errors if not. Otherwise, if there is a section in the current buffer, it deletes it and returns NIL. If there is no selection, it returns the current point.

#### current-point-unless-selection

Function

                            current-point-unless-selection

##### Description

This function checks to see if the current buffer can be modified at its current point and errors if not. Otherwise, if there's a selection in the current buffer, returns NIL. If there is no selection, it returns the current point.

#### current-mark

Function

                            current-mark

##### Description

This function returns the top of the current buffer's mark stack. There always is at least one mark at the beginning of the buffer's region, and all marks returned are right-inserting.

#### pop-buffer-mark

Function

                            pop-buffer-mark

##### Description

This function pops the current buffer's mark stack, returning the mark. If the stack becomes empty, this pushes a new mark on the stack pointing to the buffer's start. This always deactivates the current region (see Active Regions).

#### push-buffer-mark

Function

                            push-buffer-mark mark &optional; activate-region

##### Description

This function pushes mark into the current buffer's mark stack, ensuring that the mark is right-inserting. If mark does not point into the current buffer, this signals an error. Optionally, the current region is made active, but this never deactivates the current region (see Active Regions). Mark is returned.

#### push-new-buffer-mark

Function

                            push-new-buffer-mark mark &optional; activate-region

##### Description

This function pushes a new mark onto the mark stack, at the position of `mark`. It's equivalent to calling `push-buffer-mark` on `(copy-mark mark)`.

#### all-buffers

Function

                            all-buffers

##### Description

This function returns a list of all the buffer objects made with make-buffer.

#### *buffer-names*

Variable

                            *buffer-names*

##### Description

This variable holds a string-table mapping the name of a buffer to the corresponding buffer object.

### Buffer Functions

#### make-buffer

Function

                            make-buffer  name &key; :modes :modeline-fields :delete-hook

##### Description

#### Default Modeline Fields

Hemlock Variable

                            Default Modeline Fields

##### Description

#### Make Buffer Hook

Hemlock Variable

                            Make Buffer Hook

##### Description

make-buffer creates and returns a buffer with the given name. If a buffer named name already exists, nil is returned. Modes is a list of modes which should be in effect in the buffer, major mode first, followed by any minor modes. If this is omitted then the buffer is created with the list of modes contained in Default Modes. Modeline-fields is a list of modeline-field objects (see the Modelines section) which may be nil. delete-hook is a list of delete hooks specific to this buffer, and delete-buffer invokes these along with Delete Buffer Hook.

Buffers created with make-buffer are entered into the list (all-buffers), and their names are inserted into the string-table *buffer-names*. When a buffer is created the hook Make Buffer Hook is invoked with the new buffer.

#### bufferp

Function

                            bufferp buffer

##### Description

Returns t if buffer is a buffer object, otherwise nil.

#### buffer-name

Function

                            buffer-name buffer

##### Description

#### Buffer Name Hook

Hemlock Variable

                            Buffer Name Hook

##### Description

buffer-name returns the name, which is a string, of the given buffer. The corresponding setf method invokes Buffer Name Hook with buffer and the new name and then sets the buffer's name. When the user supplies a name for which a buffer already exists, the setf method signals an error.

#### buffer-region

Function

                            buffer-region buffer

##### Description

Returns the buffer's region. Note this is the region that contains all the text in a buffer, as opposed to the current-region.

This can be set with setf to replace the buffer's text.

#### buffer-pathname

Function

                            buffer-pathname buffer

##### Description

#### Buffer Pathname Hook

Hemlock Variable

                            Buffer Pathname Hook

##### Description

buffer-pathname returns the pathname of the file associated with the given buffer, or nil if it has no associated file. This is the truename of the file as of the most recent time it was read or written. There is a setf form to change the pathname. When the pathname is changed the hook Buffer Pathname Hook is invoked with the buffer and new value.

#### buffer-write-date

Function

                            buffer-write-date buffer

##### Description

Returns the write date for the file associated with the buffer in universal time format. When this the buffer-pathname is set, use setf to set this to the corresponding write date, or to nil if the date is unknown or there is no file.

#### buffer-point

Function

                            buffer-point buffer

##### Description

Returns the mark which is the current location within buffer. To move the point, use move-mark or move-to-position

#### buffer-mark

Function

                            buffer-mark buffer

##### Description

This function returns the top of buffer's mark stack. There always is at least one mark at the beginning of buffer's region, and all marks returned are right-inserting.

#### buffer-start-mark

Function

                            buffer-start-mark buffer

##### Description

#### buffer-end-mark

Function

                            buffer-end-mark buffer

##### Description

These functions return the start and end marks of buffer's region:

    (buffer-start-mark buffer )  &lt;==&gt;  (region-start (buffer-region buffer))

and

    (buffer-end-mark buffer )  &lt;==&gt;  (region-end (buffer-region buffer))

#### buffer-writable

Function

                            buffer-writable buffer

##### Description

#### Buffer Writable Hook

Hemlock Variable

                            Buffer Writable Hook

##### Description

This function returns t if you can modify the buffer, nil if you cannot. If a buffer is not writable, then any attempt to alter text in the buffer results in an error. There is a setf method to change this value. The setf method invokes the functions in Buffer Writable Hook on the buffer and new value before storing the new value.

#### buffer-modified

Function

                            buffer-modified buffer

##### Description

#### Buffer Modified Hook

Hemlock Variable

                            Buffer Modified Hook

##### Description

buffer-modified returns t if the buffer has been modified, nil if it hasn't. This attribute is set whenever a text-altering operation is performed on a buffer. There is a setf method to change this value. The setf method invokes the functions in Buffer Modified Hook with the buffer whenever the value of the modified flag changes.

#### with-writable-buffer

Macro

                            with-writable-buffer (buffer) &body; body

##### Description

This macro executes forms with buffer's writable status set. After forms execute, this resets the buffer's writable and modified status.

#### buffer-signature

Function

                            buffer-signature buffer

##### Description

This function returns an arbitrary number which reflects the buffer's current signature. The result is eql to a previous result if and only if the buffer has not been modified between the calls.

#### buffer-variables

Function

                            buffer-variables buffer

##### Description

This function returns a string-table containing the names of the buffer's local variables.

#### buffer-modes

Function

                            buffer-modes buffer

##### Description

This function returns the list of the names of the modes active in buffer. The major mode is first, followed by any minor modes. See the Modes chapter.

#### buffer-delete-hook

Function

                            buffer-delete-hook buffer

##### Description

This function returns the list of buffer specific functions delete-buffer invokes when deleting a buffer . This is setf-able.

#### delete-buffer

Function

                            delete-buffer  buffer

##### Description

#### Delete Buffer Hook

Hemlock Variable

                            Delete Buffer Hook

##### Description

delete-buffer removes buffer from (all-buffers) and its name from *buffer-names*. Before buffer is deleted, this invokes the functions on buffer returned by buffer-delete-hook and those found in Delete Buffer Hook. If buffer is the current-buffer, or if it is displayed in any view, then this function signals an error.

### Modelines

A Buffer may specify a modeline, a line of text which is displayed across the bottom of a view to indicate status information. Modelines are described by a list of modeline-field objects which have individual update functions and are optionally fixed-width. These have an eql name for convenience in referencing and updating, but the name must be unique for all created modeline-field objects. All modeline-field functions must take a buffer as an argument and return a string. When displaying a modeline-field with a specified width, the result of the update function is either truncated or padded on the right to meet the constraint.

Whenever one of the following changes occurs, all of a buffer's modeline fields are updated:

- A buffer's major mode is set.

- One of a buffer's minor modes is turned on or off.

- A buffer is renamed.

- A buffer's pathname changes.

- A buffer's modified status changes.

The policy is that whenever one of these changes occurs, it is guaranteed that the modeline will be updated before the next trip through redisplay. Furthermore, since the system cannot know what modeline-field objects the user has added whose update functions rely on these values, or how he has changed Default Modeline Fields, we must update all the fields.

The user should note that modelines can be updated at any time, so update functions should be careful to avoid needless delays (for example, waiting for a local area network to determine information).

#### make-modeline-field

Function

                            make-modeline-field &key; :name :width :function

##### Description

This function returns a modeline-field object with name, width, and function. Width defaults to nil meaning that the field is variable width; otherwise, the programmer must supply this as a positive integer. Function must take a buffer as an arguments and return a string. If name already names a modeline-field object, then this signals an error.

#### modeline-field-name

Function

                            modeline-field-name modeline-field

##### Description

This function returns the name field of a modeline-field object. If this is set with setf, and the new name already names a modeline-field, then the setf method signals an error.

#### modeline-field-p

Function

                            modeline-field-p modeline-field

##### Description

This function returns t if its argument is a modeline-field object, nil otherwise.

#### modeline-field

Function

                            modeline-field name

##### Description

This returns the modeline-field object named name. If none exists, this returns nil.

#### modeline-field-function

Function

                            modeline-field-function modeline-field

##### Description

Returns the function called when updating the modeline-field. When this is set with setf, the setf method updates modeline-field for all views on all buffers that contain the given field, so the next trip through redisplay will reflect the change. All modeline-field functions must take a buffer as an argument and return a string.

#### modeline-field-width

Function

                            modeline-field-width modeline-field

##### Description

Returns the width to which modeline-field is constrained, or nil indicating that it is variable width. When this is set with setf, the setf method updates all modeline-fields for all views on all buffers that contain the given field, so the next trip through redisplay will reflect the change.

#### buffer-modeline-fields

Function

                            buffer-modeline-fields buffer

##### Description

Returns a copy of the list of buffer's modeline-field objects. This list can be destructively modified without affecting display of buffer's modeline, but modifying any particular field's components (for example, width or function) causes the changes to be reflected the next trip through redisplay in every modeline display that uses the modified modeline-field. When this is set with setf, the setf method method updates all modeline-fields on all views on the buffer, so next trip through the redisplay will reflect the change.

#### buffer-modeline-field-p

Function

                            buffer-modeline-field-p buffer field

##### Description

If field, a modeline-field or the name of one, is in buffer's list of modeline-field objects, it is returned; otherwise, this returns nil.

#### update-modeline-fields

Function

                            update-modeline-fields buffer

##### Description

Arranges so that the modeline display is updated with the latest values at the end of current command.

## Altering and Searching Text

A note on marks and text alteration: :temporary marks are invalid after any change has been made to the buffer the mark points to; it is an error to use a temporary mark after such a change has been made.

If text is deleted which has permanent marks pointing into it then they are left pointing to the position where the text was.

### Altering Text

#### insert-character

Function

                            insert-character mark character

##### Description

#### insert-string

Function

                            insert-string mark string

##### Description

#### insert-region

Function

                            insert-region mark region

##### Description

Inserts character, string or region at mark. `insert-character` signals an error if character is not `string-char-p`. If string or region is empty, and mark is in some buffer, then Hemlock leaves buffer-modified of mark's buffer unaffected.

#### ninsert-region

Function

                            ninsert-region mark region

##### Description

Like `insert-region`, inserts the region at the mark's position, destroying the source region. This must be used with caution, since if anyone else can refer to the source region bad things will happen. In particular, one should make sure the region is not linked into any existing buffer. If region is empty, and mark is in some buffer, then Hemlock leaves buffer-modified of mark's buffer unaffected.

#### delete-characters

Function

                            delete-characters mark n

##### Description

This deletes n characters after the mark (or -n before if n is negative). If n characters after (or -n before) the mark do not exist, then this returns nil; otherwise, it returns t. If n is zero, and mark is in some buffer, then Hemlock leaves buffer-modified of mark's buffer unaffected.

#### delete-region

Function

                            delete-region region

##### Description

This deletes region. This is faster than delete-and-save-region (below) because no lines are copied. If region is empty and contained in some buffer's buffer-region, then Hemlock leaves buffer-modified of the buffer unaffected.

#### delete-and-save-region

Function

                            delete-and-save-region region

##### Description

This deletes region and returns a region containing the original region's text. If region is empty and contained in some buffer's buffer-region, then Hemlock leaves buffer-modified of the buffer unaffected. In this case, this returns a distinct empty region.

#### filter-region

Function

                            filter-region function region

##### Description

Destructively modifies region by replacing the text of each line with the result of the application of function to a string containing that text. Function must obey the following restrictions:

1. The argument may not be destructively modified.

2. The return value may not contain newline characters.

3. The return value may not be destructively modified after it is returned from function.

The strings are passed in order.

Using this function, a region could be uppercased by doing: `(filter-region #'string-upcase region)`

### Text Predicates

#### start-line-p

Function

                            start-line-p mark

##### Description

Returns t if the mark points before the first character in a line, nil otherwise.

#### end-line-p

Function

                            end-line-p mark

##### Description

Returns t if the mark points after the last character in a line and before the newline, nil otherwise.

`empty-line-p` mark [Function] Return t if the line which mark points to contains no characters.

#### blank-line-p

Function

                            blank-line-p line

##### Description

Returns t if line contains only characters with a Whitespace attribute of 1. See the Character Attributes chapter for discussion of character attributes.

#### blank-before-p

Function

                            blank-before-p mark

##### Description

#### blank-after-p

Function

                            blank-after-p mark

##### Description

These functions test if all the characters preceding or following mark on the line it is on have a Whitespace attribute of 1.

#### same-line-p

Function

                            same-line-p mark1 mark2

##### Description

Returns t if mark1 and mark2 point to the same line, or nil otherwise; That is,

    (same-line-p a b) &lt;==&gt; (eq (mark-line a) (mark-line b))

#### mark<

Function

                            mark< mark1 mark2

##### Description

#### mark<=

Function

                            mark<= mark1 mark2

##### Description

#### mark=

Function

                            mark= mark1 mark2

##### Description

#### mark/=

Function

                            mark/= mark1 mark2

##### Description

#### mark>=

Function

                            mark>= mark1 mark2

##### Description

#### mark>

Function

                            mark> mark1 mark2

##### Description

These predicates test the relative ordering of two marks in a piece of text, that is a mark is mark> another if it points to a position after it. An error is signalled if the marks do not point into the same buffer, except that for such marks mark= is always false and mark/= is always true.

#### line<

Function

                            line< line1 line2

##### Description

#### line<=

Function

                            line<= line1 line2

##### Description

#### line>=

Function

                            line>= line1 line2

##### Description

#### line>

Function

                            line> line1 line2

##### Description

These predicates test the ordering of line1 and line2. An error is signalled if the lines are not in the same buffer.

#### lines-related

Function

                            lines-related line1 line2

##### Description

This function returns t if line1 and line2 are in the same buffer, nil nil otherwise.

#### first-line-p

Function

                            first-line-p mark

##### Description

#### last-line-p

Function

                            last-line-p mark

##### Description

`first-line-p` returns t if there is no line before the line mark is on, and nil otherwise. `Last-line-p` similarly tests tests whether there is no line after mark.

### Kill Ring

There is a global ring of regions deleted from buffers. Some commands save affected regions on the kill ring before performing modifications. You should consider making the command undoable, but this is a simple way of achieving a less satisfactory means for the user to recover.

#### kill-region

Function

                            kill-region region  current-type

##### Description

This kills region saving it in the kill ring. Current-type is either :kill-forward or :kill-backward. When the last-command-type is one of these, this adds region to the beginning or end, respectively, of the top of the kill ring. The result of calling this is undoable using the command Undo (see the Hemlock User's Manual). This sets last-command-type to current-type, and it interacts with kill-characters.

#### kill-characters

Function

                            kill-characters mark count

##### Description

#### Character Deletion Threshold

Hemlock Variable

                            Character Deletion Threshold (initial value 5)

##### Description

kill-characters kills count characters after mark if count is positive, otherwise before mark if count is negative. When count is greater than or equal to Character Deletion Threshold, the killed characters are saved on the kill ring. This may be called multiple times contiguously (that is, without last-command-type being set) to accumulate an effective count for purposes of comparison with the threshold.

This sets last-command-type, and it interacts with kill-region. When this adds a new region to the kill ring, it sets last-command-type to :kill-forward (if count is positive) or :kill-backward (if count is negative). When last-command-type is :kill-forward or :kill-backward, this adds the killed characters to the beginning (if count is negative) or the end (if count is positive) of the top of the kill ring, and it sets last-command-type as if it added a new region to the kill ring. When the kill ring is unaffected, this sets last-command-type to :char-kill-forward or :char-kill-backward depending on whether count is positive or negative, respectively.

This returns mark if it deletes characters. If there are not count characters in the appropriate direction, this returns nil.

### Active Regions

Every buffer has a mark stack and a mark known as the point where most text altering nominally occurs. Between the top of the mark stack, the current-mark, and the current-buffer's point, the current-point, is what is known as the current-region . Certain commands signal errors when the user tries to operate on the current-region without its having been activated. If the user turns off this feature, then the current-region is effectively always active.

When writing a command that marks a region of text, the programmer should make sure to activate the region. This typically occurs naturally from the primitives that you use to mark regions, but sometimes you must explicitly activate the region. These commands should be written this way, so they do not require the user to separately mark an area and then activate it. Commands that modify regions do not have to worry about deactivating the region since modifying a buffer automatically deactivates the region. Commands that insert text often activate the region ephemerally; that is, the region is active for the immediately following command, allowing the user wants to delete the region inserted, fill it, or whatever.

Once a marking command makes the region active, it remains active until:

- a command uses the region,

- a command modifies the buffer,

- a command changes the current window or buffer,

- a command signals an editor-error,

- or the user types C-g.

#### Active Regions Enabled

Hemlock Variable

                            Active Regions Enabled (initial value t)

##### Description

When this variable is non-nil, some primitives signal an editor-error if the region is not active. This may be set to nil for more traditional Emacs region semantics.

#### *ephemerally-active-command-types*

Variable

                            *ephemerally-active-command-types*

##### Description

This is a list of command types, and its initial value is the list of :ephemerally-active and :unkill. When the previous command's type is one of these, the current-region is active for the currently executing command only, regardless of whether it does something to deactivate the region. However, the current command may activate the region for future commands. :ephemerally-active is a default command type that may be used to ephemerally activate the region, and:unkill is the type used by two commands, Un-kill and Rotate Kill Ring (what users typically think of as C-y and M-y).

#### activate-region

Function

                            activate-region

##### Description

This makes the current-region active.

#### deactivate-region

Function

                            deactivate-region

##### Description

After invoking this the current-region is no longer active.

#### region-active-p

Function

                            region-active-p

##### Description

Returns whether the current-region is active, including ephemerally. This ignores Active Regions Enabled.

#### check-region-active

Function

                            check-region-active

##### Description

This signals an editor-error when active regions are enabled, and the current-region is not active.

#### current-region

Function

                            current-region &optional; error-if-not-active deactivate-region

##### Description

This returns a region formed with current-mark and current-point, optionally signaling an editor-error if the current region is not active. Error-if-not-active defaults to t. Each call returns a distinct region object. Depending on deactivate-region (defaults to t), fetching the current region deactivates it. Hemlock primitives are free to modify text regardless of whether the region is active, so a command that checks for this can deactivate the region whenever it is convenient.

### Searching and Replacing

Before using any of these functions to do a character search, look at character attributes. They provide a facility similar to the syntax table in real Emacs. Syntax tables are a powerful, general, and efficient mechanism for assigning meanings to characters in various modes.

#### new-search-pattern

Function

                            new-search-pattern kind direction pattern &optional; result-search-pattern

##### Description

Returns a search-pattern object which can be given to the find-pattern and replace-pattern functions. A search-pattern is a specification of a particular sort of search to do. direction is either :forward or :backward, indicating the direction to search in. kind specifies the kind of search pattern to make, and pattern is a thing which specifies what to search for. The interpretation of pattern depends on the kind of pattern being made. Currently defined kinds of search pattern are:

:string-insensitive

  Does a case-insensitive string search for pattern

:string-sensitive

  Does a case-sensitive string search for pattern.

:character

  Finds an occurrence of the character pattern. This is case sensitive.

:not-character

  Find a character which is not the character pattern.

:test

  Finds a character which satisfies the function pattern. This function may not be applied an any particular fashion, so it should depend only on what its argument is, and should have no side-effects.

:test-not

  Similar to :test, except it finds a character that fails the test.

:any

  Finds a character that is in the string pattern.

:not-any

  Finds a character that is not in the string pattern.

result-search-pattern, if supplied, is a search-pattern to destructively modify to produce the new pattern. Where reasonable this should be supplied, since some kinds of search patterns may involve large data structures.

#### search-pattern-p

Function

                            search-pattern-p search-pattern

##### Description

Returns t if search-pattern is a search-pattern object, otherwise nil.

#### get-search-pattern

Function

                            get-search-pattern string direction

##### Description

get-search-pattern interfaces to a default search string and pattern that search and replacing commands can use. These commands then share a default when prompting for what to search or replace, and save on consing a search pattern each time they execute. This uses Default Search Kind (see the Hemlock User's Manual) when updating the pattern object.

#### *last-search-string*

Variable

                            *last-search-string*

##### Description

Returns the last string searched for, useful when prompting.

#### find-pattern

Function

                            find-pattern mark search-pattern

##### Description

Find the next match of search-pattern starting at mark. If a match is found then mark is altered to point before the matched text and the number of characters matched is returned. If no match is found then nil is returned and mark is not modified.

#### replace-pattern

Function

                            replace-pattern mark search-pattern replacement &optional; n

##### Description

Replace n matches of search-pattern with the string replacement starting at mark. If n is nil (the default) then replace all matches. A mark pointing before the last replacement done is returned.

## The Current Environment

### Different Scopes

In Hemlock the "current" values of variables, key bindings and character-attributes depend on the current buffer and the modes active in it. There are three possible scopes for Hemlock values:

buffer local

  The value is present only if the buffer it is local to is the current buffer.

mode local

  The value is present only when the mode it is local to is active in the current buffer.

global

  The value is always present unless shadowed by a buffer or mode local value.

### Shadowing

It is possible that there are different values for the same thing in in different scopes. For example, there be might a global binding for a given variable and also a local binding in the current buffer. Whenever there is a conflict, shadowing occurs, permitting only one of the values to be visible in the current environment.

The process of resolving such a conflict can be described as a search down a list of places where the value might be defined, returning the first value found. The order for the search is as follows:

1. Local values in the current buffer.

2. Mode local values in the minor modes of the current buffer, in order from the highest precedence mode to the lowest precedence mode. The order of minor modes with equal precedences is undefined.

3. Mode local values in the current buffer's major mode.

4. Global values.

## Hemlock Variables

Hemlock implements a system of variables separate from normal Lisp variables for the following reasons:

1. Hemlock has different scoping rules which are useful in an editor. Hemlock variables can be local to a buffer or a mode.

2. Hemlock variables have hooks, lists of functions called when someone sets the variable. See variable-value for the arguments Hemlock passes to these hook functions.

3. There is a database of variable names and documentation which makes it easier to find out what variables exist and what their values mean.

### Variable Names

To the user, a variable name is a case insensitive string. This string is referred to as the string name of the variable. A string name is conventionally composed of words separated by spaces.

In Lisp code a variable name is a symbol. The name of this symbol is created by replacing any spaces in the string name with hyphens. This symbol name is always interned in the Hemlock package.

#### *global-variable-names*

Variable

                            *global-variable-names*

##### Description

This variable holds a string-table of the names of all the global Hemlock variables. The value of each entry is the symbol name of the variable.

#### current-variable-tables

Function

                            current-variable-tables

##### Description

This function returns a list of variable tables currently established, globally, in the current buffer, and by the modes of the current-buffer. This list is suitable for use with prompt-for-variable.

### Variable Functions

In the following descriptions name is the symbol name of the variable.

#### defhvar

Function

                            defhvar string-name documentation &key; :mode :buffer :hooks :value

##### Description

This function defines a Hemlock variable. Functions that take a variable name signal an error when the variable is undefined.

string-name

  The string name of the variable to define.

documentation

  The documentation string for the variable.

:mode, :buffer

  If buffer is supplied, the variable is local to that buffer. If mode is supplied, it is local to that mode. If neither is supplied, it is global.

:value

  This is the initial value for the variable, which defaults to nil.

:hooks

  This is the initial list of functions to call when someone sets the variable's value. These functions execute before Hemlock establishes the new value. See variable-value for the arguments passed to the hook functions.

If a variable with the same name already exists in the same place, then defhvar sets its hooks and value from hooks and value if the user supplies these keywords.

#### variable-value

Function

                            variable-value name &optional; kind where

##### Description

This function returns the value of a Hemlock variable in some place. The following values for kind are defined:

:current

  Return the value present in the current environment, taking into consideration any mode or buffer local variables. This is the default.

:global

  Return the global value.

:mode

  Return the value in the mode named where.

:buffer

  Return the value in the buffer where.

When set with setf, Hemlock sets the value of the specified variable and invokes the functions in its hook list with name, kind, where, and the new value.

#### variable-documentation

Function

                            variable-documentation name &optional; kind where

##### Description

#### variable-hooks

Function

                            variable-hooks name &optional; kind where

##### Description

#### variable-name

Function

                            variable-name name &optional; kind where

##### Description

These function return the documentation, hooks and string name of a Hemlock variable. The kind and where arguments are the same as for variable-value. The documentation and hook list may be set using setf.

#### string-to-variable

Function

                            string-to-variable string

##### Description

This function converts a string into the corresponding variable symbol name. String need not be the name of an actual Hemlock variable.

#### value

Macro

                            value name

##### Description

#### setv

Macro

                            setv name new-value

##### Description

These macros get and set the current value of the Hemlock variable name. Name is not evaluated. There is a setf form for `value`.

#### hlet

Macro

                            hlet ({(var value)}*){form}*

##### Description

This macro is very similar to let in effect; within its scope each of the Hemlock variables var have the respective values, but after the scope is exited by any means the binding is removed. This does not cause any hooks to be invoked. The value of the last form is returned.

#### hemlock-bound-p

Function

                            hemlock-bound-p name &optional; kind where

##### Description

Returns t if name is defined as a Hemlock variable in the place specified by kind and where, or nil otherwise.

#### delete-variable

Function

                            delete-variable name &optional; kind where

##### Description

#### Delete Variable Hook

Hemlock Variable

                            Delete Variable Hook

##### Description

delete-variable makes the Hemlock variable name no longer defined in the specified place. Kind and where have the same meanings as they do for variable-value, except that :current is not available, and the default for kind is :global

An error will be signaled if no such variable exists. The hook, Delete Variable Hook is invoked with the same arguments before the variable is deleted.

### Hooks

Hemlock actions such as setting variables, changing buffers, changing windows, turning modes on and off, etc., often have hooks associated with them. A hook is a list of functions called before the system performs the action. The manual describes the object specific hooks with the rest of the operations defined on these objects.

Often hooks are stored in Hemlock variables, Delete Buffer Hook and Set Window Hook for example. This leads to a minor point of confusion because these variables have hooks that the system executes when someone changes their values. These hook functions Hemlock invokes when someone sets a variable are an example of a hook stored in an object instead of a Hemlock variable. These are all hooks for editor activity, but Hemlock keeps them in different kinds of locations. This is why some of the routines in this section have a special interpretation of the hook place argument.

#### add-hook

Macro

                            add-hook place hook-fun

##### Description

#### remove-hook

Macro

                            remove-hook place hook-fun

##### Description

These macros add or remove a hook function in some place. If hook-fun already exists in place, this call has no effect. If place is a symbol, then it is a Hemlock variable; otherwise, it is a generalized variable or storage location. Here are two examples:

    (add-hook delete-buffer-hook 'remove-buffer-from-menu)
    (add-hook (variable-hooks 'check-mail-interval)
              'reschedule-mail-check)

#### invoke-hook

Macro

                            invoke-hook place &rest; args

##### Description

This macro calls all the functions in place. If place is a symbol, then it is a Hemlock variable; otherwise, it is a generalized variable.

## Commands

### Introduction

The way that the user tells Hemlock to do something is by invoking a command. Commands have three attributes:

name

  A command's name provides a way to refer to it. Command names are usually capitalized words separated by spaces, such as Forward Word.

documentation

  The documentation for a command is used by on-line help facilities.

function

  A command is implemented by a Lisp function, which is callable from Lisp.

#### Defining Commands

##### *command-names*

Variable

                            *command-names*

###### Description

Holds a string-table associating command names to command objects. Whenever a new command is defined it is entered in this table.

##### defcommand

Macro

                                    defcommand {command-name | (command-name function-name &key;)} lambda-list command-doc {function-doc} {form}*

###### Description

Defines a command named name. defcommand creates a function to implement the command from the lambda-list and forms supplied. The lambda-list must specify one required argument, see below, which by convention is typically named `p`. If the caller does not specify function-name, defcommand creates the command name by replacing all spaces with hyphens and appending "-command". Any keyword arguments are as for `make-command`. Command-doc becomes the command documentation for the command. Function-doc, if present, becomes the documentation for the function and should primarily describe issues involved in calling the command as a function, such as what any additional arguments are.

##### make-command

Function

                                    make-command name documentation function &key; :transparent-p

###### Description

Defines a new command named name, with command documentation documentation and function function. If :transparent-p is true, the command becomes transparent. The command in entered in the string-table *command-names*, with the command object as its value. Normally command implementors will use the defcommand macro, but this permits access to the command definition mechanism at a lower level, which is occasionally useful.

##### commandp

Function

                                    commandp command

###### Description

Returns t if command is a command object, otherwise nil.

##### command-documentation

Function

                                    command-documentation command

###### Description

##### command-function

Function

                                    command-function command

###### Description

##### command-name

Function

                                    command-name command

###### Description

Returns the documentation, function, or name for command. These may be set with setf.

#### Command Documentation

Command documentation is a description of what the command does when it is invoked as an extended command or from a key. Command documentation may be either a string or a function. If the documentation is a string then the first line should briefly summarize the command, with remaining lines filling the details. Example:

    (defcommand "Forward Character" (p)
      "Move the point forward one character.
       With prefix argument move that many characters, with negative
       argument go backwards."
    . . .)

Command documentation may also be a function of one argument. The function is called with either :short or :full, indicating that the function should return a short documentation string or do something to document the command fully.

### The Command Interpreter

The command interpreter is the functionality invoked by the event handler to process key-events from the keyboard and dispatch to different commands on the basis of what the user types. When the command interpreter executes a command, we say it invokes the command. The command interpreter also provides facilities for communication between contiguously running commands, such as a last command type register. It also takes care of resetting communication mechanisms, clearing the echo area, displaying partial keys typed slowly by the user, etc.

#### Controlling The Command Interpreter

##### Command Abort Hook

Hemlock Variable

                            Command Abort Hook

###### Description

The command interpreter invokes the function in this variable whenever someone aborts a command (for example, if someone called editor-error).

#### Editor Input

The canonical representation of editor input is a key-event structure. Users can bind commands to keys, which are non-empty sequences of key-events. A key-event consists of an identifying token known as a keysym and a field of bits representing modifiers. Users define keysym names by supplying names that reflect the legends on their keyboard's keys. Users define modifier names similarly, but the system chooses the bit and mask for recognizing the modifier. You can use keysym and modifier names to textually specify key-events and Hemlock keys in a #k syntax. The following are some examples:

    #k"C-u"
    #k"Control-u"
    #k"c-m-z"
    #k"control-x meta-d"
    #k"a"
    #k"A"
    #k"Linefeed"

This is convenient for use within code and in init files containing `bind-key` calls.

The #k syntax is delimited by double quotes. Within the double quotes, spaces separate multiple key-events. A single key-event optionally starts with modifier names terminated by hyphens. Modifier names are alphabetic sequences of characters which the system uses case-insensitively. Following modifiers is a keysym name, which is case-insensitive if it consists of multiple characters, but if the name consists of only a single character, then it is case-sensitive.

You can escape special characters---hyphen, double quote, open angle bracket, close angle bracket, and space---with a backslash, and you can specify a backslash by using two contiguously. You can use angle brackets to enclose a keysym name with many special characters in it. Between angle brackets appearing in a keysym name position, there are only two special characters, the closing angle bracket and backslash.

For more information on key-events see the Key-events section.

#### Binding Commands to Keys

The command interpreter determines which command to invoke on the basis of key bindings. A key binding is an association between a command and a sequence of key-events. A sequence of key-events is called a key and is represented by a single key-event or a sequence (list or vector) of key-events.

Since key bindings may be local to a mode or buffer, the current environment determines the set of key bindings in effect at any given time. When the command interpreter tries to find the binding for a key, it first checks if there is a local binding in the current buffer, then if there is a binding in each of the minor modes and the major mode for the current buffer, and finally checks to see if there is a global binding. If no binding is found, then the command interpreter beeps or flashes the screen to indicate this.

##### bind-key

Function

                                    bind-key name key &optional; kind where

###### Description

This function associates command name and key in some environment. Key is either a key-event or a sequence of key-events. There are three possible values of kind:

:global

  The default, make a global key binding.

:mode

  Make a mode specific key binding in the mode whose name is where.

:buffer

  Make a binding which is local to buffer where.

This processes key for key translations before establishing the binding.

If the key is some prefix of a key binding which already exists in the specified place, then the new one will override the old one, effectively deleting it.

`do-alpha-key-events` is useful for setting up bindings in certain new modes.

##### command-bindings

Function

                                    command-bindings command

###### Description

This function returns a list of the places where command is bound. A place is specified as a list of the key (always a vector), the kind of binding, and where (either the mode or buffer to which the binding is local, or nil if it is a global).

##### delete-key-binding

Function

                                    delete-key-binding key &optional; kind where

###### Description

This function removes the binding of key in some place. Key is either a key-event or a sequence of key-events. kind is the kind of binding to delete, one of :global(the default), :mode or :buffer. If kind is :mode, where is the mode name, and if kind is :buffer, then where is the buffer.

This function signals an error if key is unbound.

This processes key for key translations before deleting the binding.

##### get-command

Function

                                    get-command key &optional; kind where

###### Description

This function returns the command bound to key, returning nil if it is unbound. Key is either a key-event or a sequence of key-events. If key is an initial subsequence of some keys, then this returns the keyword :prefix. There are four cases of kind:

:current

  Return the current binding of key using the current buffer's search list. If there are any transparent key bindings for key, then they are returned in a list as a second value.

:global

  Return the global binding of key. This is the default.

:mode

  Return the binding of key in the mode named where.

:buffer

  Return the binding of key local to the buffer where.

This processes key for key translations before looking for any binding.

##### map-bindings

Function

                                    map-bindings function kind &optional; where

###### Description

This function maps over the key bindings in some place. For each binding, this passes function the key and the command bound to it. Kind and where are the same as in bind-key. The key is not guaranteed to remain valid after a given iteration.

#### Key Translation

Key translation is a process that the command interpreter applies to keys before doing anything else. There are two kinds of key translations: substitution and bit-prefix. In either case, the command interpreter translates a key when a specified key-event sequence appears in a key.

In a substitution translation, the system replaces the matched subsequence with another key-event sequence. Key translation is not recursively applied to the substituted key-events.

In a bit-prefix translation, the system removes the matched subsequence and effectively sets the specified bits in the next key-event in the key.

While translating a key, if the system encounters an incomplete final subsequence of key-events, it aborts the translation process. This happens when those last key-events form a prefix of some translation. It also happens when they translate to a bit-prefix, but there is no following key-event to which the system can apply the indicated modifier. If there is a binding for this partially untranslated key, then the command interpreter will invoke that command; otherwise, it will wait for the user to type more key-events.

##### key-translation

Function

                                    key-translation key

###### Description

This form is setf-able and allows users to register key translations that the command interpreter will use as users type key-events.

This function returns the key translation for key, returning nil if there is none. Key is either a key-event or a sequence of key-events. If key is a prefix of a translation, then this returns :prefix.

A key translation is either a key or modifier specification. The bits translations have a list form: (:bits {bit-name}*).

Whenever key appears as a subsequence of a key argument to the binding manipulation functions, that portion will be replaced with the translation.

#### Transparent Key Bindings

Key bindings local to a mode may be transparent. A transparent key binding does not shadow less local key bindings, but rather indicates that the bound command should be invoked before the first normal key binding. Transparent key bindings are primarily useful for implementing minor modes such as auto fill and word abbreviation. There may be several transparent key bindings for a given key, in which case all of the transparent commands are invoked in the order they were found. If there no normal key binding for a key typed, then the command interpreter acts as though the key is unbound even if there are transparent key bindings.

The :transparent-p argument to defmode determines whether all the key bindings in a mode are transparent or not. In addition a particular command may be declared to be transparent by the :transparent-p argument to defcommand and make-command.

### Command Types

In many editors the behavior of a command depends on the kind of command invoked before it. Hemlock provides a mechanism to support this known as `command type`.

#### last-command-type

Function

                            last-command-type

##### Description

This returns the command type of the last command invoked. If this is set with setf, the supplied value becomes the value of last-command-type until the next command completes. If the previous command did not set last-command-type, then its value is nil. Normally a command type is a keyword. The command type is not cleared after a command is invoked due to a transparent key binding.

### Command Arguments

There are three ways in which a command may be invoked: It may be bound to a key which has been typed, it may be invoked as an extended command, or it may be called as a Lisp function. Ideally commands should be written in such a way that they will behave sensibly no matter which way they are invoked. The functions which implement commands must obey certain conventions about argument passing if the command is to function properly.

#### The Prefix Argument

Whenever a command is invoked it is passed as its first argument what is known as the prefix argument. The prefix argument is always either an integer or nil. When a command uses this value it is usually as a repeat count, or some conceptually similar function.

##### prefix-argument

Function

                                prefix-argument

###### Description

This function returns the current value of the prefix argument. When set with setf, the new value becomes the prefix argument for the next command. If the prefix argument is not set by the previous command then the prefix argument for a command is nil. The prefix argument is not cleared after a command is invoked due to a transparent key binding.

#### Lisp Arguments

It is often desirable to call commands from Lisp code, in which case arguments which would otherwise be prompted for are passed as optional arguments following the prefix argument. A command should prompt for any arguments not supplied.

## Modes

A mode is a collection of Hemlock values which may be present in the current environment depending on the editing task at hand. An example of a typical mode is Lisp, for editing Lisp code.

### Mode Hooks

When a mode is added to or removed from a buffer, its mode hook is invoked. The hook functions take two arguments, the buffer involved and t if the mode is being added or nil if it is being removed. Mode hooks are typically used to make a mode do something additional to what it usually does. One might, for example, make a Text mode hook that turned on auto-fill mode when you entered.

### Major and Minor Modes

There are two kinds of modes, major modes and minor modes. A buffer always has exactly one major mode, but it may have any number of minor modes. Major modes may have mode character attributes while minor modes may not.

A major mode is usually used to change the environment in some major way, such as to install special commands for editing some language. Minor modes generally change some small attribute of the environment, such as whether lines are automatically broken when they get too long. A minor mode should work regardless of what major mode and minor modes are in effect.

#### Default Modes

Hemlock Variable

                            Default Modes (initial value '("Fundamental" "Save"))

##### Description

This variable contains a list of mode names which are instantiated in a buffer when no other information is available.

#### *mode-names*

Variable

                            *mode-names*

##### Description

Holds a string-table of the names of all the modes.

#### Illegal

Command

                            Illegal

##### Description

This is a useful command to bind in modes that wish to shadow global bindings by making them effectively illegal. Also, although less likely, minor modes may shadow major mode bindings with this. This command calls editor-error.

### Mode Functions

#### defmode

Function

                            defmode name &key; :setup-function :cleanup-function :major-p :precedence :transparent-p :documentation

##### Description

This function defines a new mode named name, and enters it in *mode-names*. If major-p is supplied and is not nil then the mode is a major mode; otherwise it is a minor mode.

Setup-function and cleanup-function are functions which are invoked with the buffer affected, after the mode is turned on, and before it is turned off, respectively. These functions typically are used to make buffer-local key or variable bindings and to remove them when the mode is turned off.

Precedence is only meaningful for a minor mode. The precedence of a minor mode determines the order in which it in a buffer's list of modes. When searching for values in the current environment, minor modes are searched in order, so the precedence of a minor mode determines which value is found when there are several definitions.

Transparent-p determines whether key bindings local to the defined mode are transparent. Transparent key bindings are invoked in addition to the first normal key binding found rather than shadowing less local key bindings.

Documentation is some introductory text about the mode. Commands such as Describe Mode use this.

#### mode-documentation

Function

                            mode-documentation name

##### Description

This function returns the documentation for the mode named name.

#### buffer-major-mode

Function

                            buffer-major-mode buffer

##### Description

#### Buffer Major Mode Hook

Hemlock Variable

                            Buffer Major Mode Hook

##### Description

buffer-major-mode returns the name of buffer's major mode. The major mode may be changed with setf; then Buffer Major Mode Hook is invoked with buffer and the new mode.

#### buffer-minor-mode

Function

                            buffer-minor-mode buffer name

##### Description

#### Buffer Minor Mode Hook

Hemlock Variable

                            Buffer Minor Mode Hook

##### Description

buffer-minor-mode returns t if the minor mode name is active in buffer, nil otherwise. A minor mode may be turned on or off by using setf; then Buffer Minor Mode Hook is invoked with buffer, name and the new value.

#### mode-variables

Function

                            mode-variables name

##### Description

Returns the string-table of mode local variables.

#### mode-major-p

Function

                            mode-major-p name

##### Description

Returns t if name is the name of a major mode, or nil if it is the name of a minor mode. It is an error for name not to be the name of a mode.

## Character Attributes

### Introduction

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:

1. 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.

1. This centralization of information avoids needless duplication of effort.

1. 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. 20).

### 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.

#### *character-attribute-names*

Variable

                            *character-attribute-names*

##### Description

Whenever a character attribute is defined, its name is entered in this string-table, with the corresponding keyword as the value.

### Character Attribute Functions

#### defattribute

Function

                            defattribute name documentation &optional; type initial-value

##### Description

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

Function

                            character-attribute-name attribute

##### Description

#### character-attribute-documentation

Function

                            character-attribute-documentation attribute

##### Description

These functions return the name or documentation for attribute.

#### character-attribute

Function

                            character-attribute attribute character

##### Description

#### Character Attribute Hook

Hemlock Variable

                            Character Attribute Hook

##### Description

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

Function

                            character-attribute-p symbol

##### Description

This function returns t if symbolis the name of a character attribute, nil otherwise.

#### shadow-attribute

Function

                            shadow-attribute attribute character value mode

##### Description

#### Shadow Attribute Hook

Hemlock Variable

                            Shadow Attribute Hook

##### Description

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

Function

                            unshadow-attribute attribute character mode

##### Description

#### Unshadow Attribute Hook

Hemlock Variable

                            Unshadow Attribute Hook

##### Description

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

Function

                            find-attribute mark attribute &optional; test

##### Description

#### reverse-find-attribute

Function

                            reverse-find-attribute mark attribute &optional; test

##### Description

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

Function

                            find-not-attribute mark attribute

##### Description

#### reverse-find-not-attribute

Function

                            reverse-find-not-attribute mark attribute

##### Description

These are equivalent to (find-attribute mark attribute #'zerop) and (reverse-find-attribute mark attribute #'zerop), respectively.

### 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

Function

                            character-attribute-hooks attribute

##### Description

Return the current hook list for attribute. This may be set with setf. The add-hook and remove-hook macros should be used to manipulate these lists.

### System Defined Character Attributes

These are predefined in Hemlock:

"Whitespace"

  A value of 1 indicates the character is whitespace.

"Word Delimiter"

  A value of 1 indicates the character separates words (see the English Text Buffers section).

"Space"

  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 the English Text Buffers section).

"Sentence Closing Char"

  A value of 1 indicates these delimiting characters, such as " or ), may follow a Sentence Terminator.

"Paragraph Delimiter"

  A value of 1 indicates these characters delimit paragraphs when they begin a line (see the English Text Buffers section).

"Page Delimiter"

  A value of 1 indicates this character separates logical pages 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.

## Controlling the Display

### Views

A `hemlock-view` represents the GUI object(s) used to display the contents of a buffer. Conceptually it consists of a text buffer, a modeline for semi-permanent status info, an echo area for transient status info, and a text input area for reading prompted input. (Currently the last two are conflated, i.e. text input happens in the echo area).

The API for working with hemlock-views is not fully defined yet. If you need to work with views beyond what's listed here, you will probably need to get in the sources and find some internal functions to call.

### The Current View

#### current-view

Function

                            current-view

##### Description

current-view returns the hemlock view which is the target of the currently executing command. This is usually the frontmost hemlock window in the current application.

### View Functions

#### hemlock-view-p

Function

                            hemlock-view-p object

##### Description

This function returns t if object is a hemlock view, otherwise nil.

#### hemlock-view-buffer

Function

                            hemlock-view-buffer view

##### Description

This function returns the buffer which is displayed in the view.

### Cursor Positions

#### mark-column

Function

                            mark-column mark

##### Description

This function returns the X position at which mark would be displayed, supposing its line was displayed on an infinitely wide screen. This takes into consideration strange characters such as tabs.

#### move-to-column

Function

                            move-to-column mark column &optional; line

##### Description

This function is analogous to move-to-position, except that it moves mark to the position on line which corresponds to the specified column. If the line would not reach to the specified column, then nil is returned and mark is not modified. Note that since a character may be displayed on more than one column on the screen, several different values of column may cause mark to be moved to the same position.

### Redisplay

The display of the buffer contents on the screen is updated at the end of each command. The following function can be used to control the scroll position of the buffer in the view.

#### set-scroll-position

Function

                            set-scroll-position how &optional; what

##### Description

Normally, after a command that changes the contents of the buffer or the selection (i.e. the active region), the event handler repositions the view so that the selection is visible, scrolling the buffer as necessary. Calling this function tells the system to not do that, and instead to position the buffer in a particular way. `how` can be one of the following:

:center-selection

  This causes the selection (or the point) to be centered in the visible area. `what` is ignored.

:page-up

  This causes the previous page of the buffer to be shown `what` is ignored.

:page-down

  This causes the next page of the buffer to be shown. `what` is ignored.

:lines-up

  This causes `what` previous lines to be scrolled in at the top. `what` must be an integer.

:lines-down

  This causes `what` next lines to be scrolled in at the bottom. `what` must be an integer.

:line

  This causes the line containing `what` to be scrolled to the top of the view. `what` must be a mark.

## Logical Key-Events

### Introduction

Some primitives such as prompt-for-key and commands such as Emacs query replace read key-events directly from the keyboard instead of using the command interpreter. To encourage consistency between these commands and to make them portable and easy to customize, there is a mechanism for defininglogical key-events. A logical key-event is a keyword which stands for some set of key-events. The system globally interprets these key-events as indicators a particular action. For example, the :help logical key-event represents the set of key-events that request help in a given Hemlock implementation. This mapping is a many-to-many mapping, not one-to-one, so a given logical key-event may have multiple corresponding actual key-events. Also, any key-event may represent different logical key-events.

### Logical Key-Event Functions

#### *logical-key-event-names*

Variable

                            *logical-key-event-names*

##### Description

This variable holds a string-table mapping all logical key-event names to the keyword identifying the logical key-event.

#### define-logical-key-event

Function

                            define-logical-key-event string-name documentation

##### Description

This function defines a new logical key-event with name string-name. Logical key-event operations take logical key-events arguments as a keyword whose name is string-name uppercased with spaces replaced by hyphens.

Documentation describes the action indicated by the logical key-event.

#### logical-key-event-key-events

Function

                            logical-key-event-key-events keyword

##### Description

This function returns the list of key-events representing the logical key-event keyword.

#### logical-key-event-name

Function

                            logical-key-event-name keyword

##### Description

#### logical-key-event-documentation

Function

                            logical-key-event-documentation keyword

##### Description

These functions return the string name and documentation given to define-logical-key-event for logical key-event keyword.

#### logical-key-event-p

Function

                            logical-key-event-p key-event keyword

##### Description

This function returns t if key-event is the logical key-event keyword. This is setf-able establishing or disestablishing key-events as particular logical key-events. It is a error for keyword to be an undefined logical key-event.

### System Defined Logical Key-Events

There are many default logical key-events, some of which are used by functions documented in this manual. If a command wants to read a single key-event command that fits one of these descriptions then the key-event read should be compared to the corresponding logical key-event instead of explicitly mentioning the particular key-event in the code. In many cases you can use the command-case macro. It makes logical key-events easy to use and takes care of prompting and displaying help messages.

- :abort Indicates the prompter should terminate its activity without performing any closing actions of convenience, for example.

- :yes Indicates the prompter should take the action under consideration.

- :no Indicates the prompter should NOT take the action under consideration.

- :do-all Indicates the prompter should repeat the action under consideration as many times as possible.

- :do-once Indicates the prompter should execute the action under consideration once and then exit.

- :help Indicates the prompter should display some help information.

- :confirm Indicates the prompter should take any input provided or use the default if the user entered nothing.

- :quote Indicates the prompter should take the following key-event as itself without any sort of command interpretation.

- :keep Indicates the prompter should preserve something.

- :y Indicates a short positive response

- :n Indicates a short negative response

Define a new logical key-event whenever:

1. The key-event concerned represents a general class of actions, and several commands may want to take a similar action of this type.

1. The exact key-event a command implementor chooses may generate violent taste disputes among users, and then the users can trivially change the command in their init files.

1. You are using `command-case` which prevents implementors from specifying non-standard characters for dispatching in otherwise possibly portable code, and you can define and set the logical key-event in a site dependent file where you can mention implementation dependent characters.

## The Echo Area

Hemlock provides a number of facilities for displaying information and prompting the user for it. Most of these work through a small area displayed at the bottom of the screen, called the Echo Area.

### Echo Area Functions

#### clear-echo-area

Function

                            clear-echo-area

##### Description

Clears the echo area.

#### message

Function

                            message control-string &rest; format-arguments

##### Description

#### loud-message

Function

                            loud-message control-string &rest; format-arguments

##### Description

Displays a message in the echo area, replacing previous contents if any. loud-message is like message, but it also beeps.

#### beep

Function

                            beep

##### Description

Gets the user's attention, typically by making a sound.

### Prompting Functions

Prompting functions can be used to obtain short one-line input from the user.

Cocoa note: Because of implementation restrictions, only one buffer at a time is allowed to read prompted input. If a prompting function is invoked while a prompting operation is already in effect in another buffer, the attempt fails, telling the user "Buffer xxx is already waiting for input".

Most of the prompting functions accept the following keyword arguments:

:must-exist

  If :must-exist has a non-nil value then the user is prompted until a valid response is obtained. If :must-exist is nil then return as a string whatever is input. The default is t.

:default

  If null input is given when the user is prompted then this value is returned. If no default is given then some input must be given before anything interesting will happen.

:default-string

  If a :default is given then this is a string to be printed to indicate what the default is. The default is some representation of the value for :default, for example for a buffer it is the name of the buffer.

:prompt

  This is the prompt string to display.

:help

  This is similar to :prompt, except that it is displayed when the help command is typed during input.

> This may also be a function. When called with no arguments, it should either return a string which is the help text or perform some action to help the user, returning nil.

#### prompt-for-buffer

Function

                            prompt-for-buffer &key; :prompt :help :must-exist :default :default-string

##### Description

Prompts with completion for a buffer name and returns the corresponding buffer. If must-exist is nil, then it returns the input string if it is not a buffer name. This refuses to accept the empty string as input when :default and :default-string are nil. :default-string may be used to supply a default buffer name when:default is nil, but when :must-exist is non-nil, it must name an already existing buffer.

#### prompt-for-key-event

Function

                            prompt-for-key-event &key; :prompt :help

##### Description

This function prompts for a key-event returning immediately when the user types the next key-event. command-case is more useful for most purposes. When appropriate, use logical key-events.

#### prompt-for-key

Function

                            prompt-for-key &key; :prompt :help :must-exist :default :default-string

##### Description

This function prompts for a key, a vector of key-events, suitable for passing to any of the functions that manipulate key bindings. If must-exist is true, then the key must be bound in the current environment, and the command currently bound is returned as the second value.

#### prompt-for-file

Function

                            prompt-for-file &key; :prompt :help :must-exist :default :default-string

##### Description

This function prompts for an acceptable filename. "Acceptable" means that it is a legal filename, and it exists if must-exist is non-nil. prompt-for-file returns a Common Lisp pathname. If the file exists as entered, then this returns it, otherwise it is merged with default as by merge-pathnames.

#### prompt-for-integer

Function

                            prompt-for-integer &key; :prompt :help :must-exist :default :default-string

##### Description

This function prompts for a possibly signed integer. If must-exist is nil, then prompt-for-integer returns the input as a string if it is not a valid integer.

#### prompt-for-keyword

Function

                            prompt-for-keyword string-tables &key; :prompt :help :must-exist :default :default-string

##### Description

This function prompts for a keyword with completion, using the string tables in the list string-tables. If must-exist is non-nil, then the result must be an unambiguous prefix of a string in one of the string-tables, and the returns the complete string even if only a prefix of the full string was typed. In addition, this returns the value of the corresponding entry in the string table as the second value.

If must-exist is nil, then this function returns the string exactly as entered. The difference between prompt-for-keyword with must-exist nil, and prompt-for-string, is the user may complete the input using the Complete Parse and Complete Field commands.

#### prompt-for-expression

Function

                            prompt-for-expression &key; :prompt :help :must-exist :default :default-string

##### Description

This function reads a Lisp expression. If must-exist is nil, and a read error occurs, then this returns the string typed.

#### prompt-for-string

Function

                            prompt-for-string &key; :prompt :help :default :default-string

##### Description

This function prompts for a string; this cannot fail.

#### prompt-for-variable

Function

                            prompt-for-variable &key; :prompt :help :must-exist :default :default-string

##### Description

This function prompts for a variable name. If must-exist is non-nil, then the string must be a variable defined in the current environment, in which case the symbol name of the variable found is returned as the second value.

#### prompt-for-y-or-n

Function

                            prompt-for-y-or-n &key; :prompt :help :must-exist :default :default-string

##### Description

This prompts for logical key events :Y or :N, returning t or nil without waiting for confirmation. When the user types a confirmation key, this returns default if it is supplied. If must-exist is nil, this returns whatever key-event the user first types; however, if the user types one of the above key-events, this returns t or nil. This is analogous to the Common Lisp function y-or-n-p.

#### prompt-for-yes-or-no

Function

                            prompt-for-yes-or-no &key; :prompt :help :must-exist :default :default-string

##### Description

This function is to prompt-for-y-or-n as yes-or-no-p is to y-or-n-p. "Yes" or "No" must be typed out in full and confirmation must be given.

#### command-case

Macro

                            command-case ({key value}*){({({tag}*) | tag} help {form}*)}*

##### Description

This macro is analogous to the Common Lisp case macro. Commands such as Help use this to get a key-event, translate it to a character, and then to dispatch on the character to some case. In addition to character dispatching, this supports logical key-events by using the input key-event directly without translating it to a character. Since the description of this macro is rather complex, first consider the following example:

    (defcommand "Save All Buffers" (p)
      "Give the User a chance to save each modified buffer."
      (dolist (b *buffer-list*)
        (select-buffer-command () b)
        (when (buffer-modified b)
          (command-case (:prompt "Save this buffer: [Y] "
    			     :help "Save buffer, or do something else:")
    	((:yes :confirm)
    	 "Save this buffer and go on to the next."
    	 (save-file-command () b))
    	(:no "Skip saving this buffer, and go on to the next.")
    	((:exit #\p) "Punt this silly loop."
    	 (return nil))))))

command-case prompts for a key-event and then executes the code in the first branch with a logical key-event or a character (called tags) matching the input. Each character must be a standard-character, one that satisfies the Common Lisp standard-char-p predicate, and the dispatching mechanism compares the input key-event to any character tags by mapping the key-event to a character with ext:key-event-char. If the tag is a logical key-event, then the search for an appropriate case compares the key-event read with the tag using logical-key-event-p.

All uses of command-case have two default cases, :help and :abort. You can override these easily by specifying your own branches that include these logical key-event tags. The :help branch displays in a pop-up window the a description of the valid responses using the variously specified help strings. The :abort branch signals an editor-error.

The key/value arguments control the prompting. The following are valid values:

:help

  The default :help case displays this string in a pop-up window. In addition it formats a description of the valid input including each case's help string.

:prompt

  This is the prompt used when reading the key-event.

:bind

  This specifies a variable to which the prompting mechanism binds the input key-event. Any case may reference this variable. If you wish to know what character corresponds to the key-event, use key-event-char.

Instead of specifying a tag or list of tags, you may use t. This becomes the default branch, and its forms execute if no other branch is taken, including the default :help and :abort cases. This option has no helpstring, and the default :help case does not describe the default branch. Every command-case has a default branch; if none is specified, the macro includes one that beep's and reprompt's (see below).

Within the body of command-case, there is a defined reprompt macro. It causes the prompting mechanism and dispatching mechanism to immediately repeat without further execution in the current branch.

### Control of Parsing Behavior

#### Beep On Ambiguity

Hemlock Variable

                            Beep On Ambiguity (initial value t)

##### Description

If this variable is true, then an attempt to complete a parse which is ambiguous will result in a "beep".

### Defining New Prompting Functions

Prompting functionality is implemented by the function parse-for-something in cooperation with commands defined in "Echo Area" mode on the buffer associated with the echo area. You can implement new prompting functions by invoking parse-for-something with appropriate arguments.

#### parse-for-something

Function

                            parse-for-something &key;

##### Description

This function enters a mode reading input from the user and echoing it in the echo area, and returns a value when done. The input is managed by commands bound in "Echo Area" mode on the buffer associated with the echo area. The following keyword arguments are accepted:

`:verification-function`

  This is invoked by the Confirm Parse command. It does most of the work when parsing prompted input. Confirm Parse calls it with one argument, which is the string that the user typed so far. The function should return a list of values which are to be the result of the recursive edit, or nil indicating that the parse failed. In order to return zero values, a non-nil second value may be returned along with a nil first value.

`:string-tables`

  This is the list of string-tables, if any, that pertain to this parse.

`:value-must-exist`

  This is referred to by the verification function, and possibly some of the commands.

`:default`

  The string representing the default object when prompting the user. Confirm Parse supplies this to the parse verification function when the user input is empty.

`:default-string`

  When prompting the user, if :default is not specified, Hemlock displays this string as a representation of the default object; for example, when prompting for a buffer, this argument would be a default buffer name.

`:type`

  The kind of parse, e.g. :file, :keyword, :string. This tells the completion commands how to do completion, with :string disabling completion.

`:prompt`

  The prompt to display to the user.

`:help`

  The help string or function being used for the current parse.

### Some Echo Area Commands

These are some of the Echo Area commands that coordinate with the prompting routines. Hemlock binds other commands specific to the Echo Area, but they are uninteresting to mention here, such as deleting to the beginning of the line or deleting backwards a word.

#### Help On Parse

Command

                            Help On Parse (bound to Home, C-_ in Echo Area mode)

##### Description

Display the help text for the parse currently in progress.

#### Complete Keyword

Command

                            Complete Keyword (bound to Escape in Echo Area mode)

##### Description

This attempts to complete the current region. It signals an editor-error if the input is ambiguous or incorrect.

#### Complete Field

Command

                            Complete Field (bound to Space in Echo Area mode)

##### Description

Similar to `Complete Keyword`, but only attempts to complete up to and including the first character in the keyword with a non-zero :parse-field-separator attribute. If there is no field separator then attempt to complete the entire keyword. If it is not a keyword parse then just self-insert.

#### Confirm Parse

Command

                            Confirm Parse (bound to Return in Echo Area mode)

##### Description

Call the verification function with the current input. If it returns a non-nil value then that is returned as the value of the parse. A parse may return a nil value if the verification function returns a non-nil second value.

## Files

This chapter discusses ways to read and write files at various levels---at marks, into regions, and into buffers. This also treats automatic mechanisms that affect the state of buffers in which files are read.

### File Options and Type Hooks

The user specifies file options with a special syntax on the first line of a file. If the first line contains the string "-*-", then Hemlock interprets the text between the first such occurrence and the second, which must be contained in one line , as a list of "option: value" pairs separated by semicolons. The following is a typical example:

    ;;; -*- Mode: Lisp, Editor; Package: Hemlock -*-

See the Hemlock User's Manual for more details and predefined options.

File type hooks are executed when Hemlock reads a file into a buffer based on the type of the pathname. When the user specifies a Mode file option that turns on a major mode, Hemlock ignores type hooks. This mechanism is mostly used as a simple means for turning on some appropriate default major mode.

#### define-file-option

Macro

                            define-file-option name (buffer value) {declaration}* {form}*

##### Description

This defines a new file option with the string name name. Buffer and value specify variable names for the buffer and the option value string, and forms are evaluated with these bound.

#### define-file-type-hook

Macro

                            define-file-type-hook type-list (buffer type) {declaration}* {form}*

##### Description

This defines some code that process-file-options(below) executes when the file options fail to set a major mode. This associates each type, a string, in type-list with a routine that binds buffer to the buffer the file is in and type to the type of the pathname.

#### process-file-options

Function

                            process-file-options buffer &optional; pathname

##### Description

This checks for file options in buffer and invokes handlers if there are any. Pathname defaults to buffer's pathname but may be nil. If there is no Mode file option that specifies a major mode, and pathname has a type, then this tries to invoke the appropriate file type hook. read-buffer-file calls this.

### Pathnames and Buffers

There is no good way to uniquely identify buffer names and pathnames. However, Hemlock has one way of mapping pathnames to buffer names that should be used for consistency among customizations and primitives. Independent of this, Hemlock provides a means for consistently generating prompting defaults when asking the user for pathnames.

#### pathname-to-buffer-name

Function

                            pathname-to-buffer-name pathname

##### Description

This function returns a string of the form "file-namestring directory-namestring".

#### Pathname Defaults

Hemlock Variable

                            Pathname Defaults (initial value (pathname "gazonk.del"))

##### Description

#### Last Resort Pathname Defaults Function

Hemlock Variable

                            Last Resort Pathname Defaults Function

##### Description

#### Last Resort Pathname Defaults

Hemlock Variable

                            Last Resort Pathname Defaults (initial value (pathname "gazonk"))

##### Description

These variables control the computation of default pathnames when needed for promting the user. Pathname Defaults is a sticky default. See the Hemlock User's Manual for more details.

#### buffer-default-pathname

Function

                            buffer-default-pathname buffer

##### Description

This returns Buffer Pathname if it is bound. If it is not bound, and buffer's name is composed solely of alphnumeric characters, then return a pathname formed from buffer's name. If buffer's name has other characters in it, then return the value of Last Resort Pathname Defaults Function called on buffer.

### File Groups

Currently Hemlock doesn't have support for file groups.

### File Reading and Writing

Common Lisp pathnames are used by the file primitives. For probing, checking write dates, and so forth, all of the Common Lisp file functions are available.

#### read-file

Function

                            read-file pathname mark

##### Description

This inserts the file named by pathname at mark.

#### write-file

Function

                            write-file region pathname &key; :keep-backup :append

##### Description

#### Keep Backup Files

Hemlock Variable

                            Keep Backup Files (initial value nil)

##### Description

This function writes the contents of region to the file named by pathname. This writes region using a stream as if it were opened with :if-exists supplied as :rename-and-delete.

When keep-backup, which defaults to the value of Keep Backup Files, is non-nil, this opens the stream as if :if-exists were :rename. If append is non-nil, this writes the file as if it were opened with:if-exists supplied as :append.

This signals an error if both append and keep-backup are supplied as non-nil.

#### write-buffer-file

Function

                            write-buffer-file buffer pathname

##### Description

#### Write File Hook

Hemlock Variable

                            Write File Hook

##### Description

#### Add Newline at EOF on Writing File

Hemlock Variable

                            Add Newline at EOF on Writing File (initial value :ask-user)

##### Description

write-buffer-file writes buffer to the file named by pathname including the following:

- It assumes pathname is somehow related to buffer's pathname: if the buffer's write date is not the same as pathname's, then this prompts the user for confirmation before overwriting the file.

- It consults Add Newline at EOF on Writing File (see Hemlock User's Manual for possible values) and interacts with the user if necessary.

- It sets Pathname Defaults, and after using write-file, marks buffer unmodified.

- It updates Buffer's pathname and write date.

- It renames the buffer according to the new pathname if possible.

- It invokes Write File Hook.

Write File Hook is a list of functions that take the newly written buffer as an argument.

#### read-buffer-file

Function

                            read-buffer-file pathname buffer

##### Description

#### Read File Hook

Hemlock Variable

                            Read File Hook

##### Description

read-buffer-file deletes buffer's region and uses read-file to read pathname into it, including the following:

- It sets buffer's write date to the file's write date if the file exists; otherwise, it messages that this is a new file and sets buffer's write date to nil.

- It moves buffer's point to the beginning.

- It sets buffer's unmodified status.

- It sets buffer's pathname to the result of probing pathname if the file exists; otherwise, this function sets buffer's pathname to the result of merging pathname with default-directory.

- It sets Pathname Defaults to the result of the previous item.

- It processes the file options.

- It invokes Read File Hook.

Read File Hook is a list functions that take two arguments---the buffer read into and whether the file existed, t if so.

## Hemlock's Lisp Environment

This chapter is sort of a catch all for any functions and variables which concern Hemlock's interaction with the outside world.

### Entering and Leaving the Editor

#### ed

Function

                            ed &optional; x

##### Description

This a standard Common Lisp function. If x is supplied and is a string or pathname, the file specified by x is visited in a hemlock view (opening a new window if necessary, otherwise bringing an existing window with the file to the front), and the hemlock view object is the return value from the function.

If x is null, a new empty hemlock view is created and returned.

If x is a symbol or a setf function name, it attempts to edit the definition of the name. In this last case, the function returns without waiting for the operation to complete (for example, it might put up a non-modal dialog asking the user to select one of multiple definitions) and hence the return value is always NIL.

### Keyboard Input

#### *key-event-history*

Variable

                            *key-event-history*

##### Description

This is a Hemlock ring buffer that holds the last 60 key-events received.

#### last-key-event-typed

Function

                            last-key-event-typed

##### Description

This function returns the last key-event the user typed to invoke the current command.

#### last-char-typed

Function

                            last-char-typed

##### Description

This function returns the character corresponding to the last key event typed.

### Hemlock Streams

It is possible to create streams which output to or get input from a buffer. This mechanism is quite powerful and permits easy interfacing of Hemlock to Lisp.

Note that operations on these streams operate directly on buffers, therefore they have the same restrictions as described here for interacting with buffers from outside of the GUI thread.

#### make-hemlock-output-stream

Function

                            make-hemlock-output-stream mark &optional; buffered

##### Description

This function returns a stream that inserts at mark all output directed to it. It works best if mark is a left-inserting mark. Buffered controls whether the stream is buffered or not, and its valid values are the following keywords:

:none

  No buffering is done. This is the default.

:line

  The buffer is flushed whenever a newline is written or when it is explicitly done with force-output.

:full

  The stream is only brought up to date when it is explicitly done with force-output

#### hemlock-output-stream-p

Function

                            hemlock-output-stream-p object

##### Description

This function returns t if object is a hemlock-output-stream object.

#### make-hemlock-region-stream

Function

                            make-hemlock-region-stream region

##### Description

This function returns a stream from which the text in region can be read.

#### hemlock-region-stream-p

Function

                            hemlock-region-stream-p object

##### Description

This function returns t if object is a hemlock-region-stream object.

#### with-input-from-region

Macro

                            with-input-from-region (var region) {declaration}* {form}*

##### Description

While evaluating forms, binds var to a stream which returns input from region.

#### with-output-to-mark

Macro

                            with-output-to-mark (var mark [buffered]) {declaration}* {form}*

##### Description

During the evaluation of the forms, binds var to a stream which inserts output at the permanent mark. Buffered has the same meaning as for make-hemlock-output-stream.

#### with-pop-up-display

Macro

                            with-pop-up-display (var &key; height name) {declaration}* {form}*

##### Description

This macro executes forms in a context with var bound to a stream. Hemlock collects output to this stream and tries to pop up a display of the appropriate height containing all the output. When height is supplied, Hemlock creates the pop-up display immediately, forcing output on line breaks. This is useful for displaying information of temporary interest.

### Interface to the Error System

Hemlock commands are executed from an event handler in the initial Cocoa thread. They are executed within a ccl::with-standard-abort-handling form, which means cl:abort, ccl:abort-break, ccl:throw-cancel will abort the current command only and exit the event handler in an orderly fashion.

In addition, for now, lisp errors during command execution dump a backtrace in the system console and are otherwise handled as if by `handle-lisp-errors` below, which means it is not possible to debug errors at the point of the error. Once &CCL; has better support for debugging errors in the initial Cocoa thread, better Hemlock error handling will be provided that will allow for some way to debug.

#### editor-error

Function

                            editor-error &rest; args

##### Description

This function is called to report minor errors to the user. These are errors that a normal user could encounter in the course of editing, such as a search failing or an attempt to delete past the end of the buffer. This function simply aborts the current command. Any args specified are used to format an error message to be placed in the echo area. This function never returns.

#### handle-lisp-errors

Macro

                            handle-lisp-errors {form}*

##### Description

Within the body of this macro any Lisp errors that occur are handled by displaying an error message in a dialog and aborting the current command, leaving the error text in the echo area. This macro should be wrapped around code which may get an error due to some action of the user --- for example, evaluating code fragments on the behalf of and supplied by the user.

### Definition Editing

Hemlock provides commands for finding the definition of a function or variable and placing the user at the definition in a buffer. A function is provided to allow invoking this functionality outside of Hemlock. Note that this function is unusual in that it is it is safe to call outside of the command interpreter, and in fact it can be called from any thread.

#### edit-definition

Function

                            edit-definition name

##### Description

This function tries to find the definition of `name`, create or activate the window containing it, and scroll the view to show the definition. If there are multiple definitions available, the user is given a choice of which one to use. This function may return before the operation is complete.

### Event Scheduling

No Event Scheduling functionality is provided at this time.

### Miscellaneous

#### in-lisp

Function

                            in-lisp {form}*

##### Description

This evaluates forms inside handle-lisp-errors. It also binds *package* to the package named by Current Package if it is non-nil. Use this when evaluating Lisp code on behalf of the user.

#### do-alpha-chars

Macro

                            do-alpha-chars (var kind [result]) {form}*

##### Description

This iterates over alphabetic characters in Common Lisp binding var to each character in order as specified under character relations in Common Lisp the Language. Kind is one of:lower, :upper, or :both. When the user supplies :both, lowercase characters are processed first.

## High-Level Text Primitives

This chapter discusses primitives that operate on higher level text forms than characters and words. For English text, there are functions that know about sentence and paragraph structures, and for Lisp sources, there are functions that understand this language. This chapter also describes mechanisms for organizing file sections into logical pages and for formatting text forms.

### Indenting Text

#### Indent Function

Hemlock Variable

                            Indent Function       (initial value tab-to-tab-stop)

##### Description

The value of this variable determines how indentation is done, and it is a function which is passed a mark as its argument. The function should indent the line that the mark points to. The function may move the mark around on the line. The mark will be :left-inserting. The default simply inserts a tab character at the mark. A function for Lisp mode probably moves the mark to the beginning of the line, deletes horizontal whitespace, and computes some appropriate indentation for Lisp code.

#### Indent with Tabs

Hemlock Variable

                            Indent with Tabs (initial value nil)

##### Description

#### Spaces per Tab

Hemlock Variable

                            Spaces per Tab        (initial value 8)

##### Description

Indent with Tabs should be true if indenting should use tabs whenever possible. If nil, the default, it only uses spaces. Spaces per Tab defines the size of a tab.

#### indent-region

Function

                            indent-region         region

##### Description

#### indent-region-for-commands

Function

                            indent-region-for-commands    region

##### Description

indent-region invokes the value of Indent Function on every line of region. indent-region-for-commands uses indent-region but first saves the region for the Undo command.

#### delete-horizontal-space

Function

                            delete-horizontal-space       mark

##### Description

This deletes all characters on either side of mark with a Space attribute (see System Defined Character Attributes) of 1.

### Lisp Text Buffers

Hemlock bases its Lisp primitives on parsing a block of the buffer and annotating lines as to what kind of Lisp syntax occurs on the line or what kind of form a mark might be in (for example, string, comment, list, etc.). These do not work well if the block of parsed forms is exceeded when moving marks around these forms, but the block that gets parsed is somewhat programmable.

There is also a notion of a top level form which this documentation often uses synonymously with defun, meaning a Lisp form occurring in a source file delimited by parentheses with the opening parenthesis at the beginning of some line. The names of the functions include this inconsistency.

#### pre-command-parse-check

Function

                            pre-command-parse-check       mark for-sure

##### Description

#### Parse Start Function

Hemlock Variable

                            Parse Start Function  (initial value start-of-parse-block)

##### Description

#### Parse End Function

Hemlock Variable

                            Parse End Function    (initial value end-of-parse-block)

##### Description

#### Minimum Lines Parsed

Hemlock Variable

                            Minimum Lines Parsed          (initial value 50)

##### Description

#### Maximum Lines Parsed

Hemlock Variable

                            Maximum Lines Parsed          (initial value 500)

##### Description

#### Defun Parse Goal

Hemlock Variable

                            Defun Parse Goal      (initial value 2)

##### Description

pre-command-parse-check calls Parse Start Function and Parse End Function on mark to get two marks. It then parses all the lines between the marks including the complete lines they point into. When for-sure is non-nil, this parses the area regardless of any cached information about the lines. Every command that uses the following routines calls this before doing so.

The default values of the start and end variables use Minimum Lines Parsed, Maximum Lines Parsed, and Defun Parse Goal to determine how big a region to parse. These two functions always include at least the minimum number of lines before and after the mark passed to them. They try to include Defun Parse Goal number of top level forms before and after the mark passed them, but these functions never return marks that include more than the maximum number of lines before or after the mark passed to them.

#### form-offset

Function

                            form-offset   mark count

##### Description

This tries to move mark count forms forward if positive or -count forms backwards if negative. Mark is always moved. If there were enough forms in the appropriate direction, this returns mark, otherwise nil.

#### top-level-offset

Function

                            top-level-offset      mark count

##### Description

This tries to move mark count top level forms forward if positive or -count top level forms backwards if negative. If there were enough top level forms in the appropriate direction, this returns mark, otherwise nil. Mark is moved only if this is successful.

#### mark-top-level-form

Function

                            mark-top-level-form   mark1 mark2

##### Description

This moves mark1 and mark2 to the beginning and end, respectively, of the current or next top level form. Mark1 is used as a reference to start looking. The marks may be altered even if unsuccessful. If successful, return mark2, else nil. Mark2 is left at the beginning of the line following the top level form if possible, but if the last line has text after the closing parenthesis, this leaves the mark immediately after the form.

#### defun-region

Function

                            defun-region          mark

##### Description

This returns a region around the current or next defun with respect to mark. Mark is not used to form the region. If there is no appropriate top level form, this signals an editor-error. This calls pre-command-parse-check first.

#### inside-defun-p

Function

                            inside-defun-p        mark

##### Description

#### start-defun-p

Function

                            start-defun-p         mark

##### Description

These return, respectively, whether mark is inside a top level form or at the beginning of a line immediately before a character whose Lisp Syntax (see System Defined Character Attributes) value is :opening-paren.

#### forward-up-list

Function

                            forward-up-list       mark

##### Description

#### backward-up-list

Function

                            backward-up-list      mark

##### Description

Respectively, these move mark immediately past a character whose Lisp Syntax (see System Defined Character Attributes) value is :closing-paren or immediately before a character whose Lisp Syntax value is :opening-paren.

#### valid-spot

Function

                            valid-spot    mark forwardp

##### Description

This returns t or nil depending on whether the character indicated by mark is a valid spot. When forwardp is set, use the character after mark and vice versa. Valid spots exclude commented text, inside strings, and character quoting.

#### defindent

Function

                            defindent     name count

##### Description

This defines the function with name to have count special arguments. indent-for-lisp, the value of Indent Function in Lisp mode, uses this to specially indent these arguments. For example, do has two, with-open-file has one, etc. There are many of these defined by the system including definitions for special Hemlock forms. Name is a simple-string, case insensitive and purely textual (that is, not read by the Lisp reader); therefore, "with-a-mumble" is distinct from "mumble:with-a-mumble".

### English Text Buffers

This section describes some routines that understand basic English language forms.

#### word-offset

Function

                            word-offset   mark count

##### Description

This moves mark count words forward (if positive) or backwards (if negative). If mark is in the middle of a word, that counts as one. If there were count (-count if negative) words in the appropriate direction, this returns mark, otherwise nil. This always moves mark. A word lies between two characters whose Word Delimiter attribute value is 1 (see System Defined Character Attributes).

#### sentence-offset

Function

                            sentence-offset       mark count

##### Description

This moves mark count sentences forward (if positive) or backwards (if negative). If mark is in the middle of a sentence, that counts as one. If there were count (-count if negative) sentences in the appropriate direction, this returns mark, otherwise nil. This always moves mark.

A sentence ends with a character whose Sentence Terminator attribute is 1 followed by two spaces, a newline, or the end of the buffer. The terminating character is optionally followed by any number of characters whose Sentence Closing Char attribute is 1. A sentence begins after a previous sentence ends, at the beginning of a paragraph, or at the beginning of the buffer.

#### paragraph-offset

Function

                            paragraph-offset      mark count &optional; prefix

##### Description

#### Paragraph Delimiter Function

Hemlock Variable

                            Paragraph Delimiter Function          (initial value )

##### Description

This moves mark count paragraphs forward (if positive) or backwards (if negative). If mark is in the middle of a paragraph, that counts as one. If there were count (-count if negative) paragraphs in the appropriate direction, this returns mark, otherwise nil. This only moves mark if there were enough paragraphs.

Paragraph Delimiter Function holds a function that takes a mark, typically at the beginning of a line, and returns whether or not the current line should break the paragraph. default-para-delim-function returns t if the next character, the first on the line, has a Paragraph Delimiter attribute value of 1. This is typically a space, for an indented paragraph, or a newline, for a block style. Some modes require a more complicated determinant; for example, Scribe modes adds some characters to the set and special cases certain formatting commands.

Prefix defaults to Fill Prefix, and the right prefix is necessary to correctly skip paragraphs. If prefix is non-nil, and a line begins with prefix, then the scanning process skips the prefix before invoking the Paragraph Delimiter Function. Note, when scanning for paragraph bounds, and prefix is non-nil, lines are potentially part of the paragraph regardless of whether they contain the prefix; only the result of invoking the delimiter function matters.

The programmer should be aware of an idiom for finding the end of the current paragraph. Assume paragraphp is the result of moving mark one paragraph, then the following correctly determines whether there actually is a current paragraph:

    (or paragraphp
      (and (last-line-p mark)
           (end-line-p mark)
           (not (blank-line-p (mark-line mark)))))

In this example mark is at the end of the last paragraph in the buffer, and there is no last newline character in the buffer. paragraph-offset would have returned nil since it could not skip any paragraphs since mark was at the end of the current and last paragraph. However, you still have found a current paragraph on which to operate. mark-paragraph understands this problem.

#### mark-paragraph

Function

                            mark-paragraph        mark1 mark2

##### Description

This marks the next or current paragraph, setting mark1 to the beginning and mark2 to the end. This uses Fill Prefix. Mark1 is always on the first line of the paragraph, regardless of whether the previous line is blank. Mark2 is typically at the beginning of the line after the line the paragraph ends on, this returns mark2 on success. If this cannot find a paragraph, then the marks are left unmoved, and nil is returned.

### Logical Pages

Logical pages are not supported at this time.

### Filling

Filling is an operation on text that breaks long lines at word boundaries before a given column and merges shorter lines together in an attempt to make each line roughly the specified length. This is different from justification which tries to add whitespace in awkward places to make each line exactly the same length. Hemlock's filling optionally inserts a specified string at the beginning of each line. Also, it eliminates extra whitespace between lines and words, but it knows two spaces follow sentences.

#### Fill Column

Hemlock Variable

                            Fill Column   (initial value 75)

##### Description

#### Fill Prefix

Hemlock Variable

                            Fill Prefix   (initial value nil)

##### Description

These variables hold the default values of the prefix and column arguments to Hemlock's filling primitives. If Fill Prefix is nil, then there is no fill prefix.

#### fill-region

Function

                            fill-region   region &optional; prefix column

##### Description

This deletes any blank lines in region and fills it according to prefix and column. Prefix and column default to Fill Prefix and Fill Column.

#### fill-region-by-paragraphs

Function

                            fill-region-by-paragraphs     region &optional; prefix column

##### Description

This finds paragraphs within region and fills them with fill-region. This ignores blank lines between paragraphs. Prefix and column default to Fill Prefix and Fill Column.

## Utilities

This chapter describes a number of utilities for manipulating some types of objects Hemlock uses to record information. String-tables are used to store names of variables, commands, modes, and buffers. Ring lists can be used to provide a kill ring, recent command history, or other user-visible features.

### String-table Functions

String tables are similar to Common Lisp hash tables in that they associate a value with an object. There are a few useful differences: in a string table the key is always a case insensitive string, and primitives are provided to facilitate keyword completion and recognition. Any type of string may be added to a string table, but the string table functions always return simple-string's.

A string entry in one of these tables may be thought of as being separated into fields or keywords. The interface provides keyword completion and recognition which is primarily used to implement some Echo Area commands. These routines perform a prefix match on a field-by-field basis allowing the ambiguous specification of earlier fields while going on to enter later fields. While string tables may use any string-char as a separator, the use of characters other than space may make the Echo Area commands fail or work unexpectedly.

#### make-string-table

Function

                            make-string-table

##### Description

This function creates an empty string table that uses separator as the character, which must be a string-char, that distinguishes fields. Initial-contents specifies an initial set of strings and their values in the form of a dotted a-list, for example:

    '(("Global" . t) ("Mode" . t) ("Buffer" . t))

#### string-table-p

Function

                            string-table-p  	string-table

##### Description

This function returns t if string-table is a string-table object, otherwise nil.

#### string-table-separator

Function

                            string-table-separator  	string-table

##### Description

This function returns the separator character given to make-string-table.

#### delete-string

Function

                            delete-string  	string table

##### Description

#### clrstring

Function

                            clrstring  	table

##### Description

delete-string removes any entry for string from the string-table table, returning t if there was an entry. clrstring removes all entries from table.

#### getstring

Function

                            getstring  	string table

##### Description

This function returns as multiple values, first the value corresponding to the string if it is found and nil if it isn't, and second t if it is found and nil if it isn't.

This may be set with setf to add a new entry or to store a new value for a string. It is an error to try to insert a string with more than one field separator character occurring contiguously.

#### complete-string

Function

                            complete-string  	string tables

##### Description

This function completes string as far as possible over the list of tables, returning five values. It is an error for tables to have different separator characters. The five return values are as follows:

- The maximal completion of the string or nil if there is none.

- An indication of the usefulness of the returned string:

:none

  There is no completion of string.

:complete

  The completion is a valid entry, but other valid completions exist too. This occurs when the supplied string is an entry as well as initial substring of another entry.

:unique

  The completion is a valid entry and unique.

:ambiguous

  The completion is invalid; get-string would return nil and nil if given the returned string.

- The value of the string when the completion is :unique or :complete, otherwise nil.

- An index, or nil, into the completion returned, indicating where the addition of a single field to string ends. The command Complete Field uses this when the completion contains the addition to string of more than one field.

- An index to the separator following the first ambiguous field when the completion is :ambiguous or :complete, otherwise nil.

#### find-ambiguous

Function

                            find-ambiguous  	string table

##### Description

#### find-containing

Function

                            find-containing  	string table

##### Description

find-ambiguous returns a list in alphabetical order of all the strings in table matching string. This considers an entry as matching if each field in string, taken in order, is an initial substring of the entry's fields; entry may have fields remaining.

find-containing is similar, but it ignores the order of the fields in string, returning all strings in table matching any permutation of the fields in string.

#### do-strings

Macro

                            do-strings  	(string-var value-var table result) declaration tag statement

##### Description

This macro iterates over the strings in table in alphabetical order. On each iteration, it binds string-var to an entry's string and value-var to an entry's value.

### Ring Functions

There are various purposes in an editor for which a ring of values can be used, so Hemlock provides a general ring buffer type. It is used for maintaining a ring of killed regions, a ring of marks, or a ring of command strings which various modes and commands maintain as a history mechanism.

#### make-ring

Function

                            make-ring  	length &optional; delete-function

##### Description

Makes an empty ring object capable of holding up to length Lisp objects. Delete-function is a function that each object is passed to before it falls off the end. Length must be greater than zero.

#### ringp

Function

                            ringp  	ring

##### Description

Returns t if ring is a ring object, otherwise nil.

#### ring-length

Function

                            ring-length  	ring

##### Description

Returns as multiple-values the number of elements which ring currently holds and the maximum number of elements which it may hold.

#### ring-ref

Function

                            ring-ref  	ring index

##### Description

Returns the index'th item in the ring, where zero is the index of the most recently pushed. This may be set with setf.

#### ring-push

Function

                            ring-push  	object ring

##### Description

Pushes object into ring, possibly causing the oldest item to go away.

#### ring-pop

Function

                            ring-pop  	ring

##### Description

Removes the most recently pushed object from ring and returns it. If the ring contains no elements then an error is signalled.

#### rotate-ring

Function

                            rotate-ring  	ring offset

##### Description

With a positive offset, rotates ring forward that many times. In a forward rotation the index of each element is reduced by one, except the one which initially had a zero index, which is made the last element. A negative offset rotates the ring the other way.

### Undoing commands

No API to the undo facility is provided at this time.

## Miscellaneous

This chapter is somewhat of a catch-all for comments and features that don't fit well anywhere else.

### Key-events

#### Introduction

The canonical representation of editor input is a key-event structure. Users can bind commands to keys, which are non-empty sequences of key-events. A key-event consists of an identifying token known as a keysym and a field of bits representing modifiers. Users define keysyms by supplying names that reflect the legends on their keyboard's keys. Users define modifier names similarly, but the system chooses the bit and mask for recognizing the modifier. You can use keysym and modifier names to textually specify key-events and Hemlock keys in a #k syntax. The following are some examples:

    #k"C-u"
    #k"Control-u"
    #k"c-m-z"
    #k"control-x meta-d"
    #k"a"
    #k"A"
    #k"Linefeed"

This is convenient for use within code and in init files containing bind-key calls.

The #k syntax is delimited by double quotes, but the system parses the contents rather than reading it as a Common Lisp string. Within the double quotes, spaces separate multiple key-events. A single key-event optionally starts with modifier names terminated by hyphens. Modifier names are alphabetic sequences of characters which the system uses case-insensitively. Following modifiers is a keysym name, which is case-insensitive if it consists of multiple characters, but if the name consists of only a single character, then it is case-sensitive.

You can escape special characters --- hyphen, double quote, open angle bracket, close angle bracket, and space --- with a backslash, and you can specify a backslash by using two contiguously. You can use angle brackets to enclose a keysym name with many special characters in it. Between angle brackets appearing in a keysym name position, there are only two special characters, the closing angle bracket and backslash.

#### Interface

##### define-keysym

Function

                                define-keysym  	keysym preferred-name &rest; other-names

###### Description

This function establishes a mapping from preferred-name to keysym for purposes of #k syntax. Other-names also map to keysym, but the system uses preferred-name when printing key-events. The names are case-insensitive simple-strings; however, if the string contains a single character, then it is used case-sensitively. Redefining a keysym or re-using names has undefined effects.

Keysym can be any object, but generally it is either an integer representing the window-system code for the event, or a keyword which allows the mapping of the keysym to its code to be defined separately.

##### define-keysym-code

Function

                                define-keysym-code keysym code

###### Description

Defines the window-system code for the key event which in Hemlock is represented by keysym.

##### define-mouse-keysym

Function

                                define-mouse-keysym  	button keysym name shifted-bit event-key

###### Description

This function defines keysym named name for key-events representing mouse click events. Shifted-bit is a defined modifier name that translate-mouse-key-event sets in the key-event it returns whenever the shift bit is set in an incoming event.

##### name-keysym

Function

                                name-keysym  	name

###### Description

This function returns the keysym named name. If name is unknown, this returns nil.

##### keysym-names

Function

                                keysym-names  	keysym

###### Description

This function returns the list of all names for keysym. If keysym is undefined, this returns nil.

##### keysym-preferred-name

Function

                                keysym-preferred-name  	keysym

###### Description

This returns the preferred name for keysym, how it is typically printed. If keysym is undefined, this returns nil.

##### define-key-event-modifier

Function

                                define-key-event-modifier  	long-name short-name

###### Description

This establishes long-name and short-name as modifier names for purposes of specifying key-events in #k syntax. The names are case-insensitive strings. If either name is already defined, this signals an error.

The system defines the following default modifiers (first the long name, then the short name):

- "Hyper", "H"

- "Super", "S"

- "Meta", "M"

- "Control", "C"

- "Shift", "Shift"

- "Lock", "Lock"

##### *all-modifier-names*

Variable

                                *all-modifier-names*

###### Description

This variable holds all the defined modifier names.

##### make-key-event-bits

Function

                                make-key-event-bits  	&rest; modifier-names

###### Description

This function returns bits suitable for make-key-event from the supplied modifier-names. If any name is undefined, this signals an error.

##### key-event-modifier-mask

Function

                                key-event-modifier-mask  	modifier-name

###### Description

This function returns a mask for modifier-name. This mask is suitable for use with key-event-bits. If modifier-name is undefined, this signals an error.

##### key-event-bits-modifiers

Function

                                key-event-bits-modifiers  	bits

###### Description

This returns a list of key-event modifier names, one for each modifier set in bits.

##### make-key-event

Function

                                make-key-event  	object bits

###### Description

This function returns a key-event described by object with bits. Object is one of keysym, string, or key-event. When object is a key-event, this uses key-event-keysym. You can form bits with make-key-event-bits or key-event-modifier-mask.

##### key-event-p

Function

                                key-event-p  	object

###### Description

This function returns whether object is a key-event.

##### key-event-bits

Function

                                key-event-bits  	key-event

###### Description

This function returns the bits field of a key-event.

##### key-event-keysym

Function

                                key-event-keysym  	key-event

###### Description

This function returns the keysym field of a key-event.

##### char-key-event

Function

                                char-key-event  	character

###### Description

This function returns the key-event associated with character. You can associate a key-event with a character by setf-ing this form.

##### key-event-char

Function

                                key-event-char  	key-event

###### Description

This function returns the character associated with key-event. You can associate a character with a key-event by setf'ing this form. The system defaultly translates key-events in some implementation dependent way for text insertion; for example, under an ASCII system, the key-event #k"C-h", as well as #k"backspace" would map to the Common Lisp character that causes a backspace.

##### key-event-bit-p

Function

                                key-event-bit-p  	key-event bit-name

###### Description

This function returns whether key-event has the bit set named by bit-name. This signals an error if bit-name is undefined.

##### do-alpha-key-events

Macro

                                do-alpha-key-events  	(var kind &optional; result) form

###### Description

This macro evaluates each form with var bound to a key-event representing an alphabetic character. Kind is one of :lower, :upper, or :both, and this binds var to each key-event in order a-z A-Z. When :both is specified, this processes lowercase letters first.

##### pretty-key-string

Function

                                pretty-key-string  	key &optional; stream long-names-p

###### Description

This returns a string representing key, a key-event or vector of key-events, in a user-expected fashion. Long-names-p indicates whether modifiers should be described by their long or short name.