Index: Apps/Debugger/clim-debugger.lisp
===================================================================
RCS file: /project/mcclim/cvsroot/mcclim/Apps/Debugger/clim-debugger.lisp,v
retrieving revision 1.1
diff -u -r1.1 clim-debugger.lisp
--- Apps/Debugger/clim-debugger.lisp	26 Apr 2005 03:19:34 -0000	1.1
+++ Apps/Debugger/clim-debugger.lisp	19 Jan 2006 22:01:28 -0000
@@ -151,7 +151,12 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (defclass debugger-pane (application-pane)
-  ((condition-info :reader condition-info :initarg :condition-info)))
+  ((condition-info :reader condition-info :initarg :condition-info)
+   (selected-stackframe
+    :accessor selected-stackframe
+    :initarg :selected-strackframe
+    :type 'integer
+    :initform 0)))
 
 ;; FIXME - These two variables should be removed!
 ;; Used to return the chosen reatart in the debugger.
@@ -173,9 +178,12 @@
 (define-application-frame clim-debugger ()
   ()
   (:panes
-   (debugger-pane (make-debugger-pane)))
+   (debugger-pane (make-debugger-pane))
+   (pointer-doc :pointer-documentation))
   (:layouts
-   (default (vertically () (scrolling () debugger-pane))))
+   (default (vertically ()
+              (scrolling () debugger-pane)
+              pointer-doc)))
   (:geometry :height 600 :width 800))
 
 (defun run-debugger-frame ()
@@ -225,7 +233,133 @@
 	(setf (view stack-frame) +minimized-stack-frame-view+))
     (change-space-requirements (frame-panes *application-frame*))))
 
+;;; We want to be able to invoke restarts with the 1-9 letters on the
+;;; keyboard.
 
+(define-clim-debugger-command
+    (com-invoke-restart-by-number
+     :name "Invoke numbered restart")
+    ((number 'integer))
+  ;; `number' is the number of the restart to invoke. This
+  ;; is simply used as an index into a list.
+  (let* ((debugger-pane
+          (get-frame-pane *application-frame* 'debugger-pane))
+         (restarts
+          (restarts
+           (condition-info debugger-pane)))
+         (selected-restart (nth number restarts)))
+    ;; If the restart is not valid, we just ignore the command.
+    (when selected-restart 
+      (setf *returned-restart* selected-restart)
+      (frame-exit *application-frame*))))
+
+;;; We associate keystrokes in the interval 0-9 to calls to
+;;; `clim-invoke-restart' with the keystroke as argument. Is this a
+;;; kludge? I couln't find a better way to do it.
+
+;; Define a macro for convenience.
+
+(defmacro keybind-restart-commands (n)
+  "Associate the numeric keys in the interval 0-N with a call to
+`clim-invoke-restart' with the relevant number as argument."
+  `(progn
+     ,@(loop for r from 0 upto n
+          collecting
+          `(add-command-to-command-table
+            '(com-invoke-restart-by-number ,r)
+            'clim-debugger
+            :keystroke '(,(code-char (+ (char-code #\0) r)))))))
+
+(keybind-restart-commands 9)
+
+;; We also define an abort-command to permit quick exit.
+
+(define-clim-debugger-command
+ (com-invoke-abort-restart
+  :name "Invoke abort restart"
+  :keystroke (#\q))
+ ()
+ (setf *returned-restart* nil)
+ (frame-exit *application-frame*))
+
+;; We want to be able to navigate the list of stack frames 
+;; with the keyboard.
+
+(define-clim-debugger-command
+ (com-next-stackframe
+  :name "Next stackframe"
+  :keystroke (#\n :control))
+ ()
+ (let ((debugger-pane (get-frame-pane *application-frame* 'debugger-pane)))
+   (when (< (selected-stackframe debugger-pane)
+            (1- (length (backtrace (condition-info debugger-pane)))))
+     (incf (selected-stackframe debugger-pane)))))
+
+(add-command-to-command-table
+ 'com-next-stackframe
+ 'clim-debugger
+ :errorp nil
+ :keystroke '(#\n))
+
+(define-clim-debugger-command
+ (com-prev-stackframe
+  :name "Previous stackframe"
+  :keystroke (#\p :control))
+ ()
+ (let ((debugger-pane (get-frame-pane *application-frame* 'debugger-pane)))
+   (when (> (selected-stackframe debugger-pane) 0)
+     (decf (selected-stackframe debugger-pane)))))
+
+(add-command-to-command-table
+ 'com-prev-stackframe
+ 'clim-debugger
+ :errorp nil
+ :keystroke '(#\p))
+
+(define-clim-debugger-command
+ (com-toggle-selected-stackframe-view
+  :name "Toggle view of selected stackframe"
+  :keystroke (#\e))
+ ()
+ (let* ((debugger-pane (get-frame-pane *application-frame* 'debugger-pane))
+	(stackframe (nth (selected-stackframe debugger-pane)
+			 (backtrace (condition-info debugger-pane)))))
+   (execute-frame-command *application-frame* 
+			  `(com-toggle-stack-frame-view ,stackframe))))
+
+(define-clim-debugger-command
+    (com-browse-next-stackframe
+     :name "Browse next stackframe"
+     :keystroke (#\N))
+    ()
+  ;; Minize current stackframe, select and expand next stackframe.
+  (let* ((debugger-pane (get-frame-pane *application-frame* 'debugger-pane))
+         (current-stackframe (nth (selected-stackframe debugger-pane)
+                                  (backtrace (condition-info debugger-pane)))))
+    (setf (view current-stackframe) +minimized-stack-frame-view+)
+    (com-next-stackframe)
+    ;; We have a new current stackframe (this shadowing may be a bit
+    ;; ugly)..
+    (let ((current-stackframe (nth (selected-stackframe debugger-pane)
+                                  (backtrace (condition-info debugger-pane)))))
+      (setf (view current-stackframe) +maximized-stack-frame-view+))))
+
+(define-clim-debugger-command
+    (com-browse-prev-stackframe
+     :name "Browse previous stackframe"
+     :keystroke (#\P))
+    ()
+  ;; Minize current stackframe, select and expand previous stackframe.
+  (let* ((debugger-pane (get-frame-pane *application-frame* 'debugger-pane))
+         (current-stackframe (nth (selected-stackframe debugger-pane)
+                                  (backtrace (condition-info debugger-pane)))))
+    (setf (view current-stackframe) +minimized-stack-frame-view+)
+    (com-prev-stackframe)
+    ;; We have a new current stackframe.
+    (let ((current-stackframe (nth (selected-stackframe debugger-pane)
+                                  (backtrace (condition-info debugger-pane)))))
+      (setf (view current-stackframe) +maximized-stack-frame-view+))))
+    
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;   Command translators   ;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -287,9 +421,12 @@
     (formatting-table 
 	(pane)
       (loop for r in (restarts (condition-info pane))
+           for rcount from 0
         do (formatting-row (pane)
               (with-output-as-presentation (pane r 'restart)
                 (formatting-cell (pane)
+                  (format pane "~A." rcount))
+                (formatting-cell (pane)
                   (format pane "~A" (restart-name r)))
               
                 (formatting-cell (pane)
@@ -314,6 +451,9 @@
 	  for i from 0
 	  do (formatting-row (pane)
                (with-output-as-presentation (pane stack-frame 'stack-frame)
+		 (formatting-cell (pane) (format t "~A" (if (= (selected-stackframe pane) i)
+							    ">"
+							    "")))
                  (bold (pane) (formatting-cell (pane) (format t "~A: " i)))
                  (formatting-cell (pane)
                    (present stack-frame 'stack-frame 
