At the moment, we are using the standard emacs-based interface for
user input. However, we intend to replace it as soon as the
rest of the implementation is stable.
What's wrong with the emacs interface?
Interfaces based on emacs are wonderful on vt100 terminals. The user
has command-line editing and parenthesis balancing, can cut and past parts
of forms, and can interact with scheme and edit files at the same time.
These interfaces are a significant improvement on a raw tty window.
In an X-window environment, however, emacs interfaces have outlived
their usefulness. One problem is that emacs is providing duplicative,
less powerful, versions of services already provided elsewhere:
- a lisp interpreter (a better one is provided by scheme48)
- a primitive multiple-window system (a better one is provided by X)
- a news reader and a manual system (being supplanted by programs
such as netscape)
This helps make the emacs process far too large for the service it is
providing, particularly when running a finished application.
Furthermore, the emacs interface to lisp seems primitive compared to
newly built X interfaces for other programs:
- Only limited use is made of color.
- Input is only accepted from the keyboard, not from the mouse.
- Balancing parentheses are displayed dynamically by cursor blinking.
It would be nicer if the code structure was always visible. For example,
one might assign a bright color to each matching pair of parentheses.
Different colors might be assigned in rotation or on the basis of what
operator heads the form (e.g. do forms might be consistently green).
- Commands to the interpreter are entered as if they were
forms, requiring bizarre syntax to distinguish them from forms.
- Input and output are confused in a single window. Successive
input and output forms are run together, not separated by solid markers.
The same key is used
to indicate the end of a line and the end of a form. This places a great
burden on the software parsing the contents of the window. In practice,
it is easy to confuse the emacs-lisp interface (e.g. both in Franz Common
Lisp and in Scheme48).
- Code must be edited using emacs, even if that is not the user's favorite
A better solution
Our final system will have three components:
- a user front-end processor,
- the scheme process, running its usual interpreter loop, and
- the image coprocessor.
The user front-end watches the keyboard, the mouse, and any other
input devices. It obtains the following types of input items:
- mouse events for windows created by the coprocessor (when requested),
- completed forms from the form editor (which should not dispatch forms
unless parentheses are balanced and the user has indicated completion), and
- completed commands (e.g. for loading a file).
It arranges the completed items in a linear order, which should be as
close as possible to the order in which they were completed. X
windows events from different devices sometimes appear out of order,
so perfect temporal ordering is not possible. Non-form items are
translated into scheme forms. Finally, the forms are shipped, in
order, to the scheme interpreter.
The front-end will also store a history of the interpreter's behavior.
This internal representation should follow the logical structure of
the session, distinguishing user input, values of forms, and text
printed on the standard output. A graphical display of this
information should be presented to the user (the "history window").
The user front-end should support at least the following features.
- There should be a simple form editor, using the same
keystrokes as emacs whenever possible, and including static
indication of balancing parentheses.
- The CR/ENTER key should be used only to end a line, not to indicate
completion of the form. A distinct key (perhaps SHIFT-ENTER)
and/or mouse button should be used for this purpose.
- There should be a set of mouse buttons that bring up menus of commands
for the scheme interpreter, such as exit, interrupt, load file, restart scheme.
- There should be keystroke equivalents for all mouse-based commands.
- The interpreter history window should respond to up/down arrow keys and
page up/down buttons in the standard way. (If the implementer is ambitious,
it might also have a scroll bar.)
- It should be possible to save the session to a file. The file
format should be easy for a human to read and
preserve the logical structure of the session (not
mimic the way the session was displayed graphically).
- It should be possible to re-run the input commands from a saved
session. It should be possible to create new scripts, either by
editing saved sessions or by writing them by hand (in a text editor, not
in this interface!).
- All text sub-windows should respond to X select (cut-and-paste) in
the standard way.
- It should be possible to add, remove, and list
rules for translating mouse events into scheme forms, for each
window created by the coprocessor.
- It should be possible (e.g. via mouse buttons) to sheet, flush, and
restart the queue of incoming mouse events.
- It should be possible to restart and recompile
the coprocessor, e.g. to link in compiled versions of new functions.
For example, suppose that the entire interface fits into one window.
At the top of this window might be a row of command buttons and, below
them, a narrow sub-window for editing filenames for commands like
load. Below that might be a large subwindow containing the history
display. At the very bottom might be a sub-window for editing the
next input form.
The user front-end program should be very small, so that it is not a
burden when running final versions of applications on small machines.
This means, in particular, it should be written in Xlib, not Motif or
Tcl/Tk. It also means that the number of features (e.g. buttons)
should be kept under control.
Editing of code files will be provided independently by the user's
favorite text editor.
Ownership, Maintenance and Disclaimers
Manual Top Page