]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/idlw-shell.el
Merge from emacs--rel--22
[gnu-emacs] / lisp / progmodes / idlw-shell.el
index ff1bb7b689f226a90ea720b2b7004fe196f46b8c..f903d490565df844d681aba55ce4232b84a6b349 100644 (file)
@@ -1,19 +1,20 @@
 ;; idlw-shell.el --- run IDL as an inferior process of Emacs.
 ;; idlw-shell.el --- run IDL as an inferior process of Emacs.
-;; Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-;; Free Software Foundation, Inc.
+
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;;    Free Software Foundation, Inc.
 
 ;; Authors: J.D. Smith <jdsmith@as.arizona.edu>
 ;;          Carsten Dominik <dominik@astro.uva.nl>
 ;;          Chris Chase <chase@att.com>
 ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu>
 
 ;; Authors: J.D. Smith <jdsmith@as.arizona.edu>
 ;;          Carsten Dominik <dominik@astro.uva.nl>
 ;;          Chris Chase <chase@att.com>
 ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu>
-;; Version: 5.7_22
+;; Version: 6.1_em22
 ;; Keywords: processes
 
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; Keywords: processes
 
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -31,7 +32,7 @@
 ;; This mode is for IDL version 5 or later.  It should work on
 ;; Emacs>20.3 or XEmacs>20.4.
 ;;
 ;; This mode is for IDL version 5 or later.  It should work on
 ;; Emacs>20.3 or XEmacs>20.4.
 ;;
-;; Runs IDL as an inferior process of Emacs, much like the emacs
+;; Runs IDL as an inferior process of Emacs, much like the Emacs
 ;; `shell' or `telnet' commands.  Provides command history and
 ;; searching.  Provides debugging commands available in buffers
 ;; visiting IDL procedure files, e.g., breakpoint setting, stepping,
 ;; `shell' or `telnet' commands.  Provides command history and
 ;; searching.  Provides debugging commands available in buffers
 ;; visiting IDL procedure files, e.g., breakpoint setting, stepping,
@@ -138,6 +139,11 @@ process output is made by surrounding this name with `*'s."
 
 ;; (defcustom idlwave-shell-automatic-start...)  See idlwave.el
 
 
 ;; (defcustom idlwave-shell-automatic-start...)  See idlwave.el
 
+(defcustom idlwave-shell-use-dedicated-window nil
+  "*Non-nil means, never replace the shell frame with another buffer."
+  :group 'idlwave-shell-general-setup
+  :type 'boolean) 
+
 (defcustom idlwave-shell-use-dedicated-frame nil
   "*Non-nil means, IDLWAVE should use a special frame to display shell buffer."
   :group 'idlwave-shell-general-setup
 (defcustom idlwave-shell-use-dedicated-frame nil
   "*Non-nil means, IDLWAVE should use a special frame to display shell buffer."
   :group 'idlwave-shell-general-setup
@@ -247,7 +253,7 @@ to set this option to nil."
   :group 'idlwave-shell-general-setup
   :type 'boolean)
 
   :group 'idlwave-shell-general-setup
   :type 'boolean)
 
-(defcustom idlwave-shell-file-name-chars "~/A-Za-z0-9+:_.$#%={}\\-"
+(defcustom idlwave-shell-file-name-chars "~/A-Za-z0-9+:_.$#%={}\\- "
   "The characters allowed in file names, as a string.
 Used for file name completion. Must not contain `'', `,' and `\"'
 because these are used as separators by IDL."
   "The characters allowed in file names, as a string.
 Used for file name completion. Must not contain `'', `,' and `\"'
 because these are used as separators by IDL."
@@ -313,8 +319,15 @@ the copious shell traffic to be displayed."
               (const :tag "All debug and stepping commands"       debug)
               (const :tag "Close, window, retall, etc. commands"  misc))))
 
               (const :tag "All debug and stepping commands"       debug)
               (const :tag "Close, window, retall, etc. commands"  misc))))
 
