Update of /project/mcclim/cvsroot/mcclim
In directory clnet:/tmp/cvs-serv26826
Modified Files:
decls.lisp input-editing-drei.lisp input-editing.lisp
Log Message:
Added docstrings for input-editor related stuff.
--- /project/mcclim/cvsroot/mcclim/decls.lisp 2007/08/20 14:27:14 1.47
+++ /project/mcclim/cvsroot/mcclim/decls.lisp 2008/01/19 09:38:20 1.48
@@ -528,7 +528,6 @@
(defgeneric stream-input-buffer (stream))
(defgeneric (setf stream-input-buffer) (buffer stream))
-(defgeneric stream-pointer-position (stream &key pointer))
;; (defgeneric (setf* stream-pointer-position))
(defgeneric stream-set-input-focus (stream))
(defgeneric stream-read-gesture
@@ -555,28 +554,96 @@
;;; 24.1 The Input Editor
-(defgeneric input-editor-format (stream format-string &rest args))
-(defgeneric redraw-input-buffer (stream &optional start-from))
+(defgeneric input-editor-format (stream format-string &rest args)
+ (:documentation "This function is like `format', except that it
+is intended to be called on input editing streams. It arranges to
+insert \"noise strings\" in the input editor's input
+buffer. Programmers can use this to display in-line prompts in
+`accept' methods.
+
+If `stream' is a stream that is not an input editing stream, then
+`input-editor-format' is equivalent to format."))
+
+
+(defgeneric redraw-input-buffer (stream &optional start-from)
+ (:documentation "Displays the input editor's buffer starting at
+the position `start-position' on the interactive stream that is
+encapsulated by the input editing stream `stream'."))
;;; 24.1.1 The Input Editing Stream Protocol
-(defgeneric stream-insertion-pointer (stream))
-(defgeneric (setf stream-insertion-pointer) (pointer stream))
-(defgeneric stream-scan-pointer (stream))
-(defgeneric (setf stream-scan-pointer) (pointer stream))
-(defgeneric stream-rescanning-p (stream))
-(defgeneric reset-scan-pointer (stream &optional scan-pointer))
-(defgeneric immediate-rescan (stream))
-(defgeneric queue-rescan (stream))
-(defgeneric rescan-if-necessary (stream &optional inhibit-activation))
-(defgeneric erase-input-buffer (stream &optional start-position))
+(defgeneric stream-insertion-pointer (stream)
+ (:documentation "Returns an integer corresponding to the
+current input position in the input editing stream `stream's
+buffer, that is, the point in the buffer at which the next user
+input gesture will be inserted. The insertion pointer will always
+be less than (fill-pointer (stream-input-buffer stream)). The
+insertion pointer can also be thought of as an editing cursor."))
+
+(defgeneric (setf stream-insertion-pointer) (pointer stream)
+ (:documentation "Changes the input position of the input
+editing stream `stream' to `pointer'. `Pointer' is an integer,
+and must be less than (fill-pointer (stream-input-buffer stream))"))
+
+(defgeneric stream-scan-pointer (stream)
+ (:documentation "Returns an integer corresponding to the
+current scan pointer in the input editing stream `stream's
+buffer, that is, the point in the buffer at which calls to
+`accept' have stopped parsing input. The scan pointer will always
+be less than or equal to (stream-insertion-pointer stream)."))
+
+(defgeneric (setf stream-scan-pointer) (pointer stream)
+ (:documentation "Changes the scan pointer of the input editing
+stream `stream' to `pointer'. `Pointer' is an integer, and must
+be less than or equal to (stream-insertion-pointer stream)"))
+
+(defgeneric stream-rescanning-p (stream)
+ (:documentation "Returns the state of the input editing stream
+`stream's \"rescan in progress\" flag, which is true if stream is
+performing a rescan operation, otherwise it is false. All
+extended input streams must implement a method for this, but
+non-input editing streams will always returns false."))
+
+(defgeneric reset-scan-pointer (stream &optional scan-pointer)
+ (:documentation "Sets the input editing stream stream's scan
+pointer to `scan-pointer', and sets the state of
+`stream-rescanning-p' to true."))
+
+(defgeneric immediate-rescan (stream)
+ (:documentation "Invokes a rescan operation immediately by
+\"throwing\" out to the most recent invocation of
+`with-input-editing'."))
+
+(defgeneric queue-rescan (stream)
+ (:documentation "Indicates that a rescan operation on the input
+editing stream `stream' should take place after the next
+non-input editing gesture is read by setting the \"rescan
+queued\" flag to true. "))
+
+(defgeneric rescan-if-necessary (stream &optional inhibit-activation)
+ (:documentation "Invokes a rescan operation on the input
+editing stream `stream' if `queue-rescan' was called on the same
+stream and no intervening rescan operation has taken
+place. Resets the state of the \"rescan queued\" flag to false.
+
+If `inhibit-activation' is false, the input line will not be
+activated even if there is an activation character in it."))
+
+(defgeneric erase-input-buffer (stream &optional start-position)
+ (:documentation "Erases the part of the display that
+corresponds to the input editor's buffer starting at the position
+`start-position'."))
;;; McCLIM relies on a text editor class (by default
;;; DREI-INPUT-EDITING-MIXIN) to perform the user interaction and
;;; display for input editing. Also, that class must update the stream
;;; buffer and the insertion pointer, cause rescans to happen, and
;;; handle activation gestures.
-(defgeneric stream-process-gesture (stream gesture type))
+(defgeneric stream-process-gesture (stream gesture type)
+ (:documentation "If gesture is an input editing command,
+stream-process-gesture performs the input editing operation on
+the input editing stream `stream' and returns NIL. Otherwise, it
+returns the two values gesture and type."))
;;; 24.4 Reading and Writing of Tokens
--- /project/mcclim/cvsroot/mcclim/input-editing-drei.lisp 2008/01/16 09:03:27 1.5
+++ /project/mcclim/cvsroot/mcclim/input-editing-drei.lisp 2008/01/19 09:38:20 1.6
@@ -43,7 +43,12 @@
input-editing-stream
standard-encapsulating-stream)
((scan-pointer :accessor stream-scan-pointer :initform 0)
- (rescan-queued :accessor rescan-queued :initform nil)))
+ (rescan-queued :accessor rescan-queued :initform nil))
+ (:documentation "The instantiable class that implements CLIM's
+standard input editor. This is the class of stream created by
+calling `with-input-editing'.
+
+Members of this class are mutable."))
(defmethod stream-accept ((stream standard-input-editing-stream) type
&rest args
--- /project/mcclim/cvsroot/mcclim/input-editing.lisp 2007/08/20 14:27:14 1.56
+++ /project/mcclim/cvsroot/mcclim/input-editing.lisp 2008/01/19 09:38:20 1.57
@@ -31,10 +31,22 @@
"I true, use the Goatee editing component instead of Drei. The
Goatee component is faster and more mature than Drei.")
-(defvar *activation-gestures* nil)
-(defvar *standard-activation-gestures* '(:newline :return))
-
-(defvar *delimiter-gestures* nil)
+(defvar *activation-gestures* nil
+ "The set of currently active activation gestures. The global
+value of this must be NIL. The exact format of
+`*activation-gestures*' is unspecified. `*activation-gestures*'
+and the elements in it may have dynamic extent.")
+
+(defvar *standard-activation-gestures* '(:newline :return)
+ "The default set of activation gestures. The exact set of
+standard activation is unspecified, but must include the gesture
+that corresponds to the #\Newline character. ")
+
+(defvar *delimiter-gestures* nil
+ "The set of currently active delimiter gestures. The global
+value of this must be NIL. The exact format of
+`*delimiter-gestures*' is unspecified. `*delimiter-gestures*' and
+the elements in it may have dynamic extent.")
;;; These helper functions take the arguments of ACCEPT so that they
;;; can be used directly by ACCEPT.
@@ -63,6 +75,19 @@
(t existing-delimiter-gestures)))
(defmacro with-activation-gestures ((gestures &key override) &body body)
+ "Specifies a list of gestures that terminate input during the
+execution of `body'. `Body' may have zero or more declarations as
+its first forms. `Gestures' must be either a single gesture name
+or a form that evaluates to a list of gesture names.
+
+If the boolean `override' is true, then `gestures' will override
+the current activation gestures. If it is false (the default),
+then gestures will be added to the existing set of activation
+gestures. `with-activation-gestures' must bind
+`*activation-gestures*' to the new set of activation gestures.
+
+See also the `:activation-gestures' and
+`:additional-activation-gestures' options to `accept'."
;; XXX Guess this implies that gestures need to be defined at
;; compile time. Sigh. We permit both CLIM 2.0-style gesture names
;; and CLIM 2.2 style characters.
@@ -83,6 +108,21 @@
,@body)))
(defmacro with-delimiter-gestures ((gestures &key override) &body body)
+ "Specifies a list of gestures that terminate an individual
+token, but not the entire input, during the execution of
+`body'. `Body' may have zero or more declarations as its first
+forms. `Gestures' must be either a single gesture name or a form
+that evaluates to a list of gesture names.
+
+If the boolean `override' is true, then `gestures' will override
+the current delimiter gestures. If it is false (the default),
+then gestures will be added to the existing set of delimiter
+gestures. `With-delimiter-gestures' must bind
+`*delimiter-gestures*' to the new set of delimiter
+gestures.
+
+See also the `:delimiter-gestures' and
+`:additional-delimiter-gestures' options to `accept'."
;; XXX Guess this implies that gestures need to be defined at
;; compile time. Sigh. We permit both CLIM 2.0-style gesture names
;; and CLIM 2.2 style characters.
@@ -103,12 +143,16 @@
,@body)))
(defun activation-gesture-p (gesture)
+ "Returns true if the gesture object `gesture' is an activation
+gesture, otherwise returns false."
(loop for gesture-name in *activation-gestures*
when (gesture-matches-spec-p gesture gesture-name)
do (return t)
finally (return nil)))
(defun delimiter-gesture-p (gesture)
+ "Returns true if the gesture object `gesture' is a delimiter
+gesture, otherwise returns false."
(loop for gesture-name in *delimiter-gestures*
when (gesture-matches-spec-p gesture gesture-name)
do (return t)
@@ -119,6 +163,32 @@
&key input-sensitizer (initial-contents "")
(class ''standard-input-editing-stream class-provided-p))
&body body)
+ "Establishes a context in which the user can edit the input
+typed in on the interactive stream `stream'. `Body' is then
+executed in this context, and the values returned by `body' are
+returned as the values of `with-input-editing'. `Body' may have
+zero or more declarations as its first forms.
+
+The stream argument is not evaluated, and must be a symbol that
+is bound to an input stream. If stream is T (the default),
+`*standard-input*' is used. If stream is a stream that is not an
+interactive stream, then `with-input-editing' is equivalent to
+progn.
+
+`input-sensitizer', if supplied, is a function of two arguments,
+a stream and a continuation function; the function has dynamic
+extent. The continuation, supplied by CLIM, is responsible for
+displaying output corresponding to the user's input on the
+stream. The input-sensitizer function will typically call
+`with-output-as-presentation' in order to make the output
+produced by the continuation sensitive.
+
+If `initial-contents' is supplied, it must be either a string or
+a list of two elements, an object and a presentation type. If it
+is a string, the string will be inserted into the input buffer
+using `replace-input'. If it is a list, the printed
+representation of the object will be inserted into the input
+buffer using `presentation-replace-input'."
(setq stream (stream-designator-symbol stream '*standard-input*))
(with-keywords-removed (args (:input-sensitizer :initial-contents :class))
`(invoke-with-input-editing ,stream
@@ -184,6 +254,21 @@
(pointer-button-press-handler
*pointer-button-press-handler*)
click-only)
+ "Reads characters from the interactive stream `stream' until it
+encounters a delimiter or activation gesture, or a pointer
+gesture. Returns the accumulated string that was delimited by the
+delimiter or activation gesture, leaving the delimiter
+unread.
+
+If the first character of typed input is a quotation mark (#\"),
+then `read-token' will ignore delimiter gestures until another
+quotation mark is seen. When the closing quotation mark is seen,
+`read-token' will proceed as above.
+
+`Click-only' is ignored for now.
+
+`Input-wait-handler' and `pointer-button-press-handler' are as
+for 34stream-read-gesture"
(declare (ignore click-only)) ;XXX For now
(let ((result (make-array 1
:adjustable t
@@ -222,6 +307,15 @@
(return (subseq result 0))))))
(defun write-token (token stream &key acceptably)
+ "This function is the opposite of `read-token' given the string
+token, it writes it to the interactive stream stream. If
+`acceptably' is true and there are any characters in the token
+that are delimiter gestures (see the macro
+`with-delimiter-gestures'), then `write-token' will surround the
+token with quotation marks (#\").
+
+Typically, `present' methods will use `write-token' instead of
+`write-string'."
(let ((put-in-quotes (and acceptably (some #'delimiter-gesture-p token))))
(when put-in-quotes
(write-char #\" stream))
@@ -232,9 +326,18 @@
;;; Signalling Errors Inside present (sic)
(define-condition simple-parse-error (simple-condition parse-error)
- ())
+ ()
+ (:documentation "The error that is signalled by
+`simple-parse-error'. This is a subclass of `parse-error'.
+
+This condition handles two initargs, `:format-string' and
+`:format-arguments', which are used to specify a control string
+and arguments for a call to `format'."))
(defun simple-parse-error (format-string &rest format-args)
+ "Signals a `simple-parse-error' error while parsing an input
+token. Does not return. `Format-string' and `format-args' are as
+for format."
(error 'simple-parse-error
:format-control format-string :format-arguments format-args))
@@ -244,20 +347,50 @@
(:report (lambda (condition stream)
(format stream "Input ~S is not of required type ~S"
(not-required-type-string condition)
- (not-required-type-type condition)))))
+ (not-required-type-type condition))))
+ (:documentation "The error that is signalled by
+`input-not-of-required-type'. This is a subclass of
+`parse-error'.
+
+This condition handles two initargs, `:string' and `:type', which
+specify a string to be used in an error message and the expected
+presentation type."))
(defun input-not-of-required-type (object type)
+ "Reports that input does not satisfy the specified type by
+signalling an `input-not-of-required-type' error. `Object' is a
+parsed object or an unparsed token (a string). `Type' is a
+presentation type specifier. Does not return."
(error 'input-not-of-required-type :string object :type type))
;;; 24.5 Completion
-(defvar *completion-gestures* '(:complete))
-(defvar *help-gestures* '(:help))
-(defvar *possibilities-gestures* '(:possibilities))
+(defvar *completion-gestures* '(:complete)
+ "A list of the gesture names that cause `complete-input' to
+complete the user's input as fully as possible. The exact global
+contents of this list is unspecified, but must include the
+`:complete' gesture name.")
+
+(defvar *help-gestures* '(:help)
+ "A list of the gesture names that cause `accept' and
+`complete-input' to display a (possibly input context-sensitive)
+help message, and for some presentation types a list of
+possibilities as well. The exact global contents of this list is
+unspecified, but must include the `:help' gesture name.")
+
+(defvar *possibilities-gestures* '(:possibilities)
+ "A list of the gesture names that cause `complete-input' to
+display a (possibly input context-sensitive) help message and a
+list of possibilities. The exact global contents of this list is
+unspecified, but must include the `:possibilities' gesture
+name.")
(define-condition simple-completion-error (simple-parse-error)
((input-so-far :reader completion-error-input-so-far
- :initarg :input-so-far)))
+ :initarg :input-so-far))
+ (:documentation "The error that is signalled by
+`complete-input' when no completion is found. This is a subclass
+of `simple-parse-error'."))
;;; wrapper around event-matches-gesture-name-p to match against characters too.
@@ -584,11 +717,34 @@
:predicate predicate)))
(defun suggest (completion object)
+ "Specifies one possibility for
+`completing-from-suggestions'. `Completion' is a string, the
+printed representation of object. `Object' is the internal
+representation.
+
+Calling this function outside of the body of
+`completing-from-suggestions' is an error."
(declare (ignore completion object))
(error
"SUGGEST called outside of lexical scope of COMPLETING-FROM-SUGGESTIONS" ))
(defmacro completing-from-suggestions ((stream &rest args) &body body)
+ "Reads input from the input editing stream `stream', completing
+over a set of possibilities generated by calls to `suggest'
+within `body'. `Body' may have zero or more declarations as its
+first forms.
+
+`Completing-from-suggestions' returns three values, `object',
+`success', and `string'.
+
+The stream argument is not evaluated, and must be a symbol that
+is bound to a stream. If `stream' t is (the default),
+`*standard-input*' is used. `Partial-completers',
+`allow-any-input', and `possibility-printer' are as for
+`complete-input'.
+
+Implementations will probably use `complete-from-generator' to
+implement this."
(when (eq stream t)
(setq stream '*standard-input*))
(let ((generator (gensym "GENERATOR"))