wiki:HemlockProgrammer/HemlockLispEnvironment

Version 1 (modified by rme, 6 years ago) (diff)

--

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

14.1. Entering and Leaving the Editor

ed &optional x [Function]

Entry Hook [Hemlock Variable]

ed enters the editor. It is basically as specified in Common Lisp. If x is supplied and is a symbol, the definition of x is put into a buffer, and that buffer is selected. If x is a pathname, the file specified by x is visited in a new buffer. If x is not supplied or nil, the editor is entered in the same state as when last exited.

The Entry Hook is invoked each time the editor is entered.

exit-hemlock &optional value [Function]

Exit Hook [Hemlock Variable]

exit-hemlock leaves Hemlock and return to Lisp; value is the value to return, which defaults to t. The hook Exit Hook (page 57) is invoked before this is done.

pause-hemlock [Function]

pause-hemlock suspends the editor process and returns control to the shell. When the process is resumed, it will still be running Hemlock.

14.2. Keyboard Input

Keyboard input interacts with a number of other parts of the editor. Since the command loop works by reading from the keyboard, keyboard input is the initial cause of everything that happens. Also, Hemlock redisplays in the low-level input loop when there is no available input from the user.

*editor-input* [Variable]

*real-editor-input* [Variable]

Input Hook [Hemlock Variable]

Abort Hook [Hemlock Variable]

*editor-input* is an object on which Hemlock's I/O routines operate. You can get input, clear input, return input, and listen for input. Input appears as key-events.

*real-editor-input* holds the initial value of *editor-input*. This is useful for reading from the user when *editor-input* is rebound (such as within a keyboard macro.)

Hemlock invokes the functions in Input Hook each time someone reads a key-event from *real-editor-input*. These take no arguments.

get-key-event editor-input &optional ignore-abort-attempts-p [Function]

This function returns a key-event as soon as it is available on editor-input. Editor-input is either *editor-input* or *real-editor-input*. Ignore-abort-attempts-p indicates whether C-g and C-G throw to the editor's top-level command loop; when this is non-nil, this function returns those key-events when the user types them. Otherwise, it aborts the editor's current state, returning to the command loop.

When the user aborts, Hemlock invokes the functions in Abort Hook. These functions take no arguments. When aborting, Hemlock ignores the Input Hook.

unget-key-event key-event editor-input [Function]

This function returns key-event to editor-input, so the next invocation of get-key-event will return key-event. If key-event is #k"C-g" or #k"C-G", then whether get-key-event returns it depends on that function's second argument. Editor-input is either *editor-input* or *real-editor-input*.

clear-editor-input editor-input [Function]

This function flushes any pending input on editor-input. Editor-input is either *editor-input* or *real-editor-input*.

listen-editor-inputeditor-input [Function]

This function returns whether there is any input available on editor-input. Editor-input is either *editor-input* or *real-editor-input*.

editor-sleep time [Function]

Return either after time seconds have elapsed or when input is available on *editor-input*.

*key-event-history* [Variable]

This is a Hemlock ring buffer (see page 70) that holds the last 60 key-events read from the keyboard.

*last-key-event-typed* [Variable]

Commands use this variable to realize the last key-event the user typed to invoke the commands. Before Hemlock ever reads any input, the value is nil. This variable usually holds the last key-event read from the keyboard, but it is also maintained within keyboard macros allowing commands to behave the same on each repetition as they did in the recording invocation.

*input-transcript* [Variable]

If this is non-nil then it should be an adjustable vector with a fill-pointer. When it is non-nil, Hemlock pushes all input read onto this vector.

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

make-hemlock-output-stream mark &optional buffered [Function]

hemlock-output-stream-p object [Function]

make-hemlock-output-stream returns a stream that inserts at the permanent mark mark all output directed to it. 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 screen is only brought up to date when it is explicitly done with force-output

hemlock-output-stream-p returns t if object is a hemlock-output-stream object.

make-hemlock-region-stream region [Function]

hemlock-region-stream-p object [Function]

make-hemlock-region-stream returns a stream from which the text in region can be read.

hemlock-region-stream-p returns t if object is a hemlock-region-stream object.

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

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

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

During the evaluation of theforms, bindsvarto a stream which inserts output at the permanent mark. Buffered has the same meaning as for make-hemlock-output-stream.

with-pop-up-display (var &keyheight name) {declaration}* {form}* [Macro]

*random-typeout-buffers* [Variable]

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. The system saves the output in a buffer named name, which defaults to Random Typeout. When the window is the incorrect height, the display mechanism will scroll the window with more-style prompting. This is useful for displaying information of temporary interest.

When a buffer with name name already exists and was not previously created by with-pop-up-display,Hemlock signals an error.

*random-typeout-buffers* is an association list mapping random typeout buffers to the streams that operate on the buffers.

14.4. Interface to the Error System

The error system interface is minimal. There is a simple editor-error condition which is a subtype of error and a convenient means for signaling them. Hemlock also provides a standard handler for error conditions while in the editor.

editor-error-format-string condition [Function]

editor-error-format-arguments condition [Function]

Handlers for editor-error conditions can access the condition object with these.

editor-error &rest args [Function]

This function is called to signal minor errors within Hemlock; 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 signals an editor-error condition formed from args, which are nil or a format string possibly followed by format arguments. Hemlock invokes commands in a dynamic context with an editor-error condition handler bound. This default handler beeps or flashes (or both) the display. If the condition passed to the handler has a non-nil string slot, the handler also invokes message on it. The command in progress is always aborted, and this function never returns.

handle-lisp-errors{form}* [Macro]

Within the body of this macro any Lisp errors that occur are handled in some fashion more gracefully than simply dumping the user in the debugger. 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. Using this in a command allows the established handler to shadow the default editor-error handler, so commands should take care to signal user errors (calls to editor-errors) outside of this context.

14.5. Definition Editing

Hemlock provides commands for finding the definition of a function, macro, or command and placing the user at the definition in a buffer. This, of course, is implementation dependent, and if an implementation does not associate a source file with a routine, or if Hemlock cannot get at the information, then these commands do not work. If the Lisp system does not store an absolute pathname, independent of the machine on which the maintainer built the system, then users need a way of translating a source pathname to one that will be able to locate the source.

add-definition-dir-translation dir1 dir2 [Function]

This maps directory pathname dir1 to dir2. Successive invocations using the same dir1 push into a translation list. When Hemlock seeks a definition source file, and it has a translation, then it tries the translations in order. This is useful if your sources are on various machines, some of which may be down. When Hemlock tries to find a translation, it first looks for translations of longer directory pathnames, finding more specific translations before shorter, more general ones.

delete-definition-dir-translation dir [Function]

This deletes the mapping of dir to all directories to which it has been mapped.

14.6. Event Scheduling

The mechanism described in this chapter is only operative when the Lisp process is actually running inside of Hemlock, within the ed function. The designers intended its use to be associated with the editor, such as with auto-saving files, reminding the user, etc.

schedule-event time function &optional repeat [Function]

This causes Hemlock to call function after time seconds have passed, optionally repeating every time seconds. Repeat defaults to t. This is a rough mechanism since commands can take an arbitrary amount of time to run; Hemlock invokes function at the first possible moment after time has elapsed. Function takes the time in seconds that has elapsed since the last time it was called (or since it was scheduled for the first invocation).

remove-scheduled-eventfunction [Function]

This removes function from the scheduling queue. Function does not have to be in the queue.

14.7. Miscellaneous

in-lisp{form}* [Function]

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 (var kind [result) {form}*] [Macro]

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.