27.1 Commands

A command is an object that represents a user interaction. Commands are stored as a cons of the command name and a list of the command's arguments. All positional arguments will be represented in the command object, but only those keywords arguments that were explicitly supplied by the user will be included. When the first element of the cons is apply'ed to the rest of the cons, the code representing that interaction is executed. [annotate]

[command, Concept← A Glossary]

A partial command is a command object with the value of *unsupplied-argument-marker* in place of any argument that needs to be filled in. [annotate]

Every command is named by command name, which is a symbol. To avoid collisions among command names, application frames should reside in their own package; for example, the com-show-chart command might be defined for both a spreadsheet and a medical application. [annotate]

command-name  command [Function]
command-arguments  command [Function]
          

Given a command object command, returns the command's arguments. [annotate]

[annotate]

partial-command-p  command [Function]
          

Returns true if the command is a partial command, that is, has any occurrences of *unsupplied-argument-marker* in it. Otherwise, partial-command-p returns false. [annotate]

[annotate]

define-command  name-and-options arguments &body body [Macro]
          

This is the most basic command-defining form. Usually, the programmer will not use define-command directly, but will instead use a define-frame-command form that is automatically generated by define-application-frame. define-frame-command adds the command to the application frame's command table. By default, define-command does not add the command to any command table. [annotate]

name-and-options is either a command name, or a cons of the command name and a list of keyword-value pairs. [annotate]

define-command defines two functions. The first function has the same name as the command name, and implements the body of the command. It takes as arguments the arguments to the command as specified by the define-command form, as required and keyword arguments. [annotate]

The name of the other function defined by define-command is unspecified. It implements the code used by the command processor for parsing and returning the command's arguments. [annotate]

The keywords from name-and-options can be: [annotate]

  • :command-table command-table-name, where command-table-name either names a command table to which the command will be added, or is nil (the default) to indicate that the command should not be added to any command table. If the command table does not exist, the command-table-not-found error will be signalled. This keyword is only accepted by define-command, not by define-frame-command. [annotate]
  • :name string, where string is a string that will be used as the command-line name for the command for keyboard interactions in the command table specified by the :command-table option. The default is nil, meaning that the command will not be available via command-line interactions. If string is t, then the command-line name will be generated automatically, as described in add-command-to-command-table. [annotate]
  • :menu menu-spec, where menu-spec describes an item in the menu of the command table specified by the :command-table option. The default is nil, meaning that the command will not be available via menu interactions. If menu-spec is a string, then that string will be used as the menu name. If menu-spec is t, then if a command-line name was supplied, it will be used as the menu name; otherwise the menu name will be generated automatically, as described in add-command-to-command-table. Otherwise, menu-spec must be a cons of the form (string . menu-options), where string is the menu name and menu-options consists of keyword-value pairs. The valid keywords are :after, :documentation, and :text-style, which are interpreted as for add-menu-item-to-command-table. [annotate]
  • :keystroke gesture, where gesture is a keyboard gesture name that specifies a keystroke accelerator to use for this command in the command table specified by the :command-table option. The default is nil, meaning that there is no keystroke accelerator. [annotate]

The :name, :menu, and :keystroke options are only allowed if the :command-table option was supplied explicitly or implicitly, as in define-frame-command. [annotate]

arguments is a list consisting of argument descriptions. A single occurrence of the symbol &key may appear in arguments to separate required command arguments from keyword arguments. Each argument description consists of a parameter variable, followed by a presentation type specifier, followed by keyword-value pairs. The keywords can be: [annotate]

  • :default value, where value is the default that should be used for the argument, as for accept. [annotate]
  • :default-type is the same as for accept. [annotate]
  • :display-default is the same as for accept. [annotate]
  • :mentioned-default value, where value is the default that should be used for the argument when a keyword is explicitly supplied via the command-line processor, but no value is supplied for it. :mentioned-default is only allowed on keyword arguments. [annotate]
  • :prompt string, where string is a prompt to print out during command-line parsing, as for accept. [annotate]
  • :documentation string, where string is a documentation string that describes what the argument is. [annotate]
  • :when form. form is evaluated in a scope where the parameter variables for the required parameters are bound, and if the result is nil, the keyword argument is not available. :when is only allowed on keyword arguments, and form cannot use the values of other keyword arguments. [annotate]
  • :gesture gesture, where gesture is either a pointer gesture name or a list of a pointer gesture name followed by keyword-value pairs. When a gesture is supplied, a presentation translator will be defined that translates from this argument's presentation type to an instance of this command with the selected object as the argument; the other arguments will be filled in with their default values. The keyword-value pairs are used as options for the translator. Valid keywords are :tester, :menu, :priority, :echo, :documentation, and :pointer-documentation. The default for gesture is nil, meaning no translator will be written. :gesture is only allowed when the :command-table option was supplied to the command-defining form. [annotate]

body implements the body of the command. It has lexical access to all of the commands arguments. If the body of the command needs access to the application frame itself, it should use *application-frame*. The returned values of body are ignored. body may have zero or more declarations as its first forms. [annotate]

define-command must arrange for the function that implements the body of the command to get the proper values for unsupplied keyword arguments. [annotate]

name-and-options and body are not evaluated. In the argument descriptions, the parameter variable name is not evaluated, and everything else is evaluated at run-time when argument parsing reaches that argument, except that the value for :when is evaluated when parsing reaches the keyword arguments, and :gesture isn't evaluated at all. [annotate]

Note:

This paragraph seems insane to me. Are variables in the key positions allowed? If so, then the potential for confusion is high: already

(define-command com-foo ((x *type*)) ...)

seems to have little utility, but

(define-command com-foo ((x *type* *arg1* *arg2*)) ...)

seems just mad. Furthermore, what if *arg1* evalutes to :gesture?

I think if I were rewriting this paragraph I would specify that the keywords had to be macroexpand-time constants, while those values needing evaluation would be dealt with as in defclass (with its initform / initfunction handling).

[edit]-- Christophe Rhodes 2006-04-25 16:58Z
 

[annotate]