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


12. 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 window displayed at the bottom of the screen. This is called the echo area and is supported by a buffer and a window. This buffer's modeline (see section 3.3) is referred to as the status line, which, unlike other buffers' modelines, is used to show general status about the editor, Lisp, or world.

Default Status Line Fields [Hemlock Variable]

This is the initial list of modeline-field objects stored in the echo area buffer.

Echo Area Height (initial value 3) [Hemlock Variable] This variable determines the initial height in lines of the echo area window.

12.1. Echo Area Functions

It is considered poor taste to perform text operations on the echo area buffer to display messages; the message function should be used instead. A command must use this function or set buffer-modified (page 12) for the Echo Area buffer to nil to cause Hemlock to leave text in the echo area after the command's execution.

clear-echo-area [Function]

Clears the echo area.

message control-string &rest format-arguments [Function]

loud-message control-string &rest format-arguments [Function]

Message Pause (initial value 0.5) [Hemlock Variable]

Displays a message in the echo area. The message is always displayed on a fresh line. message pauses for Message Pause seconds before returning to assure that messages are not displayed too briefly to be seen. Because of this, message is the best way to display text in the echo area. loud-message is like message, but it first clears the echo area and beeps.

*echo-area-window* [Variable]

*echo-area-buffer* [Variable]

echo-area-buffer contains the buffer object for the echo area, which is named Echo Area. This buffer is usually in Echo Area mode. echo-area-window contains a window displaying echo-area-buffer. Its modeline is the status line, see the beginning of this chapter.

*echo-area-stream* [Variable]

This is a buffered Hemlock output stream (59) which inserts text written to it at the point of the echo area buffer. Since this stream is buffered a force-output must be done when output is complete to assure that it is displayed.

12.2. Prompting Functions

Most of the prompting functions accept the following keyword arguments:

If :must-exist has a non-nilvalue 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.
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.
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.
This is the prompt string to display.
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 &key :prompt :help :must-exist :default [Function] :default-string

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.

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

This macro is analogous to the Common Lisp case macro. Commands such as Query Replace 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 (page 45) 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."
  "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.")
	 "Go into a recursive edit in this buffer."
	 (do-recursive-edit) (reprompt))
	((: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:

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.
This is the prompt used when reading the key-event.


If this is non-nil (the default), then the echo area window becomes the current window while the prompting mechanism reads a key-event. Sometimes it is desirable to maintain the current window since it may be easier for users to answer the question if they can see where the current point is.

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 ext: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 system: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.

prompt-for-key-event &key :prompt :change-window [Function]

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

prompt-for-key &key :prompt :help :must-exist :default [Function] :default-string

This function prompts for akey, a vector of key-events, suitable for passing to any of the functions that manipulate key bindings (page 29). 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 &key :prompt :help :must-exist :default [Function] :default-string

This function prompts for an acceptable filename in some system dependent fashion. "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 &key :prompt :help :must-exist :default [Function] :default-string

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-keywordstring-tables &key :prompt :help :must-exist [Function] :default :default-string

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 &key :prompt :help :must-exist :default [Function] :default-string

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 &key :prompt :help :default :default-string [Function]

This function prompts for a string; this cannot fail.

prompt-for-variable &key :prompt :help :must-exist :default [Function] :default-string

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 &key :prompt :help :must-exist :default [Function] :default-string

This prompts for y, Y, n, 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 returnstor nil. This is analogous to the Common Lisp function y-or-n-p.

prompt-for-yes-or-no &key :prompt :help :must-exist :default [Function] :default-string

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.

12.3. Control of Parsing Behavior

Beep On Ambiguity (initial value t) [Hemlock Variable]

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

12.4. Defining New Prompting Functions

Prompting functions are implemented as a recursive edit in the Echo Area buffer. Completion, help, and other parsing features are implemented by commands which are bound in Echo Area Mode. A prompting function passes information down into the recursive edit by binding a collection of special variables.

*parse-verification-function* [Variable]

The system binds this to a function that Confirm Parse (page 52) calls. It does most of the work when parsing prompted input. Confirm Parse (page 52) passes one argument, which is the string that was in *parse-input-region* when the user invokes the command. 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.

*parse-string-tables* [Variable]

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

*parse-value-must-exist* [Variable]

This is bound to the value of the :must-exist argument, and is referred to by the verification function, and possibly some of the commands.

*parse-default* [Variable]

When prompting the user, this is bound to a string representing the default object, the value supplied as the :default argument. Confirm Parse supplies this to the parse verification function when the *parse-input-region* is empty.

*parse-default-string* [Variable]

When prompting the user, if *parse-default* is nil, Hemlock displays this string as a representation of the default object; for example, when prompting for a buffer, this variable would be bound to the buffer name.

*parse-type* [Variable]

The kind of parse in progress, one of :file, :keyword or :string. This tells the completion commands how to do completion, with :string disabling completion.

*parse-prompt* [Variable]

The prompt being used for the current parse.

*parse-help* [Variable]

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

*parse-starting-mark* [Variable]

This variable holds a mark in the *echo-area-buffer* (page 47) which is the position at which the parse began.

*parse-input-region* [Variable]

This variable holds a region with *parse-starting-mark* as its start and the end of the echo-area buffer as its end. When Confirm Parse is called, the text in this region is the text that will be parsed.

12.5. 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 (bound to Home, C-_ in Echo Area mode) [Command]

Display the help text for the parse currently in progress.

Complete Keyword (bound to Escape in Echo Area mode) [Command]

This attempts to complete the current region as a keyword in*string-tables*. It signals an editor-error if the input is ambiguous or incorrect.

Complete Field (bound to Space in Echo Area mode) [Command]

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 (bound to Return in Echo Area mode) [Command]

If *string-tables* is non-nil find the string in the region in them. Call *parse-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.