[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: More customizing command loops

    Date: Thu, 3 Sep 87 18:00 PDT
    From: Mabry Tyson <TYSON@AI.SRI.COM>

    While we're on the customizing command loops stuff, my wish would be to
    be able to do more than just read with Symbolics's supplied read routines
    that are designed for that.  I want to do something on the order of LINEREAD
    if, say, it doesn't start with a colon or open parenthesis.  The application
    is that the user is typing in English sentences most of the time, but I'd
    be very happy if he could type in commands.  WITHOUT THE SOURCES, it is hard
    to figure this out.  I had just punted and didn't use the new command
    code.  I see I'm not the only one who found the command interface opaque
    (for the programmer).

    By the way, isn't it confusing how CP:READ-ACCELERATED-COMMAND will return
    a flag saying a :COMMAND, :FORM, or :ACCELERATOR was read, but then the function
    is documented as "Reads a command processor command input as a single-key
    accelerator".  I tried calling it with :FORM-P T and it still seemed as
    though it would only read a single character.  My only guess is that the
    command *only* reads accelerator keys and the documentation and keywords are
    confusing or wrong.  Now, if I only had the source code...

Read the documentation again.  "If the caller is expecting a form (1:form-p0 is
1t0), the values returned are the form and a flag."  In other words,
:form-p only affects the return values.  

cp:read-accelerated-command is documented, as are all of the options
that you need to do what you asked for in the first paragraph.
cp:read-accelerated-command expects to read accelerator characters, and
dispatches on those keys it doesn't recognize according to the various
:unknown-accelerator-xxx options.

;;; Here is a simple example.

;;; Define a command table for use in this example.
;;; The only magic thing about this is the fact that it inherits from
;;; "colon full command", but this is documented on page 160 of
;;; 7A.
(cp:make-command-table 'mabry
		       :inherit-from '(user "colon full command"))

;;; Define a command in that command table.
(cp:define-command (com-mabry-test :command-table 'mabry)
   (print "Foo"))

;;; Define a keyboard accelerator (Hyper-H) for that command in the
;;; command-table.
(cp:define-command-accelerator mabry-test mabry (#\h-h) () ()

;;; Define a function that reads either a command (prefixed with a ":"),
;;; or an accelerator (in this case, only Hyper-H).  Anything else is
;;; assumed to be a line of text.
(defun read-a-sentence-or-a-command (&key (stream *query-io*)
				     (command-table (cp:find-command-table 'mabry)))
    :unknown-accelerator-is-command t
    :unknown-accelerator-reader (lambda ()
				  (values (read-line stream) nil :form))
    :unknown-accelerator-reader-prompt ""
    :command-prompt nil
    :stream stream
    :command-table command-table))