Update of /project/mcclim/cvsroot/mcclim/Drei
In directory clnet:/tmp/cvs-serv27756/Drei
Modified Files:
core-commands.lisp drei-clim.lisp drei.lisp input-editor.lisp
packages.lisp search-commands.lisp syntax.lisp
Log Message:
Go some way towards fixing the minibuffer debacle.
Drei will no longer attempt to create a minibuffer on its own pane.
Commands that need the minibuffer, when none is available, will fail
somewhat gracefully.
Pointer documentation isn't broken yet, even with all the
pointer-documentation-pane abuse I'm doing. I'll have to work on that.
--- /project/mcclim/cvsroot/mcclim/Drei/core-commands.lisp 2008/01/21 17:08:28 1.15
+++ /project/mcclim/cvsroot/mcclim/Drei/core-commands.lisp 2008/01/30 11:48:40 1.16
@@ -67,6 +67,7 @@
(define-command (com-zap-to-object :name t :command-table deletion-table) ()
"Prompt for an object and kill to the next occurence of that object after point.
Characters can be entered in #\ format."
+ (require-minibuffer)
(let* ((item (handler-case (accept 't :prompt "Zap to Object")
(error () (progn (beep)
(display-message "Not a valid object")
@@ -81,6 +82,7 @@
FIXME: Accepts a string (that is, zero or more characters)
terminated by a #\NEWLINE. If a zero length string signals an error.
If a string of length >1, uses the first character of the string."
+ (require-minibuffer)
(let* ((item-string (handler-case (accept 'string :prompt "Zap to Character") ; Figure out how to get #\d and d. (or 'string 'character)?
(error () (progn (beep)
(display-message "Not a valid string. ")
--- /project/mcclim/cvsroot/mcclim/Drei/drei-clim.lisp 2008/01/28 16:53:21 1.35
+++ /project/mcclim/cvsroot/mcclim/Drei/drei-clim.lisp 2008/01/30 11:48:40 1.36
@@ -179,7 +179,8 @@
(defmethod stream-default-view ((stream drei-pane))
(view stream))
-(defmethod display-drei ((drei drei-pane))
+(defmethod display-drei ((drei drei-pane) &rest args)
+ (declare (ignore args))
(redisplay-frame-pane (pane-frame drei) drei))
(defmethod editor-pane ((drei drei-pane))
@@ -227,8 +228,7 @@
keyboard focus"))
(:metaclass modual-class)
(:default-initargs
- :command-executor 'execute-drei-command
- :redisplay-minibuffer t)
+ :command-executor 'execute-drei-command)
(:documentation "An actual, instantiable Drei gadget with
event-based command processing."))
@@ -285,26 +285,20 @@
(defmethod handle-gesture ((drei drei-gadget-pane) gesture)
(let ((*command-processor* drei)
(*abort-gestures* *esa-abort-gestures*))
- ;; It is important that the minibuffer of the Drei object is
- ;; actually the minibuffer that will be used for output, or it
- ;; will not be properly redisplayed by `display-drei'.
(accepting-from-user (drei)
- (letf (((minibuffer drei) (or (minibuffer drei) *minibuffer*
- (unless (eq drei *standard-input*)
- *standard-input*))))
- (handler-case (process-gesture drei gesture)
- (unbound-gesture-sequence (c)
- (display-message "~A is unbound" (gesture-name (gestures c))))
- (abort-gesture ()
- (display-message "Aborted")))
- (display-drei drei)
- (when (modified-p (view drei))
- (when (gadget-value-changed-callback drei)
- (value-changed-callback drei
- (gadget-client drei)
- (gadget-id drei)
- (gadget-value drei)))
- (setf (modified-p (view drei)) nil))))))
+ (handler-case (process-gesture drei gesture)
+ (unbound-gesture-sequence (c)
+ (display-message "~A is unbound" (gesture-name (gestures c))))
+ (abort-gesture ()
+ (display-message "Aborted")))
+ (display-drei drei :redisplay-minibuffer t)
+ (when (modified-p (view drei))
+ (when (gadget-value-changed-callback drei)
+ (value-changed-callback drei
+ (gadget-client drei)
+ (gadget-id drei)
+ (gadget-value drei)))
+ (setf (modified-p (view drei)) nil)))))
;;; This is the method that functions as the entry point for all Drei
;;; gadget logic.
@@ -314,8 +308,7 @@
(let ((gesture (convert-to-gesture event)))
(when (proper-gesture-p gesture)
(with-bound-drei-special-variables (gadget :prompt (format nil "~A " (gesture-name gesture)))
- (let ((*standard-input* (or *minibuffer* *standard-input*)))
- (handle-gesture gadget gesture))))))))
+ (handle-gesture gadget gesture)))))))
(defmethod handle-event :before
((gadget drei-gadget-pane) (event pointer-button-press-event))
@@ -362,8 +355,7 @@
record of the Drei area instance."))
(:metaclass modual-class)
(:default-initargs
- :command-executor 'execute-drei-command
- :redisplay-minibuffer t)
+ :command-executor 'execute-drei-command)
(:documentation "A Drei editable area implemented as an output
record."))
@@ -380,7 +372,8 @@
(defmethod esa-current-window ((drei drei-area))
(editor-pane drei))
-(defmethod display-drei ((drei drei-area))
+(defmethod display-drei ((drei drei-area) &rest args)
+ (declare (ignore args))
(display-drei-area drei))
;;; Implementation of the displayed-output-record and region protocol
@@ -503,9 +496,8 @@
(:documentation "A constellation of a Drei gadget instance and
a minibuffer."))
-(defmethod display-drei :after ((drei drei))
- (when (and *minibuffer* (not (eq *minibuffer* (editor-pane drei)))
- (redisplay-minibuffer drei))
+(defmethod display-drei :after ((drei drei) &key redisplay-minibuffer)
+ (when (and *minibuffer* redisplay-minibuffer)
;; We need to use :force-p t to remove any existing output from
;; the pane.
(redisplay-frame-pane (pane-frame *minibuffer*) *minibuffer* :force-p t)))
--- /project/mcclim/cvsroot/mcclim/Drei/drei.lisp 2008/01/30 07:31:33 1.34
+++ /project/mcclim/cvsroot/mcclim/Drei/drei.lisp 2008/01/30 11:48:40 1.35
@@ -194,6 +194,7 @@
(define-command (com-drei-extended-command :command-table exclusive-gadget-table)
()
"Prompt for a command name and arguments, then run it."
+ (require-minibuffer)
(let ((item (handler-case
(accept
`(command :command-table ,(command-table (drei-instance)))
@@ -287,14 +288,6 @@
:initarg :cursors-visible
:documentation "If true, the cursors of this
Drei instance will be visible. If false, they will not.")
- (%redisplay-minibuffer :accessor redisplay-minibuffer
- :initform nil
- :initarg :redisplay-minibuffer
- :documentation "If true, the minibuffer
-associated with this Drei instance will be redisplayed as the
-last part of the Drei redisplay process. If false, it is the task
-of the Drei-using application to make sure the minibuffer is
-redisplayed as appropriate.")
(%isearch-mode :initform nil :accessor isearch-mode)
(%isearch-states :initform '() :accessor isearch-states)
(%isearch-previous-string :initform nil :accessor isearch-previous-string)
@@ -388,13 +381,37 @@
(format stream "~A" (type-of (view object)))))
;; Main redisplay entry point.
-(defgeneric display-drei (drei)
+(defgeneric display-drei (drei &key redisplay-minibuffer)
(:documentation "`Drei' must be an object of type `drei' and
`frame' must be a CLIM frame containing the editor pane of
`drei'. If you define a new subclass of `drei', you must define a
method for this generic function. In most cases, methods defined
on this function will merely be a trampoline to a function
-specific to the given Drei variant."))
+specific to the given Drei variant.
+
+If `redisplay-minibuffer' is true, also redisplay `*minibuffer*'
+if it is non-NIL."))
+
+(define-condition no-available-minibuffer (user-condition-mixin error)
+ ((%drei :reader drei
+ :initarg :drei
+ :initform (error "A drei instance must be provided")
+ :documentation "The Drei instance that does not have an
+available minibuffer."))
+ (:documentation "This error is signalled when a command wants
+to use the minibuffer, but none is available."))
+
+(defun no-available-minibuffer (drei-instance)
+ "Signal an `no-available-minibuffer' error for
+`drei-instance'."
+ (error 'no-available-minibuffer :drei drei-instance))
+
+(defun require-minibuffer (&optional (drei-instance (drei-instance)))
+ "Check that the provided Drei instance (defaulting to the one
+currently running) has an available minibuffer. If not, signal an
+error of type `no-available-minibuffer'."
+ (unless *minibuffer*
+ (no-available-minibuffer drei-instance)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
@@ -419,9 +436,6 @@
(defmethod handle-drei-condition (drei (condition motion-after-end))
(beep) (display-message "End of buffer"))
-(defmethod handle-drei-condition (drei (condition no-expression))
- (beep) (display-message "No expression around point"))
-
(defmethod handle-drei-condition (drei (condition no-such-operation))
(beep) (display-message "Operation unavailable for syntax"))
@@ -453,13 +467,27 @@
(handle-drei-condition (drei-instance) c))
(motion-after-end (c)
(handle-drei-condition (drei-instance) c))
- (no-expression (c)
- (handle-drei-condition (drei-instance) c))
(no-such-operation (c)
- (handle-drei-condition (drei-instance) c))
- (buffer-read-only (c)
(handle-drei-condition (drei-instance) c))))
+(defun find-available-minibuffer (drei-instance)
+ "Find a pane usable as the minibuffer for `drei-instance'. The
+default will be to use the minibuffer specified for
+`drei-instance' (if there is one), secondarily the value of
+`*minibuffer*' will be used. Thirdly, the value of
+`*pointer-documentation-output*' will be used. If the found panes
+are not available (for example, if they are the editor-panes of
+`drei-instance'), it is possible for this function to return
+NIL."
+ (flet ((available-minibuffer-p (pane)
+ (and (or (typep pane 'minibuffer-pane)
+ (typep pane 'pointer-documentation-pane))
+ (not (eq pane (editor-pane drei-instance))))))
+ (find-if #'available-minibuffer-p
+ (list (minibuffer drei-instance)
+ *minibuffer*
+ *pointer-documentation-output*))))
+
(defmacro with-bound-drei-special-variables ((drei-instance &key
(kill-ring nil kill-ring-p)
(minibuffer nil minibuffer-p)
@@ -482,7 +510,7 @@
(*kill-ring* ,(if kill-ring-p kill-ring
`(kill-ring (drei-instance))))
(*minibuffer* ,(if minibuffer-p minibuffer
- `(or (minibuffer (drei-instance)) *minibuffer*)))
+ `(find-available-minibuffer (drei-instance))))
(*command-parser* ,(if command-parser-p command-parser
''esa-command-parser))
(*partial-command-parser* ,(if partial-command-parser-p partial-command-parser
@@ -490,7 +518,8 @@
(*previous-command* ,(if previous-command-p previous-command
`(previous-command (drei-instance))))
(*extended-command-prompt* ,(if prompt-p prompt
- "Extended command: ")))
+ "Extended command: "))
+ (*standard-input* (or *minibuffer* *standard-input*)))
,@body))
(defgeneric invoke-performing-drei-operations (drei continuation &key with-undo redisplay)
@@ -510,7 +539,7 @@
(pane
(redisplay-frame-pane *application-frame* drei))
(t
- (display-drei drei))))))
+ (display-drei drei :redisplay-minibuffer t))))))
(defmacro performing-drei-operations ((drei &rest args &key with-undo
(redisplay t))
@@ -581,9 +610,7 @@
`(invoke-accepting-from-user ,drei #'(lambda () ,@body)))
;;; Plain `execute-frame-command' is not good enough for us. Our
-;;; event-handler method uses this function to invoke commands, note
-;;; that it is also responsible for updating the syntax of the buffer
-;;; in the pane.
+;;; event-handler method uses this function to invoke commands.
(defgeneric execute-drei-command (drei-instance command)
(:documentation "Execute `command' for `drei'. This is the
standard function for executing Drei commands - it will take care
@@ -592,9 +619,8 @@
recording the operations performed by `command' for undo."))
(defmethod execute-drei-command ((drei drei) command)
- (let ((*standard-input* (or *minibuffer* *standard-input*)))
- (performing-drei-operations (drei :redisplay nil
- :with-undo t)
- (handling-drei-conditions
- (apply (command-name command) (command-arguments command)))
- (setf (previous-command drei) command))))
+ (performing-drei-operations (drei :redisplay nil
+ :with-undo t)
+ (handling-drei-conditions
+ (apply (command-name command) (command-arguments command)))
+ (setf (previous-command drei) command)))
--- /project/mcclim/cvsroot/mcclim/Drei/input-editor.lisp 2008/01/27 09:36:07 1.25
+++ /project/mcclim/cvsroot/mcclim/Drei/input-editor.lisp 2008/01/30 11:48:40 1.26
@@ -73,8 +73,6 @@
:y-position cy
:active cursor-visibility
:max-width max-width
- :minibuffer (or *minibuffer*
- *pointer-documentation-output*)
:allow-other-keys t
args)))
;; XXX Really add it here?
@@ -561,19 +559,8 @@
(let* ((drei (drei-instance stream))
(*command-processor* drei)
(was-directly-processing (directly-processing-p drei))
- (minibuffer (or (minibuffer drei) *minibuffer*))
(*drei-input-editing-stream* stream))
- (with-bound-drei-special-variables (drei
- ;; If the minibuffer is the
- ;; stream we are encapsulating
- ;; for the
- ;; input-editing-stream, we
- ;; don't want to use it as a
- ;; minibuffer.
- :minibuffer (if (eq minibuffer *standard-input*)
- *pointer-documentation-output*
- minibuffer)
- :prompt "M-x ")
+ (with-bound-drei-special-variables (drei :prompt "M-x ")
(update-drei-buffer stream)
;; Commands are permitted to signal immediate rescans, but
;; we may need to do some stuff first.
@@ -589,14 +576,13 @@
(abort-gesture (c)
(if (member (abort-gesture-event c)
*abort-gestures*
- :test #'event-matches-gesture-name-p)
+ :test #'event-matches-gesture-name-p)
(signal 'abort-gesture :event (abort-gesture-event c))
(when was-directly-processing
(display-message "Aborted")))))))
(update-drei-buffer stream))
(let ((first-mismatch (prefix-size (view drei))))
- ;; Will also take care of redisplaying minibuffer.
- (display-drei drei)
+ (display-drei drei :redisplay-minibuffer t)
(cond ((null first-mismatch)
;; No change actually took place, even though IP may
;; have moved.
@@ -873,7 +859,7 @@
;; and signal a rescan.
(setf (activation-gesture stream) nil)
(handle-drei-condition drei e)
- (display-drei drei)
+ (display-drei drei :redisplay-minibuffer t)
(immediate-rescan stream))))
(ptype (presentation-type-of object)))
(return-from control-loop
--- /project/mcclim/cvsroot/mcclim/Drei/packages.lisp 2008/01/30 07:31:33 1.48
+++ /project/mcclim/cvsroot/mcclim/Drei/packages.lisp 2008/01/30 11:48:40 1.49
@@ -167,7 +167,7 @@
#:parse-stack-top #:target-parse-tree #:parse-state-empty-p
#:parse-stack-next #:parse-stack-symbol
#:parse-stack-parse-trees #:map-over-parse-trees
- #:no-such-operation #:no-expression
+ #:no-such-operation
#:name-for-info-pane
#:display-syntax-name
#:syntax-line-indentation
@@ -213,6 +213,7 @@
#:user-condition-mixin
#:buffer-read-only
#:buffer-single-line
+ #:no-available-minibuffer
;; Views and their facilities.
#:drei-view #:modified-p #:no-cursors
@@ -289,6 +290,7 @@
#:performing-drei-operations #:invoke-performing-drei-operations
#:with-bound-drei-special-variables
#:accepting-from-user #:invoke-accepting-from-user
+ #:require-minibuffer
;; Gadget interface stuff.
#:handle-gesture
--- /project/mcclim/cvsroot/mcclim/Drei/search-commands.lisp 2008/01/26 12:37:25 1.7
+++ /project/mcclim/cvsroot/mcclim/Drei/search-commands.lisp 2008/01/30 11:48:40 1.8
@@ -309,6 +309,7 @@
(define-command (com-replace-string :name t :command-table search-table)
()
"Replace all occurrences of `string' with `newstring'."
+ (require-minibuffer)
;; We have to do it this way if we want to refer to STRING in NEWSTRING
(let* ((string (accept 'string :prompt "Replace String"))
(newstring (accept'string :prompt (format nil "Replace ~A with" string))))
@@ -343,6 +344,7 @@
t))))
(define-command (com-query-replace :name t :command-table search-table) ()
+ (require-minibuffer)
(let* ((drei (drei-instance))
(old-state (query-replace-state drei))
(old-string1 (when old-state (string1 old-state)))
@@ -493,6 +495,7 @@
do (princ char result))))
(define-command (com-regex-search-forward :name t :command-table search-table) ()
+ (require-minibuffer)
(let ((string (accept 'string :prompt "RE search"
:delimiter-gestures nil
:activation-gestures
@@ -502,6 +505,7 @@
(re-search-forward mark (normalise-minibuffer-regex string))))))
(define-command (com-regex-search-backward :name t :command-table search-table) ()
+ (require-minibuffer)
(let ((string (accept 'string :prompt "RE search backward"
:delimiter-gestures nil
:activation-gestures
--- /project/mcclim/cvsroot/mcclim/Drei/syntax.lisp 2008/01/29 19:13:06 1.16
+++ /project/mcclim/cvsroot/mcclim/Drei/syntax.lisp 2008/01/30 11:48:40 1.17
@@ -73,14 +73,6 @@
(:documentation "This condition is signaled whenever an attempt is
made to execute an operation that is unavailable for the particular syntax" ))
-(define-condition no-expression (simple-error)
- ()
- (:report (lambda (condition stream)
- (declare (ignore condition))
- (format stream "No expression at point")))
- (:documentation "This condition is signaled whenever an attempt is
-made to execute a by-experssion motion command and no expression is available." ))
-
(defgeneric update-syntax (syntax unchanged-prefix unchanged-suffix
&optional begin end)
(:documentation "Inform the syntax module that it must update