+(defcustom idlwave-shell-max-print-length 200
+  "Maximum number of array elements to print when examining."
+  :group 'idlwave-shell-command-setup
+  :type 'integer)
+
 (defcustom idlwave-shell-examine-alist 
 (defcustom idlwave-shell-examine-alist 
-  '(("Print"           . "print,___")
+  `(("Print"           . ,(concat "idlwave_print_safe,___," 
+                                  (number-to-string 
+                                   idlwave-shell-max-print-length)))
     ("Help"            . "help,___")
     ("Structure Help"          . "help,___,/STRUCTURE")
     ("Dimensions"      . "print,size(___,/DIMENSIONS)")
     ("Help"            . "help,___")
     ("Structure Help"          . "help,___,/STRUCTURE")
     ("Dimensions"      . "print,size(___,/DIMENSIONS)")
@@ -322,6 +335,7 @@ the copious shell traffic to be displayed."
     ("N_Elements"      . "print,n_elements(___)")
     ("All Size Info"   . "help,(__IWsz__=size(___,/STRUCTURE)),/STRUCTURE & print,__IWsz__.DIMENSIONS")
     ("Ptr Valid"       . "print,ptr_valid(___)")
     ("N_Elements"      . "print,n_elements(___)")
     ("All Size Info"   . "help,(__IWsz__=size(___,/STRUCTURE)),/STRUCTURE & print,__IWsz__.DIMENSIONS")
     ("Ptr Valid"       . "print,ptr_valid(___)")
+    ("Arg Present"      . "print,arg_present(___)")
     ("Widget Valid"     . "print,widget_info(___,/VALID)")
     ("Widget Geometry"  . "help,widget_info(___,/GEOMETRY)"))
   "Alist of special examine commands for popup selection.  
     ("Widget Valid"     . "print,widget_info(___,/VALID)")
     ("Widget Geometry"  . "help,widget_info(___,/GEOMETRY)"))
   "Alist of special examine commands for popup selection.  
@@ -437,6 +451,11 @@ popup help text on the line."
   :group 'idlwave-shell-command-setup
   :type 'boolean)
 
   :group 'idlwave-shell-command-setup
   :type 'boolean)
 
+(defcustom idlwave-shell-reset-no-prompt nil
+  "If non-nil, skip the yes/no prompt when resetting the IDL session."
+  :group 'idlwave-shell-command-setup
+  :type 'boolean)
+
 ;; Breakpoint Overlays etc
 (defgroup idlwave-shell-highlighting-and-faces nil
   "Highlighting and Faces used by the IDLWAVE Shell mode."
 ;; Breakpoint Overlays etc
 (defgroup idlwave-shell-highlighting-and-faces nil
   "Highlighting and Faces used by the IDLWAVE Shell mode."
@@ -488,11 +507,11 @@ line where IDL is stopped.  See also `idlwave-shell-mark-stop-line'."
 
 (defcustom idlwave-shell-electric-stop-line-face 
   (prog1
 
 (defcustom idlwave-shell-electric-stop-line-face 
   (prog1
-      (copy-face 'modeline 'idlwave-shell-electric-stop-line-face)
-    (set-face-background 'idlwave-shell-electric-stop-line-face 
+      (copy-face 'modeline 'idlwave-shell-electric-stop-line)
+    (set-face-background 'idlwave-shell-electric-stop-line 
                         idlwave-shell-electric-stop-color)
     (condition-case nil
                         idlwave-shell-electric-stop-color)
     (condition-case nil
-       (set-face-foreground 'idlwave-shell-electric-stop-line-face nil)
+       (set-face-foreground 'idlwave-shell-electric-stop-line nil)
       (error nil)))
   "*The face for `idlwave-shell-stop-line-overlay' when in electric debug mode.
 Allows you to choose the font, color and other properties for the line
       (error nil)))
   "*The face for `idlwave-shell-stop-line-overlay' when in electric debug mode.
 Allows you to choose the font, color and other properties for the line
@@ -553,6 +572,7 @@ lines which have a breakpoint.  See also `idlwave-shell-mark-breakpoints'."
     "Face for highlighting lines with breakpoints."
     :group 'idlwave-shell-highlighting-and-faces))
 
     "Face for highlighting lines with breakpoints."
     :group 'idlwave-shell-highlighting-and-faces))
 
+
 (defcustom idlwave-shell-expression-face 'secondary-selection
   "*The face for `idlwave-shell-expression-overlay'.
 Allows you to choose the font, color and other properties for
 (defcustom idlwave-shell-expression-face 'secondary-selection
   "*The face for `idlwave-shell-expression-overlay'.
 Allows you to choose the font, color and other properties for
@@ -652,7 +672,7 @@ the directory stack.")
   "The overlay for where IDL is currently stopped.")
 (defvar idlwave-shell-is-stopped nil)
 (defvar idlwave-shell-expression-overlay nil
   "The overlay for where IDL is currently stopped.")
 (defvar idlwave-shell-is-stopped nil)
 (defvar idlwave-shell-expression-overlay nil
-  "The overlay for where IDL is currently stopped.")
+  "The overlay for the examined expression.")
 (defvar idlwave-shell-output-overlay nil
   "The overlay for the last IDL output.")
 
 (defvar idlwave-shell-output-overlay nil
   "The overlay for the last IDL output.")
 
@@ -700,10 +720,21 @@ the directory stack.")
 (setq idlwave-shell-expression-overlay (make-overlay 1 1))
 (overlay-put idlwave-shell-expression-overlay
             'face idlwave-shell-expression-face)
 (setq idlwave-shell-expression-overlay (make-overlay 1 1))
 (overlay-put idlwave-shell-expression-overlay
             'face idlwave-shell-expression-face)
+(overlay-put idlwave-shell-expression-overlay
+            'priority 1)
 (setq idlwave-shell-output-overlay (make-overlay 1 1))
 (overlay-put idlwave-shell-output-overlay
             'face idlwave-shell-output-face)
 
 (setq idlwave-shell-output-overlay (make-overlay 1 1))
 (overlay-put idlwave-shell-output-overlay
             'face idlwave-shell-output-face)
 
+(copy-face idlwave-shell-stop-line-face 
+          'idlwave-shell-pending-stop)
+(copy-face idlwave-shell-electric-stop-line-face 
+          'idlwave-shell-pending-electric-stop)
+(set-face-background 'idlwave-shell-pending-stop "gray70")
+(set-face-background 'idlwave-shell-pending-electric-stop "gray70")
+
+
+
 (defvar idlwave-shell-bp-query "help,/breakpoints"
   "Command to obtain list of breakpoints")
 
 (defvar idlwave-shell-bp-query "help,/breakpoints"
   "Command to obtain list of breakpoints")
 
@@ -823,6 +854,7 @@ IDL has currently stepped.")
   ?          Help on expression near point or in region ([C-u ?]).
   x          Examine expression near point or in region ([C-u x]) with 
              letter completion of the examine type.
   ?          Help on expression near point or in region ([C-u ?]).
   x          Examine expression near point or in region ([C-u x]) with 
              letter completion of the examine type.
+  e          Prompt for an expression to print.
 
  Miscellaneous:
   q         Quit - end debugging session and return to the Shell's main level.
 
  Miscellaneous:
   q         Quit - end debugging session and return to the Shell's main level.
@@ -994,10 +1026,13 @@ IDL has currently stepped.")
   (setq idlwave-shell-ready nil)
   (setq idlwave-shell-bp-alist nil)
   (idlwave-shell-update-bp-overlays) ; Throw away old overlays
   (setq idlwave-shell-ready nil)
   (setq idlwave-shell-bp-alist nil)
   (idlwave-shell-update-bp-overlays) ; Throw away old overlays
-  (setq idlwave-shell-sources-alist nil)
+  (setq idlwave-shell-post-command-hook nil ;clean up any old stuff
+       idlwave-shell-sources-alist nil)
   (setq idlwave-shell-default-directory default-directory)
   (setq idlwave-shell-hide-output nil)
 
   (setq idlwave-shell-default-directory default-directory)
   (setq idlwave-shell-hide-output nil)
 
+  ;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
+  ;; (make-local-hook 'kill-buffer-hook)
   (add-hook 'kill-buffer-hook 'idlwave-shell-kill-shell-buffer-confirm
            nil 'local)
   (add-hook 'kill-buffer-hook 'idlwave-shell-delete-temp-files nil 'local)
   (add-hook 'kill-buffer-hook 'idlwave-shell-kill-shell-buffer-confirm
            nil 'local)
   (add-hook 'kill-buffer-hook 'idlwave-shell-delete-temp-files nil 'local)
@@ -1040,6 +1075,8 @@ IDL has currently stepped.")
   (set (make-local-variable 'comment-start) ";")
   (setq abbrev-mode t)
 
   (set (make-local-variable 'comment-start) ";")
   (setq abbrev-mode t)
 
+  ;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
+  ;; make-local-hook 'post-command-hook)
   (add-hook 'post-command-hook 'idlwave-command-hook nil t)
 
   ;; Read the command history?
   (add-hook 'post-command-hook 'idlwave-command-hook nil t)
 
   ;; Read the command history?
@@ -1061,23 +1098,25 @@ IDL has currently stepped.")
   (idlwave-shell-send-command 
    (format "defsysv,'!idlwave_version','%s',1" idlwave-mode-version)
    nil 'hide)
   (idlwave-shell-send-command 
    (format "defsysv,'!idlwave_version','%s',1" idlwave-mode-version)
    nil 'hide)
-  ;; Get the paths if they weren't read in from file
-  (if (and (not idlwave-path-alist)
-          (or (not (stringp idlwave-system-directory))
-              (eq (length idlwave-system-directory) 0)))
-      (idlwave-shell-send-command idlwave-shell-path-query
-                                 'idlwave-shell-get-path-info
-                                 'hide)))
+  ;; Read the paths, and save if they changed
+  (idlwave-shell-send-command idlwave-shell-path-query
+                             'idlwave-shell-get-path-info
+                             'hide))
 
 
+(defvar idlwave-system-directory)
 (defun idlwave-shell-get-path-info (&optional no-write)
   "Get the path lists, writing to file unless NO-WRITE is set."
   (let* ((rpl (idlwave-shell-path-filter))
         (sysdir (car rpl))
         (dirs (cdr rpl))
 (defun idlwave-shell-get-path-info (&optional no-write)
   "Get the path lists, writing to file unless NO-WRITE is set."
   (let* ((rpl (idlwave-shell-path-filter))
         (sysdir (car rpl))
         (dirs (cdr rpl))
-        (old-path-alist idlwave-path-alist))
+        (old-path-alist idlwave-path-alist)
+        (old-sys-dir idlwave-system-directory)
+        path-changed sysdir-changed)
     (when sysdir
       (setq idlwave-system-directory sysdir)
     (when sysdir
       (setq idlwave-system-directory sysdir)
-      (put 'idlwave-system-directory 'from-shell t))
+      (if (setq sysdir-changed 
+               (not (string= idlwave-system-directory old-sys-dir)))
+         (put 'idlwave-system-directory 'from-shell t)))
     ;; Preserve any existing flags
     (setq idlwave-path-alist 
          (mapcar (lambda (x)
     ;; Preserve any existing flags
     (setq idlwave-path-alist 
          (mapcar (lambda (x)
@@ -1086,11 +1125,13 @@ IDL has currently stepped.")
                          (cons x (cdr old-entry))
                        (list x))))
                  dirs))
                          (cons x (cdr old-entry))
                        (list x))))
                  dirs))
-    (put 'idlwave-path-alist 'from-shell t)
+    (if (setq path-changed (not (equal idlwave-path-alist old-path-alist)))
+       (put 'idlwave-path-alist 'from-shell t))
     (if idlwave-path-alist 
     (if idlwave-path-alist 
-       (if (and idlwave-auto-write-paths
-                (not idlwave-library-path)
-                (not no-write) )
+       (if (and (not no-write)
+                idlwave-auto-write-paths
+                (or sysdir-changed path-changed)
+                (not idlwave-library-path))
            (idlwave-write-paths))
       ;; Fall back
       (setq idlwave-path-alist old-path-alist))))
            (idlwave-write-paths))
       ;; Fall back
       (setq idlwave-path-alist old-path-alist))))
@@ -1199,12 +1240,14 @@ See also the variable `idlwave-shell-prompt-pattern'.
          (current-window (selected-window)))
       (select-window window)
       (goto-char (point-max))
          (current-window (selected-window)))
       (select-window window)
       (goto-char (point-max))
+      (if idlwave-shell-use-dedicated-window
+         (set-window-dedicated-p window t))
       (select-window current-window)
       (if idlwave-shell-ready
          (raise-frame (window-frame window)))
       (if (eq (selected-frame) (window-frame window))
          (select-window window))))
       (select-window current-window)
       (if idlwave-shell-ready
          (raise-frame (window-frame window)))
       (if (eq (selected-frame) (window-frame window))
          (select-window window))))
-  ;; Save the paths at the end
+  ;; Save the paths at the end, if they are from the Shell and new.
   (add-hook 'idlwave-shell-sentinel-hook 
            (lambda ()
              (if (and 
   (add-hook 'idlwave-shell-sentinel-hook 
            (lambda ()
              (if (and 
@@ -1261,7 +1304,7 @@ output to complete and the next prompt to arrive before returning
 \(useful if you need an answer now\). IDL is considered ready if the
 prompt is present and if `idlwave-shell-ready' is non-nil.  
 
 \(useful if you need an answer now\). IDL is considered ready if the
 prompt is present and if `idlwave-shell-ready' is non-nil.  
 
-If SHOW-IF-ERROR is non-nil, show the output it it contains an error
+If SHOW-IF-ERROR is non-nil, show the output if it contains an error
 message, independent of what HIDE is set to."
 
 ;  (setq hide nil)  ;  FIXME: turn this on for debugging only
 message, independent of what HIDE is set to."
 
 ;  (setq hide nil)  ;  FIXME: turn this on for debugging only
@@ -1430,11 +1473,7 @@ Otherwise just move the line.  Move down unless UP is non-nil."
     (if (eq t idlwave-shell-arrows-do-history) (goto-char proc-pos))
     (if (and idlwave-shell-arrows-do-history
             (>= (1+ (save-excursion (end-of-line) (point))) proc-pos))
     (if (eq t idlwave-shell-arrows-do-history) (goto-char proc-pos))
     (if (and idlwave-shell-arrows-do-history
             (>= (1+ (save-excursion (end-of-line) (point))) proc-pos))
-       (progn
-         ;;(goto-char proc-pos)
-         (goto-char (point-max))
-         ;;(and (not (eolp)) (kill-line nil))
-         (comint-previous-input arg))
+       (comint-previous-input arg)
       (previous-line arg))))
 
 (defun idlwave-shell-up-or-history (&optional arg)
       (previous-line arg))))
 
 (defun idlwave-shell-up-or-history (&optional arg)
@@ -1518,10 +1557,10 @@ and then calls `idlwave-shell-send-command' for any pending commands."
            
            
 ;;; Test/Debug code
            
            
 ;;; Test/Debug code
-;            (save-excursion (set-buffer
-;                             (get-buffer-create "*idlwave-shell-output*"))
-;                            (goto-char (point-max))
-;                            (insert "\nSTRING===>\n" string "\n<====\n"))
+             ;(with-current-buffer
+             ;   (get-buffer-create "*idlwave-shell-output*")
+             ; (goto-char (point-max))
+             ; (insert "\nReceived STRING\n===>\n" string "\n<====\n"))
            
              ;; Check for prompt in current accumulating output
              (when (setq idlwave-shell-ready
            
              ;; Check for prompt in current accumulating output
              (when (setq idlwave-shell-ready
@@ -1536,14 +1575,15 @@ and then calls `idlwave-shell-send-command' for any pending commands."
                      (re-search-backward idlwave-shell-prompt-pattern nil t)
                      (goto-char (match-end 0))
                      (setq idlwave-shell-command-output
                      (re-search-backward idlwave-shell-prompt-pattern nil t)
                      (goto-char (match-end 0))
                      (setq idlwave-shell-command-output
-                     (buffer-substring (point-min) (point)))
+                           (buffer-substring-no-properties 
+                            (point-min) (point)))
                      (delete-region (point-min) (point)))
                  (setq idlwave-shell-command-output
                        (with-current-buffer (process-buffer proc)
                      (delete-region (point-min) (point)))
                  (setq idlwave-shell-command-output
                        (with-current-buffer (process-buffer proc)
-                       (buffer-substring
+                       (buffer-substring-no-properties
                         (save-excursion
                           (goto-char (process-mark proc))
                         (save-excursion
                           (goto-char (process-mark proc))
-                          (forward-line 0)
+                          (forward-line 0) ; Emacs 21 (beginning-of-line nil)
                           (point))
                         comint-last-input-end))))
 
                           (point))
                         comint-last-input-end))))
 
@@ -1570,10 +1610,10 @@ and then calls `idlwave-shell-send-command' for any pending commands."
                  ;; Call the post-command hook
                  (if (listp idlwave-shell-post-command-hook)
                      (progn
                  ;; Call the post-command hook
                  (if (listp idlwave-shell-post-command-hook)
                      (progn
-                                       ;(message "Calling list")
-                                       ;(prin1 idlwave-shell-post-command-hook)
+                       ;;(message "Calling list")
+                       ;;(prin1 idlwave-shell-post-command-hook)
                        (eval idlwave-shell-post-command-hook))
                        (eval idlwave-shell-post-command-hook))
-                                       ;(message "Calling command function")
+                   ;;(message "Calling command function")
                    (funcall idlwave-shell-post-command-hook))
 
                  ;; Reset to default state for next command.
                    (funcall idlwave-shell-post-command-hook))
 
                  ;; Reset to default state for next command.
@@ -1668,6 +1708,8 @@ The 5th group is the file name.
 All parts may contain linebreaks surrounded by spaces.  This is important
 in IDL5 which inserts random linebreaks in long module and file names.")
 
 All parts may contain linebreaks surrounded by spaces.  This is important
 in IDL5 which inserts random linebreaks in long module and file names.")
 
+(defvar idlwave-shell-electric-debug-mode) ; defined by easy-mmode
+
 (defun idlwave-shell-scan-for-state ()
   "Scan for state info.  Looks for messages in output from last IDL
 command indicating where IDL has stopped. The types of messages we are
 (defun idlwave-shell-scan-for-state ()
   "Scan for state info.  Looks for messages in output from last IDL
 command indicating where IDL has stopped. The types of messages we are
@@ -1688,9 +1730,8 @@ the above."
                     idlwave-shell-command-output)
        (string-match idlwave-shell-other-error
                     idlwave-shell-command-output))
                     idlwave-shell-command-output)
        (string-match idlwave-shell-other-error
                     idlwave-shell-command-output))
-      (save-excursion
-       (set-buffer
-        (get-buffer-create idlwave-shell-error-buffer))
+      (with-current-buffer
+         (get-buffer-create idlwave-shell-error-buffer)
        (erase-buffer)
        (insert idlwave-shell-command-output)
        (goto-char (point-min))
        (erase-buffer)
        (insert idlwave-shell-command-output)
        (goto-char (point-min))
@@ -1723,8 +1764,10 @@ the above."
             (substring idlwave-shell-command-output (match-end 0))))
       (setq idlwave-shell-current-state 'halt)
       ;; Don't debug trace messages
             (substring idlwave-shell-command-output (match-end 0))))
       (setq idlwave-shell-current-state 'halt)
       ;; Don't debug trace messages
-      (idlwave-shell-display-line (idlwave-shell-pc-frame) nil
-                                 (if trace 'no-debug)))
+      (idlwave-shell-display-line 
+       (idlwave-shell-pc-frame) nil
+       (if trace 'disable
+        (if idlwave-shell-electric-debug-mode 'force))))
      
      ;; Fourth Priority: Breakpoints 
      ((string-match idlwave-shell-break-message
      
      ;; Fourth Priority: Breakpoints 
      ((string-match idlwave-shell-break-message
@@ -1763,29 +1806,29 @@ the above."
 
 
 (defun idlwave-shell-parse-line (string &optional skip-main)
 
 
 (defun idlwave-shell-parse-line (string &optional skip-main)
-  "Parse IDL message for the subroutine, file name and line number.
-We need to work hard here to remove the stupid line breaks inserted by
-IDL5.  These line breaks can be right in the middle of procedure
-or file names.
-It is very difficult to come up with a robust solution.  This one seems
-to be pretty good though.  
-
-Here is in what ways it improves over the previous solution:
-
-1. The procedure name can be split and will be restored.
-2. The number can be split.  I have never seen this, but who knows.
-3. We do not require the `.pro' extension for files.
-
-This function can still break when the file name ends on a end line
-and the message line contains an additional line with garbage.  Then
-the first part of that garbage will be added to the file name.
-However, the function checks the existence of the files with and
-without this last part - thus the function only breaks if file name
-plus garbage match an existing regular file.  This is hopefully very
-unlikely.
-
-If optional arg SKIP-MAIN is non-nil, don't parse $MAIN$ routine stop
-statements."
+  "Parse IDL message for the subroutine, file name and line number."
+;We need to work hard here to remove the stupid line breaks inserted by
+;IDL5.  These line breaks can be right in the middle of procedure
+;or file names.
+;It is very difficult to come up with a robust solution.  This one seems
+;to be pretty good though.  
+;
+;Here is in what ways it improves over the previous solution:
+;
+;1. The procedure name can be split and will be restored.
+;2. The number can be split.  I have never seen this, but who knows.
+;3. We do not require the `.pro' extension for files.
+;
+;This function can still break when the file name ends on an end line
+;and the message line contains an additional line with garbage.  Then
+;the first part of that garbage will be added to the file name.
+;However, the function checks the existence of the files with and
+;without this last part - thus the function only breaks if file name
+;plus garbage match an existing regular file.  This is hopefully very
+;unlikely.
+;
+;If optional arg SKIP-MAIN is non-nil, don't parse $MAIN$ routine stop
+;statements.
 
   (let (number procedure file)
     (when (and (not (if skip-main (string-match ":\\s-*\\$MAIN" string)))
 
   (let (number procedure file)
     (when (and (not (if skip-main (string-match ":\\s-*\\$MAIN" string)))
@@ -1926,14 +1969,17 @@ CLOSE, /ALL
 HEAP_GC, /VERBOSE"
   ;; OBJ_DESTROY, OBJ_VALID()  FIXME: should this be added?
   (interactive "P")
 HEAP_GC, /VERBOSE"
   ;; OBJ_DESTROY, OBJ_VALID()  FIXME: should this be added?
   (interactive "P")
-  (message "Resetting IDL")
-  (setq idlwave-shell-calling-stack-index 0)
-  (idlwave-shell-send-command "retall" nil hidden)
-  (idlwave-shell-send-command "widget_control,/reset" nil hidden)
-  (idlwave-shell-send-command "close,/all" nil hidden)
-  ;; (idlwave-shell-send-command "obj_destroy, obj_valid()" nil hidden)
-  (idlwave-shell-send-command "heap_gc,/verbose" nil hidden)
-  (idlwave-shell-display-line nil))
+  (when (or idlwave-shell-reset-no-prompt 
+           (yes-or-no-p "Really Reset IDL and discard current session? "))
+    (message "Resetting IDL")
+    (setq idlwave-shell-calling-stack-index 0)
+    ;; Give widget exit handlers a chance
+    (idlwave-shell-send-command "retall" nil hidden)
+    (idlwave-shell-send-command "widget_control,/reset" nil hidden)
+    (idlwave-shell-send-command "close,/all" nil hidden)
+    ;; (idlwave-shell-send-command "obj_destroy, obj_valid()" nil hidden)
+    (idlwave-shell-send-command "heap_gc,/verbose" nil hidden)
+    (idlwave-shell-display-line nil)))
 
 (defun idlwave-shell-path-filter ()
   ;; Convert the output of the path query into a list of directories
 
 (defun idlwave-shell-path-filter ()
   ;; Convert the output of the path query into a list of directories
@@ -1978,9 +2024,6 @@ HEAP_GC, /VERBOSE"
          (message 
           "Routine Info warning: No match for END line in \n>>>\n%s\n<<<\n" 
           idlwave-shell-command-output)))
          (message 
           "Routine Info warning: No match for END line in \n>>>\n%s\n<<<\n" 
           idlwave-shell-command-output)))
-    (if (string-match "\\S-" text)
-       ;; Obviously, the pro worked.  Make a note that we have it now.
-       (setq idlwave-idlwave_routine_info-compiled t))
     ;; Match the output lines
     (while (string-match "^IDLWAVE-\\(PRO\\|FUN\\): \\(.*\\)" text start)
       (setq start (match-end 0))
     ;; Match the output lines
     (while (string-match "^IDLWAVE-\\(PRO\\|FUN\\): \\(.*\\)" text start)
       (setq start (match-end 0))
@@ -2061,7 +2104,7 @@ HEAP_GC, /VERBOSE"
 Change the default directory for the process buffer to concur."
   (save-excursion
     (set-buffer (idlwave-shell-buffer))
 Change the default directory for the process buffer to concur."
   (save-excursion
     (set-buffer (idlwave-shell-buffer))
-    (if (string-match ",___cur[\n\r]\\(\\S-*\\) *[\n\r]"
+    (if (string-match ",___cur[\n\r ]+\\([^\n\r]+\\)[\n\r]"
                      idlwave-shell-command-output)
        (let ((dir (substring idlwave-shell-command-output 
                              (match-beginning 1) (match-end 1))))
                      idlwave-shell-command-output)
        (let ((dir (substring idlwave-shell-command-output 
                              (match-beginning 1) (match-end 1))))
@@ -2208,7 +2251,6 @@ args of an executive .run, .rnew or .compile."
     (looking-at "\\$")))
 
 ;; Debugging Commands ------------------------------------------------------
     (looking-at "\\$")))
 
 ;; Debugging Commands ------------------------------------------------------
-(defvar idlwave-shell-electric-debug-mode) ; defined by easy-mmode
 
 (defun idlwave-shell-redisplay (&optional hide)
   "Tries to resync the display with where execution has stopped.
 
 (defun idlwave-shell-redisplay (&optional hide)
   "Tries to resync the display with where execution has stopped.
@@ -2259,14 +2301,14 @@ overlays."
     (setq idlwave-shell-calling-stack-routine 
          (nth 2 (nth idlwave-shell-calling-stack-index stack)))
 
     (setq idlwave-shell-calling-stack-routine 
          (nth 2 (nth idlwave-shell-calling-stack-index stack)))
 
-    ;; only edebug if in that mode already
+    ;; force edebug for this frame if we're in that mode already
     (idlwave-shell-display-line 
      (nth idlwave-shell-calling-stack-index stack) nil
     (idlwave-shell-display-line 
      (nth idlwave-shell-calling-stack-index stack) nil
-     (unless idlwave-shell-electric-debug-mode 'no-debug)) 
+     (if idlwave-shell-electric-debug-mode 'force))
     (message "%s" (or message 
     (message "%s" (or message 
-                (format "In routine %s (stack level %d)"
-                        idlwave-shell-calling-stack-routine
-                        (- idlwave-shell-calling-stack-index))))))
+                     (format "In routine %s (stack level %d)"
+                             idlwave-shell-calling-stack-routine
+                             (- idlwave-shell-calling-stack-index))))))
 
 (defun idlwave-shell-stack-up ()
   "Display the source code one step up the calling stack."
 
 (defun idlwave-shell-stack-up ()
   "Display the source code one step up the calling stack."
@@ -2302,30 +2344,38 @@ used.  Does nothing if the resulting frame is nil."
   "Check that frame is for an existing file."
   (file-readable-p (car frame)))
 
   "Check that frame is for an existing file."
   (file-readable-p (car frame)))
 
-(defvar idlwave-shell-suppress-electric-debug nil)
-(defun idlwave-shell-display-line (frame &optional col no-debug)
-  "Display FRAME file in other window with overlay arrow.
+(defun idlwave-shell-stop-line-pending ()
+  ;; Temporarily change the color of the stop line overlay
+  (if idlwave-shell-stop-line-overlay
+      (overlay-put idlwave-shell-stop-line-overlay 'face
+                  (if idlwave-shell-electric-debug-mode
+                      'idlwave-shell-pending-electric-stop
+                    'idlwave-shell-pending-stop))))
 
 
-FRAME is a list of file name, line number, and subroutine name.  If
-FRAME is nil then remove overlay.  If COL is set, move point to that
-column in the line.  If NO-DEBUG is non-nil, do *not* toggle the electric
-debug mode."
+(defvar idlwave-shell-suppress-electric-debug nil)
+(defun idlwave-shell-display-line (frame &optional col debug)
+  "display frame file in other window with overlay arrow.
+
+frame is a list of file name, line number, and subroutine name.  if
+frame is nil then remove overlay.  if col is set, move point to that
+column in the line.  if debug is non-nil, enable the electric debug
+mode.  if it is 'disable, do not enable no matter what the setting of
+'idlwave-shell-automatic-electric-debug'.  if it is 'force, enable no
+matter what the settings of that variable."
   (if (not frame)
   (if (not frame)
-      ;; Remove stop-line overlay from old position
+      ;; remove stop-line overlay from old position
       (progn 
         (setq overlay-arrow-string nil)
        (setq idlwave-shell-mode-line-info nil)
        (setq idlwave-shell-is-stopped nil)
         (if idlwave-shell-stop-line-overlay
             (delete-overlay idlwave-shell-stop-line-overlay))
       (progn 
         (setq overlay-arrow-string nil)
        (setq idlwave-shell-mode-line-info nil)
        (setq idlwave-shell-is-stopped nil)
         (if idlwave-shell-stop-line-overlay
             (delete-overlay idlwave-shell-stop-line-overlay))
-       ;; Turn off electric debug everywhere, if it's on
-       (if (and (not no-debug)
-                idlwave-shell-automatic-electric-debug)
-           (idlwave-shell-electric-debug-all-off)))
+       ;; turn off electric debug everywhere, if it's on
+       (idlwave-shell-electric-debug-all-off))
     (if (not (idlwave-shell-valid-frame frame))
     (if (not (idlwave-shell-valid-frame frame))
-       ;; FIXME: errors are dangerous in shell filters.  But I think I
+       ;; fixme: errors are dangerous in shell filters.  but i think i
        ;; have never encountered this one.
        ;; have never encountered this one.
-        (error (concat "Invalid frame - unable to access file: " (car frame)))
+        (error (concat "invalid frame - unable to access file: " (car frame)))
 ;;;
 ;;; buffer : the buffer to display a line in.
 ;;; select-shell: current buffer is the shell.
 ;;;
 ;;; buffer : the buffer to display a line in.
 ;;; select-shell: current buffer is the shell.
@@ -2339,15 +2389,15 @@ debug mode."
              (select-shell (equal (buffer-name) (idlwave-shell-buffer)))
              window pos electric)
 
              (select-shell (equal (buffer-name) (idlwave-shell-buffer)))
              window pos electric)
 
-       ;; First make sure the shell window is visible
+       ;; first make sure the shell window is visible
        (idlwave-display-buffer (idlwave-shell-buffer)
                                nil (idlwave-shell-shell-frame))
 
        (idlwave-display-buffer (idlwave-shell-buffer)
                                nil (idlwave-shell-shell-frame))
 
-       ;; Now display the buffer and remember which window it is.
+       ;; now display the buffer and remember which window it is.
        (setq window (idlwave-display-buffer buffer
                                             nil (idlwave-shell-source-frame)))
 
        (setq window (idlwave-display-buffer buffer
                                             nil (idlwave-shell-source-frame)))
 
-       ;; Enter the buffer and mark the line
+       ;; enter the buffer and mark the line
         (save-excursion
           (set-buffer buffer)
           (save-restriction
         (save-excursion
           (set-buffer buffer)
           (save-restriction
@@ -2358,45 +2408,53 @@ debug mode."
            (setq idlwave-shell-is-stopped t)
            
             (if idlwave-shell-stop-line-overlay
            (setq idlwave-shell-is-stopped t)
            
             (if idlwave-shell-stop-line-overlay
-                ;; Move overlay
-               (move-overlay idlwave-shell-stop-line-overlay
-                             (point) (save-excursion (end-of-line) (point))
-                             (current-buffer))
-             ;; Use the arrow instead, but only if marking is wanted.
+                (progn
+                 ;; restore face and move overlay 
+                 (overlay-put idlwave-shell-stop-line-overlay 'face
+                              (if idlwave-shell-electric-debug-mode
+                                   idlwave-shell-electric-stop-line-face 
+                                 idlwave-shell-stop-line-face))
+                 (move-overlay idlwave-shell-stop-line-overlay
+                               (point) (save-excursion (end-of-line) (point))
+                               (current-buffer)))
+             ;; use the arrow instead, but only if marking is wanted.
              (if idlwave-shell-mark-stop-line
                  (setq overlay-arrow-string idlwave-shell-overlay-arrow))
               (or overlay-arrow-position  ; create the marker if necessary
                   (setq overlay-arrow-position (make-marker)))
              (set-marker overlay-arrow-position (point) buffer)))
 
              (if idlwave-shell-mark-stop-line
                  (setq overlay-arrow-string idlwave-shell-overlay-arrow))
               (or overlay-arrow-position  ; create the marker if necessary
                   (setq overlay-arrow-position (make-marker)))
              (set-marker overlay-arrow-position (point) buffer)))
 
-         ;; If the point is outside the restriction, widen the buffer.
+         ;; if the point is outside the restriction, widen the buffer.
           (if (or (< pos (point-min)) (> pos (point-max)))
              (progn
                (widen)
                (goto-char pos)))
 
           (if (or (< pos (point-min)) (> pos (point-max)))
              (progn
                (widen)
                (goto-char pos)))
 
-         ;; If we have the column of the error, move the cursor there.
+         ;; if we have the column of the error, move the cursor there.
           (if col (move-to-column col))
           (setq pos (point))
          
           (if col (move-to-column col))
           (setq pos (point))
          
-         ;; Enter electric debug mode, if not prohibited and not in
+         ;; enter electric debug mode, if not prohibited and not in
          ;; it already
          ;; it already
-         (when (and (or 
-                     (eq idlwave-shell-automatic-electric-debug t)
-                     (and 
-                      (eq idlwave-shell-automatic-electric-debug 'breakpoint)
-                      (not (eq idlwave-shell-current-state 'error))))
-                    (not no-debug)
-                    (not idlwave-shell-suppress-electric-debug)
-                    (not idlwave-shell-electric-debug-mode))
-           (idlwave-shell-electric-debug-mode)
-           (setq electric t)))
+         (when  (and (not idlwave-shell-electric-debug-mode)
+                     (or (eq debug 'force)
+                         (and 
+                          (not (eq debug 'disable)) ;; explicitly disabled
+                          (or 
+                           (eq idlwave-shell-automatic-electric-debug t)
+                           (and 
+                            (eq idlwave-shell-automatic-electric-debug 
+                                'breakpoint)
+                            (not (eq idlwave-shell-current-state 'error))))
+                          (not idlwave-shell-suppress-electric-debug))))
+           (idlwave-shell-electric-debug-mode t))
+         (setq electric idlwave-shell-electric-debug-mode))
        
        ;; Make sure pos is really displayed in the window.
        (set-window-point window pos)
        
        ;; If we came from the shell, go back there.  Otherwise select 
        
        ;; Make sure pos is really displayed in the window.
        (set-window-point window pos)
        
        ;; If we came from the shell, go back there.  Otherwise select 
-       ;; the window where the error is displayed.
+       ;; the window where the error/halt is displayed.
         (if (or (and idlwave-shell-electric-zap-to-file electric)
                (and (equal (buffer-name) (idlwave-shell-buffer)) 
                     (not select-shell)))
         (if (or (and idlwave-shell-electric-zap-to-file electric)
                (and (equal (buffer-name) (idlwave-shell-buffer)) 
                     (not select-shell)))
@@ -2408,6 +2466,7 @@ debug mode."
   (interactive "p")
   (or (not arg) (< arg 1)
       (setq arg 1))
   (interactive "p")
   (or (not arg) (< arg 1)
       (setq arg 1))
+  (idlwave-shell-stop-line-pending)
   (idlwave-shell-send-command 
    (concat ".s " (if (integerp arg) (int-to-string arg) arg))
    nil (if (idlwave-shell-hide-p 'debug) 'mostly) nil t))
   (idlwave-shell-send-command 
    (concat ".s " (if (integerp arg) (int-to-string arg) arg))
    nil (if (idlwave-shell-hide-p 'debug) 'mostly) nil t))
@@ -2419,6 +2478,7 @@ Uses IDL's stepover executive command which does not enter called functions."
   (interactive "p")
   (or (not arg) (< arg 1)
       (setq arg 1))
   (interactive "p")
   (or (not arg) (< arg 1)
       (setq arg 1))
+  (idlwave-shell-stop-line-pending)
   (idlwave-shell-send-command 
    (concat ".so " (if (integerp arg) (int-to-string arg) arg))
    nil (if (idlwave-shell-hide-p 'debug) 'mostly) nil t))
   (idlwave-shell-send-command 
    (concat ".so " (if (integerp arg) (int-to-string arg) arg))
    nil (if (idlwave-shell-hide-p 'debug) 'mostly) nil t))
@@ -2462,13 +2522,13 @@ the problem with not being able to set the breakpoint."
               (beep)
               (y-or-n-p 
                (concat "Okay to recompile file "
               (beep)
               (y-or-n-p 
                (concat "Okay to recompile file "
-                       (idlwave-shell-bp-get bp 'file) "? ")))
+                       (idlwave-shell-bp-get bp 'file) "?")))
             ;; Recompile
             (progn
               ;; Clean up before retrying
               (idlwave-shell-command-failure)
               (idlwave-shell-send-command
             ;; Recompile
             (progn
               ;; Clean up before retrying
               (idlwave-shell-command-failure)
               (idlwave-shell-send-command
-               (concat ".run " (idlwave-shell-bp-get bp 'file)) nil 
+               (concat ".run \"" (idlwave-shell-bp-get bp 'file) "\"") nil 
               (if (idlwave-shell-hide-p 'run) 'mostly) nil t)
               ;; Try setting breakpoint again
               (idlwave-shell-set-bp bp))
               (if (idlwave-shell-hide-p 'run) 'mostly) nil t)
               ;; Try setting breakpoint again
               (idlwave-shell-set-bp bp))
@@ -2496,6 +2556,7 @@ breakpoint can not be set."
 (defun idlwave-shell-cont (&optional no-show)
   "Continue executing."
   (interactive)
 (defun idlwave-shell-cont (&optional no-show)
   "Continue executing."
   (interactive)
+  (idlwave-shell-stop-line-pending)
   (idlwave-shell-send-command ".c" (unless no-show 
                                     '(idlwave-shell-redisplay 'hide))
                              (if (idlwave-shell-hide-p 'debug) 'mostly) 
   (idlwave-shell-send-command ".c" (unless no-show 
                                     '(idlwave-shell-redisplay 'hide))
                              (if (idlwave-shell-hide-p 'debug) 'mostly) 
@@ -2504,6 +2565,7 @@ breakpoint can not be set."
 (defun idlwave-shell-go ()
   "Run .GO.  This starts the main program of the last compiled file."
   (interactive)
 (defun idlwave-shell-go ()
   "Run .GO.  This starts the main program of the last compiled file."
   (interactive)
+  (idlwave-shell-stop-line-pending)
   (idlwave-shell-send-command ".go" '(idlwave-shell-redisplay 'hide)
                              (if (idlwave-shell-hide-p 'debug) 'mostly)
                              nil t))
   (idlwave-shell-send-command ".go" '(idlwave-shell-redisplay 'hide)
                              (if (idlwave-shell-hide-p 'debug) 'mostly)
                              nil t))
@@ -2511,6 +2573,7 @@ breakpoint can not be set."
 (defun idlwave-shell-return ()
   "Run .RETURN (continue to next return, but stay in subprogram)."
   (interactive)
 (defun idlwave-shell-return ()
   "Run .RETURN (continue to next return, but stay in subprogram)."
   (interactive)
+  (idlwave-shell-stop-line-pending)
   (idlwave-shell-send-command ".return" '(idlwave-shell-redisplay 'hide)
                              (if (idlwave-shell-hide-p 'debug) 'mostly)
                              nil t))
   (idlwave-shell-send-command ".return" '(idlwave-shell-redisplay 'hide)
                              (if (idlwave-shell-hide-p 'debug) 'mostly)
                              nil t))
@@ -2518,11 +2581,12 @@ breakpoint can not be set."
 (defun idlwave-shell-skip ()
   "Run .SKIP (skip one line, then step)."
   (interactive)
 (defun idlwave-shell-skip ()
   "Run .SKIP (skip one line, then step)."
   (interactive)
+  (idlwave-shell-stop-line-pending)  
   (idlwave-shell-send-command ".skip" '(idlwave-shell-redisplay 'hide)
                              (if (idlwave-shell-hide-p 'debug) 'mostly)
                              nil t))
 
   (idlwave-shell-send-command ".skip" '(idlwave-shell-redisplay 'hide)
                              (if (idlwave-shell-hide-p 'debug) 'mostly)
                              nil t))
 
-(defun idlwave-shell-clear-bp (bp)
+(defun idlwave-shell-clear-bp (bp &optional no-query)
   "Clear breakpoint BP.
 Clears in IDL and in `idlwave-shell-bp-alist'."
   (let ((index (idlwave-shell-bp-get bp)))
   "Clear breakpoint BP.
 Clears in IDL and in `idlwave-shell-bp-alist'."
   (let ((index (idlwave-shell-bp-get bp)))
@@ -2531,7 +2595,7 @@ Clears in IDL and in `idlwave-shell-bp-alist'."
           (idlwave-shell-send-command
            (concat "breakpoint,/clear," (int-to-string index))
           nil (idlwave-shell-hide-p 'breakpoint) nil t)
           (idlwave-shell-send-command
            (concat "breakpoint,/clear," (int-to-string index))
           nil (idlwave-shell-hide-p 'breakpoint) nil t)
-         (idlwave-shell-bp-query)))))
+         (unless no-query (idlwave-shell-bp-query))))))
 
 (defun idlwave-shell-current-frame ()
   "Return a list containing the current file name and line point is in.
 
 (defun idlwave-shell-current-frame ()
   "Return a list containing the current file name and line point is in.
@@ -2558,7 +2622,10 @@ Returns nil if unable to obtain a module name."
       (widen)
       (save-excursion
         (if (idlwave-prev-index-position)
       (widen)
       (save-excursion
         (if (idlwave-prev-index-position)
-            (upcase (idlwave-unit-name)))))))
+           (let* ((module (idlwave-what-module))
+                  (name (idlwave-make-full-name (nth 2 module) (car module)))
+                  (type (nth 1 module)))
+             (list (upcase name) type)))))))
 
 (defun idlwave-shell-clear-current-bp ()
   "Remove breakpoint at current line.
 
 (defun idlwave-shell-clear-current-bp ()
   "Remove breakpoint at current line.
@@ -2571,7 +2638,10 @@ at a breakpoint."
 
 (defun idlwave-shell-toggle-enable-current-bp (&optional bp force
                                                         no-update)
 
 (defun idlwave-shell-toggle-enable-current-bp (&optional bp force
                                                         no-update)
-  "Disable or enable current bp."
+  "Disable or enable current breakpoint or a breakpoint passed in BP.
+If FORCE is 'disable or 'enable, for that condition instead of
+toggling.  If NO-UPDATE is non-nil, don't update the breakpoint
+list after toggling."
   (interactive)
   (let* ((bp (or bp (idlwave-shell-find-current-bp)))
         (disabled (idlwave-shell-bp-get bp 'disabled)))
   (interactive)
   (let* ((bp (or bp (idlwave-shell-find-current-bp)))
         (disabled (idlwave-shell-bp-get bp 'disabled)))
@@ -2603,6 +2673,7 @@ If ENABLE is non-nil, enable them instead."
 (defun idlwave-shell-to-here ()
   "Set a breakpoint with count 1 then continue."
   (interactive)
 (defun idlwave-shell-to-here ()
   "Set a breakpoint with count 1 then continue."
   (interactive)
+  ;; temporarily disable all other breakpoints
   (let ((disabled (idlwave-shell-enable-all-bp 'disable 'no-update)))
     (idlwave-shell-break-here 1 nil nil nil 'no-show)
     (idlwave-shell-cont 'no-show)
   (let ((disabled (idlwave-shell-enable-all-bp 'disable 'no-update)))
     (idlwave-shell-break-here 1 nil nil nil 'no-show)
     (idlwave-shell-cont 'no-show)
@@ -2621,23 +2692,30 @@ The command looks for an identifier near point and sets a breakpoint
 for the first line of the corresponding module.  If MODULE is `t', set
 in the current routine."
   (interactive)
 for the first line of the corresponding module.  If MODULE is `t', set
 in the current routine."
   (interactive)
-  (let ((module (idlwave-fix-module-if-obj_new (idlwave-what-module))))
+  (let* ((module (idlwave-fix-module-if-obj_new (idlwave-what-module)))
+        (type (nth 1 module))
+        (name (car module))
+        (class (nth 2 module)))
     (if module
        (progn 
     (if module
        (progn 
-         (setq module (idlwave-make-full-name (nth 2 module) (car module)))
-         (idlwave-shell-module-source-query module)
-         (idlwave-shell-set-bp-in-module module))
+         (setq module (idlwave-make-full-name class name))
+         (idlwave-shell-module-source-query module type)
+         (idlwave-shell-set-bp-in-module name type class))
       (error "No identifier at point"))))
 
 
       (error "No identifier at point"))))
 
 
-(defun idlwave-shell-set-bp-in-module (module)
+(defun idlwave-shell-set-bp-in-module (name type class)
   "Set breakpoint in module.  Assumes that `idlwave-shell-sources-alist'
 contains an entry for that module."
   "Set breakpoint in module.  Assumes that `idlwave-shell-sources-alist'
 contains an entry for that module."
-  (let ((source-file (car-safe 
-                     (cdr-safe
-                      (assoc (upcase module)
-                             idlwave-shell-sources-alist))))
-       buf)
+  (let* ((module (idlwave-make-full-name class name))
+        (source-file 
+         (car-safe (cdr-safe
+                    (or
+                     (assoc (upcase module)
+                            idlwave-shell-sources-alist)
+                     (nth 3 (idlwave-best-rinfo-assoc name type class 
+                                                      (idlwave-routines)))))))
+        buf)
     (if (or (not source-file)
            (not (file-regular-p source-file))
            (not (setq buf
     (if (or (not source-file)
            (not (file-regular-p source-file))
            (not (setq buf
@@ -2739,13 +2817,18 @@ Runs to the last statement and then steps 1 statement.  Use the .out command."
   `(lambda (event)
      "Expansion function for expression examination."
      (interactive "e")
   `(lambda (event)
      "Expansion function for expression examination."
      (interactive "e")
-     (let ((transient-mark-mode t)
-          (zmacs-regions t)
-          (tracker (if (featurep 'xemacs) 
-                       (if (fboundp 'default-mouse-track-event-is-with-button)
-                           'idlwave-xemacs-hack-mouse-track
-                         'mouse-track)
-                     'mouse-drag-region)))
+     (let* ((drag-track (fboundp 'mouse-drag-track))
+           (transient-mark-mode t)
+           (zmacs-regions t)
+           (tracker (if (featurep 'xemacs) 
+                        (if (fboundp 
+                             'default-mouse-track-event-is-with-button)
+                            'idlwave-xemacs-hack-mouse-track
+                          'mouse-track)
+                      ;; Emacs 22 no longer completes the drag with
+                      ;; mouse-drag-region, without an additional
+                      ;; event.  mouse-drag-track does so.
+                      (if drag-track 'mouse-drag-track 'mouse-drag-region))))
        (funcall tracker event)
        (idlwave-shell-print (if (idlwave-region-active-p) '(4) nil)
                            ,help ,ev))))
        (funcall tracker event)
        (idlwave-shell-print (if (idlwave-region-active-p) '(4) nil)
                            ,help ,ev))))
@@ -2756,8 +2839,9 @@ Runs to the last statement and then steps 1 statement.  Use the .out command."
   t)
 
 (defun idlwave-xemacs-hack-mouse-track (event)
   t)
 
 (defun idlwave-xemacs-hack-mouse-track (event)
-  (if (featurep 'xemacs) 
-      (let ((oldfunc (symbol-function 'default-mouse-track-event-is-with-button)))
+  (if (featurep 'xemacs)
+      (let ((oldfunc (symbol-function 
+                     'default-mouse-track-event-is-with-button)))
        (unwind-protect
            (progn
              (fset 'default-mouse-track-event-is-with-button 
        (unwind-protect
            (progn
              (fset 'default-mouse-track-event-is-with-button 
@@ -2822,6 +2906,11 @@ idlw-shell-examine-alist from which to select the help command text.
 If instead COMPLETE-HELP-TYPE is non-nil, choose from
 idlw-shell-examine-alist via mini-buffer shortcut key."
   (interactive "P")
 If instead COMPLETE-HELP-TYPE is non-nil, choose from
 idlw-shell-examine-alist via mini-buffer shortcut key."
   (interactive "P")
+
+  ;; For speed: assume the helper routine hasn't been lost, e.g. with
+  ;; .FULL_RESET_SESSION.  We'll recover if necessary
+  (unless idlwave-idlwave_routine_info-compiled
+    (idlwave-shell-compile-helper-routines))
   (save-excursion
     (let* ((process (get-buffer-process (current-buffer)))
           (process-mark (if process (process-mark process)))
   (save-excursion
     (let* ((process (get-buffer-process (current-buffer)))
           (process-mark (if process (process-mark process)))
@@ -2831,7 +2920,7 @@ idlw-shell-examine-alist via mini-buffer shortcut key."
                (format "  [-%d:%s]" 
                        idlwave-shell-calling-stack-index 
                        idlwave-shell-calling-stack-routine)))
                (format "  [-%d:%s]" 
                        idlwave-shell-calling-stack-index 
                        idlwave-shell-calling-stack-routine)))
-          expr beg end cmd examine-hook)
+          expr beg end cmd)
       (cond
        ((equal arg '(16))
        (setq expr (read-string "Expression: ")))
       (cond
        ((equal arg '(16))
        (setq expr (read-string "Expression: ")))
@@ -2874,10 +2963,6 @@ idlw-shell-examine-alist via mini-buffer shortcut key."
                      (current-buffer))
        (add-hook 'pre-command-hook 
                  'idlwave-shell-delete-expression-overlay))
                      (current-buffer))
        (add-hook 'pre-command-hook 
                  'idlwave-shell-delete-expression-overlay))
-      (setq examine-hook 
-           (if idlwave-shell-separate-examine-output
-               'idlwave-shell-examine-display
-             'idlwave-shell-examine-highlight))
       (add-hook 'pre-command-hook
                'idlwave-shell-delete-output-overlay)
       
       (add-hook 'pre-command-hook
                'idlwave-shell-delete-output-overlay)
       
@@ -2939,7 +3024,7 @@ idlw-shell-examine-alist via mini-buffer shortcut key."
        ;;(idlwave-shell-recenter-shell-window)
        (idlwave-shell-send-command 
         cmd 
        ;;(idlwave-shell-recenter-shell-window)
        (idlwave-shell-send-command 
         cmd 
-        examine-hook 
+        'idlwave-shell-check-compiled-and-display
         (if idlwave-shell-separate-examine-output 'hide))))))
 
 (defvar idlwave-shell-examine-window-alist nil
         (if idlwave-shell-separate-examine-output 'hide))))))
 
 (defvar idlwave-shell-examine-window-alist nil
@@ -2949,6 +3034,15 @@ idlw-shell-examine-alist via mini-buffer shortcut key."
 (define-key idlwave-shell-examine-map "q" 'idlwave-shell-examine-display-quit)
 (define-key idlwave-shell-examine-map "c" 'idlwave-shell-examine-display-clear)
 
 (define-key idlwave-shell-examine-map "q" 'idlwave-shell-examine-display-quit)
 (define-key idlwave-shell-examine-map "c" 'idlwave-shell-examine-display-clear)
 
+
+(defun idlwave-shell-check-compiled-and-display ()
+  "Check examine output for warning about undefined procedure/function."
+  (if (string-match "% Attempt to call undefined" idlwave-shell-command-output)
+      (idlwave-shell-compile-helper-routines))
+  (if idlwave-shell-separate-examine-output
+      (idlwave-shell-examine-display)
+    (idlwave-shell-examine-highlight)))
+
 (defun idlwave-shell-examine-display ()
   "View the examine command output in a separate buffer."
   (let (win cur-beg cur-end)
 (defun idlwave-shell-examine-display ()
   "View the examine command output in a separate buffer."
   (let (win cur-beg cur-end)
@@ -3121,13 +3215,16 @@ HELP can be non-nil for `help,', nil for 'print,' or any string into which
 to insert expression in place of the marker ___, e.g.: print,
 size(___,/DIMENSIONS)"
   (cond
 to insert expression in place of the marker ___, e.g.: print,
 size(___,/DIMENSIONS)"
   (cond
-   ((null help) (concat "print, " expr))
+   ((null help)
+    (concat "idlwave_print_safe, " expr "," 
+           (number-to-string idlwave-shell-max-print-length)))
    ((stringp help) 
     (if (string-match "\\(^\\|[^_]\\)\\(___\\)\\([^_]\\|$\\)" help)
        (concat (substring help 0 (match-beginning 2))
                expr
                (substring help (match-end 2)))))
    ((stringp help) 
     (if (string-match "\\(^\\|[^_]\\)\\(___\\)\\([^_]\\|$\\)" help)
        (concat (substring help 0 (match-beginning 2))
                expr
                (substring help (match-end 2)))))
-   (t (concat "help, " expr))))
+   (t 
+    (concat "help, " expr))))
    
 
 (defun idlwave-shell-examine-highlight ()
    
 
 (defun idlwave-shell-examine-highlight ()
@@ -3221,7 +3318,8 @@ If there is a prefix argument, display IDL process."
                  (idlwave-look-at "\\<end\\>")))
           (insert "\nend\n"))
       (save-buffer 0)))
                  (idlwave-look-at "\\<end\\>")))
           (insert "\nend\n"))
       (save-buffer 0)))
-  (idlwave-shell-send-command (concat ".run " idlwave-shell-temp-pro-file)
+  (idlwave-shell-send-command (concat ".run \"" 
+                                     idlwave-shell-temp-pro-file "\"")
                              nil 
                              (if (idlwave-shell-hide-p 'run) 'mostly)
                              nil t)
                              nil 
                              (if (idlwave-shell-hide-p 'run) 'mostly)
                              nil t)
@@ -3292,12 +3390,12 @@ Queries IDL using the string in `idlwave-shell-bp-query'."
                              'hide))
 
 (defun idlwave-shell-bp-get (bp &optional item)
                              'hide))
 
 (defun idlwave-shell-bp-get (bp &optional item)
-  "Get a value for a breakpoint.  
-BP has the form of elements in idlwave-shell-bp-alist.  Optional
-second arg ITEM is the particular value to retrieve.  ITEM can be
-'file, 'line, 'index, 'module, 'count, 'cmd, 'condition, 'disabled or
-'data.  'data returns a list of 'count, 'cmd and 'condition.  Defaults
-to 'index."
+  "Get a value for a breakpoint.  BP has the form of elements in
+idlwave-shell-bp-alist.  Optional second arg ITEM is the
+particular value to retrieve.  ITEM can be 'file, 'line, 'index,
+'module, 'count, 'cmd, 'condition, 'disabled, 'type, or
+'data.  'data returns a list of 'count, 'cmd and 'condition.
+Defaults to 'index."
   (cond
    ;; Frame
    ((eq item 'line) (nth 1 (car bp)))
   (cond
    ;; Frame
    ((eq item 'line) (nth 1 (car bp)))
@@ -3309,7 +3407,12 @@ to 'index."
    ((eq item 'condition) (nth 2 (cdr (cdr bp))))
    ((eq item 'disabled) (nth 3 (cdr (cdr bp))))
    ;; IDL breakpoint info
    ((eq item 'condition) (nth 2 (cdr (cdr bp))))
    ((eq item 'disabled) (nth 3 (cdr (cdr bp))))
    ;; IDL breakpoint info
-   ((eq item 'module) (nth 1 (car (cdr bp))))
+   ((eq item 'module) 
+    (let ((module (nth 1 (car (cdr bp)))))
+      (if (listp module) (car module) module)))
+   ((eq item 'type)
+    (let ((module (nth 1 (car (cdr bp)))))
+      (if (listp module) (nth 1 module))))
    ;;    index - default
    (t (nth 0 (car (cdr bp))))))
 
    ;;    index - default
    (t (nth 0 (car (cdr bp))))))
 
@@ -3402,7 +3505,9 @@ If BP frame is in `idlwave-shell-bp-alist' updates the breakpoint data."
 and third args, DATA and MODULE, are optional.  Returns a breakpoint
 of the format used in `idlwave-shell-bp-alist'.  Can be used in commands
 attempting match a breakpoint in `idlwave-shell-bp-alist'."
 and third args, DATA and MODULE, are optional.  Returns a breakpoint
 of the format used in `idlwave-shell-bp-alist'.  Can be used in commands
 attempting match a breakpoint in `idlwave-shell-bp-alist'."
-  (cons frame (cons (list nil module) data)))
+  (cons frame ;; (file line)
+       (cons (list nil module) ;; (index_id (module type) | module)
+             data)))           ;; (count command condition disabled)
 
 (defvar idlwave-shell-old-bp nil
   "List of breakpoints previous to setting a new breakpoint.")
 
 (defvar idlwave-shell-old-bp nil
   "List of breakpoints previous to setting a new breakpoint.")
@@ -3438,20 +3543,24 @@ specified.  If NO-SHOW is non-nil, don't do any updating."
    'hide)
 
   ;; Get sources for this routine in the sources list
    'hide)
 
   ;; Get sources for this routine in the sources list
-  (idlwave-shell-module-source-query (idlwave-shell-bp-get bp 'module))
+  (idlwave-shell-module-source-query (idlwave-shell-bp-get bp 'module)
+                                    (idlwave-shell-bp-get bp 'type))
   (let*
   (let*
-      ((arg (idlwave-shell-bp-get bp 'count))
-       (key (cond
-              ((not (and arg (numberp arg))) "")
-              ((= arg 1)
-               ",/once")
-              ((> arg 1)
-               (format ",after=%d" arg))))
+      ((count (idlwave-shell-bp-get bp 'count))
        (condition (idlwave-shell-bp-get bp 'condition))
        (disabled (idlwave-shell-bp-get bp 'disabled))
        (condition (idlwave-shell-bp-get bp 'condition))
        (disabled (idlwave-shell-bp-get bp 'disabled))
-       (key (concat key 
-                   (if condition (concat ",CONDITION=\"" condition "\""))))
-       (key (concat key (if disabled ",/DISABLE")))
+       (key (concat (if (and count (numberp count))
+                       (cond
+                        ((= count 1) ",/once")
+                        ((> count 1) (format ",after=%d" count))))
+                   (if condition (concat ",CONDITION=\"" condition "\""))
+                   ;; IDL can't simultaneously set a condition/count
+                   ;; and disable a breakpoint, but it does keep both
+                   ;; of these when resetting the same BP.  We assume
+                   ;; DISABLE and CONDITION/COUNT are not set
+                   ;; together for a newly created breakpoint.
+                   (if (and disabled (not condition) (not count))
+                           ",/DISABLE")))
        (line (idlwave-shell-bp-get bp 'line)))
     (idlwave-shell-send-command
      (concat "breakpoint,'" 
        (line (idlwave-shell-bp-get bp 'line)))
     (idlwave-shell-send-command
      (concat "breakpoint,'" 
@@ -3613,17 +3722,22 @@ Existing overlays are recycled, in order to minimize consumption."
                (setq old-buffers (delq (current-buffer) old-buffers)))
            (if (fboundp 'set-specifier) ;; XEmacs
                (set-specifier left-margin-width (cons (current-buffer) 2))
                (setq old-buffers (delq (current-buffer) old-buffers)))
            (if (fboundp 'set-specifier) ;; XEmacs
                (set-specifier left-margin-width (cons (current-buffer) 2))
-             (setq left-margin-width 2))
-           (if (setq win (get-buffer-window (current-buffer) t))
-               (set-window-buffer win (current-buffer))))))
+             (if (< left-margin-width 2)
+                 (setq left-margin-width 2)))
+           (let ((window (get-buffer-window (current-buffer) 0)))
+             (if window
+                 (set-window-margins 
+                  window left-margin-width right-margin-width))))))
       (if use-glyph
          (while (setq buf (pop old-buffers))
            (with-current-buffer buf
              (if (fboundp 'set-specifier) ;; XEmacs
                  (set-specifier left-margin-width (cons (current-buffer) 0))
                (setq left-margin-width 0))
       (if use-glyph
          (while (setq buf (pop old-buffers))
            (with-current-buffer buf
              (if (fboundp 'set-specifier) ;; XEmacs
                  (set-specifier left-margin-width (cons (current-buffer) 0))
                (setq left-margin-width 0))
-             (if (setq win (get-buffer-window buf t))
-                 (set-window-buffer win buf))))))))
+             (let ((window (get-buffer-window buf 0)))
+               (if window
+                   (set-window-margins 
+                    window left-margin-width right-margin-width)))))))))
 
 (defun idlwave-shell-make-new-bp-overlay (&optional type disabled)
   "Make a new overlay for highlighting breakpoints.  
 
 (defun idlwave-shell-make-new-bp-overlay (&optional type disabled)
   "Make a new overlay for highlighting breakpoints.  
@@ -3822,8 +3936,11 @@ handled by this command."
                       ((eq action 'compile) ".compile ")
                       ((eq action 'batch)   "@")
                       (t (error "Unknown action %s" action)))
                       ((eq action 'compile) ".compile ")
                       ((eq action 'batch)   "@")
                       (t (error "Unknown action %s" action)))
-                idlwave-shell-last-save-and-action-file)
-        'idlwave-shell-maybe-update-routine-info
+                "\""
+                idlwave-shell-last-save-and-action-file
+                "\"")
+        `(idlwave-shell-maybe-update-routine-info nil
+          ,idlwave-shell-last-save-and-action-file)
         (if (idlwave-shell-hide-p 'run) 'mostly) nil t)
        (idlwave-shell-bp-query))
     (let ((msg (format "No such file %s" 
         (if (idlwave-shell-hide-p 'run) 'mostly) nil t)
        (idlwave-shell-bp-query))
     (let ((msg (format "No such file %s" 
@@ -3831,14 +3948,14 @@ handled by this command."
       (setq idlwave-shell-last-save-and-action-file nil)
       (error msg))))
 
       (setq idlwave-shell-last-save-and-action-file nil)
       (error msg))))
 
-(defun idlwave-shell-maybe-update-routine-info (&optional wait)
+(defun idlwave-shell-maybe-update-routine-info (&optional wait file)
   "Update the routine info if the shell is not stopped at an error."
   (if (and (not idlwave-shell-is-stopped)
           (or (eq t idlwave-auto-routine-info-updates)
               (memq 'compile-buffer idlwave-auto-routine-info-updates))
           idlwave-query-shell-for-routine-info
           idlwave-routines)
   "Update the routine info if the shell is not stopped at an error."
   (if (and (not idlwave-shell-is-stopped)
           (or (eq t idlwave-auto-routine-info-updates)
               (memq 'compile-buffer idlwave-auto-routine-info-updates))
           idlwave-query-shell-for-routine-info
           idlwave-routines)
-      (idlwave-shell-update-routine-info t nil wait)))
+      (idlwave-shell-update-routine-info t nil wait file)))
 
 (defvar idlwave-shell-sources-query "help,/source,/full"
   "IDL command to obtain source files for compiled procedures.")
 
 (defvar idlwave-shell-sources-query "help,/source,/full"
   "IDL command to obtain source files for compiled procedures.")
@@ -3849,30 +3966,31 @@ Elements of the alist have the form:
 
   (module name . (source-file-truename idlwave-internal-filename)).")
 
 
   (module name . (source-file-truename idlwave-internal-filename)).")
 
-(defun idlwave-shell-module-source-query (module)
-  "Determine the source file for a given module."
+(defun idlwave-shell-module-source-query (module &optional type)
+  "Determine the source file for a given module.
+Query as a function if TYPE set to something beside 'pro."
   (if module
       (idlwave-shell-send-command 
   (if module
       (idlwave-shell-send-command 
-       (format "print,(routine_info('%s',/SOURCE)).PATH" module)
+       (format "print,(routine_info('%s',/SOURCE%s)).PATH" module
+              (if (eq type 'pro) "" ",/FUNCTIONS"))
        `(idlwave-shell-module-source-filter ,module)
        `(idlwave-shell-module-source-filter ,module)
-       'hide)))
+       'hide 'wait)))
 
 (defun idlwave-shell-module-source-filter (module)
   "Get module source, and update idlwave-shell-sources-alist."
   (let ((old (assoc (upcase module) idlwave-shell-sources-alist))
        filename)
 
 (defun idlwave-shell-module-source-filter (module)
   "Get module source, and update idlwave-shell-sources-alist."
   (let ((old (assoc (upcase module) idlwave-shell-sources-alist))
        filename)
-    (if (string-match "\.PATH *[\n\r]\\([^\r\n]+\\)[\n\r]"
-                     idlwave-shell-command-output)
-       (setq filename (substring idlwave-shell-command-output 
-                                 (match-beginning 1) (match-end 1)))
-      (error "No file matching module found."))
-    (if old
-       (setcdr old (list (idlwave-shell-file-name filename) filename))
-      (setq idlwave-shell-sources-alist
-           (append idlwave-shell-sources-alist 
-                   (list (cons (upcase module)
-                               (list (idlwave-shell-file-name filename) 
-                                     filename))))))))
+    (when (string-match "\.PATH *[\n\r]\\([^%][^\r\n]+\\)[\n\r]"
+                       idlwave-shell-command-output)
+      (setq filename (substring idlwave-shell-command-output 
+                               (match-beginning 1) (match-end 1)))
+      (if old
+         (setcdr old (list (idlwave-shell-file-name filename) filename))
+       (setq idlwave-shell-sources-alist
+             (append idlwave-shell-sources-alist 
+                     (list (cons (upcase module)
+                                 (list (idlwave-shell-file-name filename) 
+                                       filename)))))))))
   
 (defun idlwave-shell-sources-query ()
   "Determine source files for all IDL compiled procedures.
   
 (defun idlwave-shell-sources-query ()
   "Determine source files for all IDL compiled procedures.
@@ -3942,7 +4060,9 @@ list elements of the form:
    idlwave-shell-bp-query
    '(progn
       (idlwave-shell-filter-bp)
    idlwave-shell-bp-query
    '(progn
       (idlwave-shell-filter-bp)
-      (mapcar 'idlwave-shell-clear-bp idlwave-shell-bp-alist))
+      (mapcar (lambda (x) (idlwave-shell-clear-bp x 'no-query))
+             idlwave-shell-bp-alist)
+      (idlwave-shell-bp-query))
    'hide))
 
 (defun idlwave-shell-list-all-bp ()
    'hide))
 
 (defun idlwave-shell-list-all-bp ()
@@ -3983,7 +4103,7 @@ list elements of the form:
       (setq idlwave-shell-error-last (point)))
     (if frame
         (progn
       (setq idlwave-shell-error-last (point)))
     (if frame
         (progn
-          (idlwave-shell-display-line frame col 'no-debug))
+          (idlwave-shell-display-line frame col 'disable))
       (beep)
       (message "No more errors."))))
 
       (beep)
       (message "No more errors."))))
 
@@ -4014,13 +4134,16 @@ Otherwise, just expand the file name."
 
 ;(define-key idlwave-shell-mode-map "\M-?" 'comint-dynamic-list-completions)
 ;(define-key idlwave-shell-mode-map "\t" 'comint-dynamic-complete)
 
 ;(define-key idlwave-shell-mode-map "\M-?" 'comint-dynamic-list-completions)
 ;(define-key idlwave-shell-mode-map "\t" 'comint-dynamic-complete)
+
+(define-key idlwave-shell-mode-map "\C-w"     'comint-kill-region)
 (define-key idlwave-shell-mode-map "\t"       'idlwave-shell-complete)
 (define-key idlwave-shell-mode-map "\M-\t"    'idlwave-shell-complete)
 (define-key idlwave-shell-mode-map "\C-c\C-s" 'idlwave-shell)
 (define-key idlwave-shell-mode-map "\C-c?"    'idlwave-routine-info)
 (define-key idlwave-shell-mode-map "\C-g"     'idlwave-keyboard-quit)
 (define-key idlwave-shell-mode-map "\M-?"     'idlwave-context-help)
 (define-key idlwave-shell-mode-map "\t"       'idlwave-shell-complete)
 (define-key idlwave-shell-mode-map "\M-\t"    'idlwave-shell-complete)
 (define-key idlwave-shell-mode-map "\C-c\C-s" 'idlwave-shell)
 (define-key idlwave-shell-mode-map "\C-c?"    'idlwave-routine-info)
 (define-key idlwave-shell-mode-map "\C-g"     'idlwave-keyboard-quit)
 (define-key idlwave-shell-mode-map "\M-?"     'idlwave-context-help)
-(define-key idlwave-shell-mode-map [(control meta ?\?)] 'idlwave-online-help)
+(define-key idlwave-shell-mode-map [(control meta ?\?)] 
+  'idlwave-help-assistant-help-with-topic)
 (define-key idlwave-shell-mode-map "\C-c\C-i" 'idlwave-update-routine-info)
 (define-key idlwave-shell-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
 (define-key idlwave-shell-mode-map "\C-c\C-x" 'idlwave-shell-send-char)
 (define-key idlwave-shell-mode-map "\C-c\C-i" 'idlwave-update-routine-info)
 (define-key idlwave-shell-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
 (define-key idlwave-shell-mode-map "\C-c\C-x" 'idlwave-shell-send-char)
@@ -4158,6 +4281,8 @@ Otherwise, just expand the file name."
   'idlwave-shell-stack-down)
 (define-key idlwave-shell-electric-debug-mode-map "_" 
   'idlwave-shell-stack-down)
   'idlwave-shell-stack-down)
 (define-key idlwave-shell-electric-debug-mode-map "_" 
   'idlwave-shell-stack-down)
+(define-key idlwave-shell-electric-debug-mode-map "e" 
+  '(lambda () (interactive) (idlwave-shell-print '(16))))
 (define-key idlwave-shell-electric-debug-mode-map "q" 'idlwave-shell-retall)
 (define-key idlwave-shell-electric-debug-mode-map "t" 
   '(lambda () (interactive) (idlwave-shell-send-command "help,/TRACE")))
 (define-key idlwave-shell-electric-debug-mode-map "q" 'idlwave-shell-retall)
 (define-key idlwave-shell-electric-debug-mode-map "t" 
   '(lambda () (interactive) (idlwave-shell-send-command "help,/TRACE")))
@@ -4181,9 +4306,11 @@ Otherwise, just expand the file name."
   ;; session until we return or hit $MAIN$.  Cancel this suppression
   ;; if it's explicitly turned on.
   (if idlwave-shell-electric-debug-mode
   ;; session until we return or hit $MAIN$.  Cancel this suppression
   ;; if it's explicitly turned on.
   (if idlwave-shell-electric-debug-mode
-      (setq idlwave-shell-suppress-electric-debug t)
-    (setq idlwave-shell-suppress-electric-debug nil))
-  (idlwave-shell-electric-debug-mode))
+      (progn ;; Turn it off, and make sure it stays off.
+       (setq idlwave-shell-suppress-electric-debug t)
+       (idlwave-shell-electric-debug-mode 0))
+    (setq idlwave-shell-suppress-electric-debug nil)
+    (idlwave-shell-electric-debug-mode t)))
 
 (defvar idlwave-shell-electric-debug-read-only) 
 (defvar idlwave-shell-electric-debug-buffers nil)
 
 (defvar idlwave-shell-electric-debug-read-only) 
 (defvar idlwave-shell-electric-debug-buffers nil)
@@ -4196,9 +4323,9 @@ Null prefix argument turns off the mode.
 
 When Electric Debug mode is enabled, the many debugging commands are
 available as single key sequences."
 
 When Electric Debug mode is enabled, the many debugging commands are
 available as single key sequences."
-  nil
-  " *Debugging*"
-  idlwave-shell-electric-debug-mode-map)
+nil
+" *Debugging*"
+idlwave-shell-electric-debug-mode-map)
 
 (add-hook 
  'idlwave-shell-electric-debug-mode-on-hook
 
 (add-hook 
  'idlwave-shell-electric-debug-mode-on-hook
@@ -4249,7 +4376,7 @@ available as single key sequences."
          (when (and (eq major-mode 'idlwave-mode)
                     buffer-file-name
                     idlwave-shell-electric-debug-mode)
          (when (and (eq major-mode 'idlwave-mode)
                     buffer-file-name
                     idlwave-shell-electric-debug-mode)
-           (idlwave-shell-electric-debug-mode))))))
+           (idlwave-shell-electric-debug-mode 0))))))
   (setq idlwave-shell-electric-debug-buffers nil))
 
 ;; Show the help text
   (setq idlwave-shell-electric-debug-buffers nil))
 
 ;; Show the help text
@@ -4295,7 +4422,7 @@ available as single key sequences."
      ["Edit Default Cmd" idlwave-shell-edit-default-command-line t])
     ("Breakpoints"
      ["Set Breakpoint" idlwave-shell-break-here 
      ["Edit Default Cmd" idlwave-shell-edit-default-command-line t])
     ("Breakpoints"
      ["Set Breakpoint" idlwave-shell-break-here 
-      :keys "C-c C-d C-c" :active (eq major-mode 'idlwave-mode)]
+      :keys "C-c C-d C-b" :active (eq major-mode 'idlwave-mode)]
      ("Set Special Breakpoint"
       ["Set After Count Breakpoint"
        (progn
      ("Set Special Breakpoint"
       ["Set After Count Breakpoint"
        (progn