;; idlw-shell.el --- run IDL as an inferior process of Emacs.
-;; Copyright (c) 1999,2000,2001,2002,2003,2004 Free Software Foundation
+
+;; 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>
-;; Version: 5.5
+;; 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
-;; 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,
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; 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,
:prefix "idlwave-shell"
:group 'idlwave)
-(defcustom idlwave-shell-prompt-pattern "^ ?IDL> "
+(defcustom idlwave-shell-prompt-pattern "^\r? ?IDL> "
"*Regexp to match IDL prompt at beginning of a line.
-For example, \"^IDL> \" or \"^WAVE> \".
-The \"^\" means beginning of line, and is required.
+For example, \"^\r?IDL> \" or \"^\r?WAVE> \".
+The \"^\r?\" is needed, to indicate the beginning of the line, with
+optional return character (which IDL seems to output randomly).
This variable is used to initialize `comint-prompt-regexp' in the
process buffer.
;; (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
: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."
(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
- '(("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)")
("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.
(defcustom idlwave-shell-comint-settings
'((comint-scroll-to-bottom-on-input . t)
(comint-scroll-to-bottom-on-output . t)
- (comint-scroll-show-maximum-output . nil))
+ (comint-scroll-show-maximum-output . nil)
+ (comint-prompt-read-only . t))
"Alist of special settings for the comint variables in the IDLWAVE Shell.
Each entry is a cons cell with the name of a variable and a value.
(regexp :tag "Char-mode regexp")
(regexp :tag "Line-mode regexp")))
+(defcustom idlwave-shell-breakpoint-popup-menu t
+ "*If non-nil, provide a menu on mouse-3 on breakpoint lines, and
+popup help text on the line."
+ :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
(defcustom idlwave-shell-mark-stop-line t
"*Non-nil means, mark the source code line where IDL is currently stopped.
-Value decides about the method which is used to mark the line. Legal values
+Value decides about the method which is used to mark the line. Valid values
are:
nil Do not mark the line
(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
- (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
(defcustom idlwave-shell-mark-breakpoints t
"*Non-nil means, mark breakpoints in the source files.
-Legal values are:
+Valid values are:
nil Do not mark breakpoints.
'face Highlight line with `idlwave-shell-breakpoint-face'.
'glyph Red dot at the beginning of line. If the display does not
(defvar idlwave-shell-use-breakpoint-glyph t
"Obsolete variable. See `idlwave-shell-mark-breakpoints.")
-(defcustom idlwave-shell-breakpoint-face 'idlwave-shell-bp-face
+(defcustom idlwave-shell-breakpoint-face 'idlwave-shell-bp
"*The face for breakpoint lines in the source code.
Allows you to choose the font, color and other properties for
lines which have a breakpoint. See also `idlwave-shell-mark-breakpoints'."
:group 'idlwave-shell-highlighting-and-faces
:type 'symbol)
-(if idlwave-shell-have-new-custom
- ;; We have the new customize - use it to define a customizable face
- (defface idlwave-shell-bp-face
- '((((class color)) (:foreground "Black" :background "Pink"))
- (t (:underline t)))
- "Face for highlighting lines with breakpoints."
- :group 'idlwave-shell-highlighting-and-faces)
- ;; Just copy the underline face to be on the safe side.
- (copy-face 'underline 'idlwave-shell-bp-face))
+(if (not idlwave-shell-have-new-custom)
+ ;; Just copy the underline face to be on the safe side.
+ (copy-face 'underline 'idlwave-shell-bp)
+ ;; We have the new customize - use it to define a customizable face
+ (defface idlwave-shell-bp
+ '((((class color)) (:foreground "Black" :background "Pink"))
+ (t (:underline t)))
+ "Face for highlighting lines with breakpoints."
+ :group 'idlwave-shell-highlighting-and-faces))
(defcustom idlwave-shell-disabled-breakpoint-face
- 'idlwave-shell-disabled-bp-face
+ 'idlwave-shell-disabled-bp
"*The face for disabled breakpoint lines in the source code.
Allows you to choose the font, color and other properties for
lines which have a breakpoint. See also `idlwave-shell-mark-breakpoints'."
:group 'idlwave-shell-highlighting-and-faces
:type 'symbol)
-(if idlwave-shell-have-new-custom
- ;; We have the new customize - use it to define a customizable face
- (defface idlwave-shell-disabled-bp-face
- '((((class color)) (:foreground "Black" :background "gray"))
- (t (:underline t)))
- "Face for highlighting lines with breakpoints."
- :group 'idlwave-shell-highlighting-and-faces)
- ;; Just copy the underline face to be on the safe side.
- (copy-face 'underline 'idlwave-shell-disabled-bp-face))
+(if (not idlwave-shell-have-new-custom)
+ ;; Just copy the underline face to be on the safe side.
+ (copy-face 'underline 'idlwave-shell-disabled-bp)
+ ;; We have the new customize - use it to define a customizable face
+ (defface idlwave-shell-disabled-bp
+ '((((class color)) (:foreground "Black" :background "gray"))
+ (t (:underline t)))
+ "Face for highlighting lines with breakpoints."
+ :group 'idlwave-shell-highlighting-and-faces))
(defcustom idlwave-shell-expression-face 'secondary-selection
"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.")
(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)
+(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-ready nil
"If non-nil can send next command to IDL process.")
-(defvar idlwave-shell-wait-for-output nil
- "Whether to wait for output to accumulate.")
-
;;; The following are the types of messages we attempt to catch to
;;; resync our idea of where IDL execution currently is.
;;;
? 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.
(set-marker comint-last-input-end (point))
(setq idlwave-idlwave_routine_info-compiled nil)
(setq idlwave-shell-ready nil)
- (setq idlwave-shell-wait-for-output 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)
;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
- ;;(make-local-hook 'kill-buffer-hook)
+ ;; (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)
(setq abbrev-mode t)
;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
- ;;(make-local-hook 'post-command-hook)
+ ;; make-local-hook 'post-command-hook)
(add-hook 'post-command-hook 'idlwave-command-hook nil t)
;; Read the command history?
(set (make-local-variable 'tool-bar-map) nil)
;; Run the hooks.
- (run-hooks 'idlwave-shell-mode-hook)
+ (run-mode-hooks 'idlwave-shell-mode-hook)
(idlwave-shell-send-command idlwave-shell-initial-commands nil 'hide)
;; Turn off IDL's ^d interpreting, and define a system
;; variable which knows the version of IDLWAVE
(idlwave-shell-send-command
- (format "defsysv,'!idlwave_version','%s',1"
- idlwave-mode-version)
+ (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))
- (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)
- (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)
(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 (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))))
(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))))
- ;; 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
\(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
; (progn
; (message "SENDING Pending commands: %s"
; (prin1-to-string idlwave-shell-pending-commands)))
-; (message "SENDING %s|||%s" cmd pcmd))
+; (message "SENDING %s|||%s" cmd pcmd))
(if (and (symbolp idlwave-shell-show-commands)
(eq idlwave-shell-show-commands 'everything))
(setq hide nil))
(set-marker comint-last-input-end (point))
(comint-simple-send proc cmd)
(setq idlwave-shell-ready nil)
- (when (equal preempt 'wait) ; Get all the output at once
- (setq idlwave-shell-wait-for-output t)
- (accept-process-output proc))))
+ (if (equal preempt 'wait) ; Get all the output at once
+ (while (not idlwave-shell-ready)
+ (when (not (accept-process-output proc 6)) ; long wait
+ (setq idlwave-shell-pending-commands nil)
+ (error "Process timed out"))))))
(goto-char save-point))
(set-buffer save-buffer))))
(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)
When the IDL prompt is received executes `idlwave-shell-post-command-hook'
and then calls `idlwave-shell-send-command' for any pending commands."
;; We no longer do the cleanup here - this is done by the process sentinel
- (when (eq (process-status idlwave-shell-process-name) 'run)
- ;; OK, process is still running, so we can use it.
- (let ((data (match-data)) p full-output)
- (unwind-protect
- (progn
- ;; Ring the bell if necessary
- (while (setq p (string-match "\C-G" string))
- (ding)
- (aset string p ?\C-j ))
- (if idlwave-shell-hide-output
- (save-excursion
- (while (setq p (string-match "\C-M" string))
- (aset string p ?\ ))
- (set-buffer
- (get-buffer-create idlwave-shell-hidden-output-buffer))
- (goto-char (point-max))
- (insert string))
- (idlwave-shell-comint-filter proc string))
- ;; Watch for magic - need to accumulate the current line
- ;; since it may not be sent all at once.
- (if (string-match "\n" string)
- (progn
- (if idlwave-shell-use-input-mode-magic
- (idlwave-shell-input-mode-magic
- (concat idlwave-shell-accumulation string)))
- (setq idlwave-shell-accumulation
- (substring string
- (progn (string-match "\\(.*[\n\r]+\\)*"
- string)
- (match-end 0)))))
- (setq idlwave-shell-accumulation
- (concat idlwave-shell-accumulation string)))
+ (if (eq (process-status idlwave-shell-process-name) 'run)
+ ;; OK, process is still running, so we can use it.
+ (let ((data (match-data)) p full-output)
+ (unwind-protect
+ (progn
+ ;; Ring the bell if necessary
+ (while (setq p (string-match "\C-G" string))
+ (ding)
+ (aset string p ?\C-j ))
+ (if idlwave-shell-hide-output
+ (save-excursion
+ (while (setq p (string-match "\C-M" string))
+ (aset string p ?\ ))
+ (set-buffer
+ (get-buffer-create idlwave-shell-hidden-output-buffer))
+ (goto-char (point-max))
+ (insert string))
+ (idlwave-shell-comint-filter proc string))
+ ;; Watch for magic - need to accumulate the current line
+ ;; since it may not be sent all at once.
+ (if (string-match "\n" string)
+ (progn
+ (if idlwave-shell-use-input-mode-magic
+ (idlwave-shell-input-mode-magic
+ (concat idlwave-shell-accumulation string)))
+ (setq idlwave-shell-accumulation
+ (substring string
+ (progn (string-match "\\(.*[\n\r]+\\)*"
+ string)
+ (match-end 0)))))
+ (setq idlwave-shell-accumulation
+ (concat idlwave-shell-accumulation string)))
;;; 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
- (if (setq idlwave-shell-ready
- (string-match idlwave-shell-prompt-pattern
- idlwave-shell-accumulation))
- (progn
- ;; Gather the command output
+ ;; Check for prompt in current accumulating output
+ (when (setq idlwave-shell-ready
+ (string-match idlwave-shell-prompt-pattern
+ idlwave-shell-accumulation))
+ ;; Gather the command output
+ (if idlwave-shell-hide-output
+ (save-excursion
+ (set-buffer idlwave-shell-hidden-output-buffer)
+ (setq full-output (buffer-string))
+ (goto-char (point-max))
+ (re-search-backward idlwave-shell-prompt-pattern nil t)
+ (goto-char (match-end 0))
+ (setq idlwave-shell-command-output
+ (buffer-substring-no-properties
+ (point-min) (point)))
+ (delete-region (point-min) (point)))
+ (setq idlwave-shell-command-output
+ (with-current-buffer (process-buffer proc)
+ (buffer-substring-no-properties
+ (save-excursion
+ (goto-char (process-mark proc))
+ (forward-line 0) ; Emacs 21 (beginning-of-line nil)
+ (point))
+ comint-last-input-end))))
+
+ ;; Scan for state and do post commands - bracket
+ ;; them with idlwave-shell-ready=nil since they may
+ ;; call idlwave-shell-send-command themselves.
+ (let ((idlwave-shell-ready nil))
+ (idlwave-shell-scan-for-state)
+ ;; Show the output in the shell if it contains an error
(if idlwave-shell-hide-output
- (save-excursion
- (set-buffer idlwave-shell-hidden-output-buffer)
- (setq full-output (buffer-string))
- (goto-char (point-max))
- (re-search-backward idlwave-shell-prompt-pattern nil t)
- (goto-char (match-end 0))
- (setq idlwave-shell-command-output
- (buffer-substring (point-min) (point)))
- (delete-region (point-min) (point)))
- (setq idlwave-shell-command-output
- (with-current-buffer (process-buffer proc)
- (buffer-substring
- (save-excursion
- (goto-char (process-mark proc))
- (beginning-of-line nil)
- (point))
- comint-last-input-end))))
-
- ;; Scan for state and do post commands - bracket
- ;; them with idlwave-shell-ready=nil since they may
- ;; call idlwave-shell-send-command themselves.
- (let ((idlwave-shell-ready nil))
- (idlwave-shell-scan-for-state)
- ;; Show the output in the shell if it contains an error
- (if idlwave-shell-hide-output
- (if (and idlwave-shell-show-if-error
- (eq idlwave-shell-current-state 'error))
- (idlwave-shell-comint-filter proc full-output)
- ;; If it's only *mostly* hidden, filter % lines,
- ;; and show anything that remains
- (if (eq idlwave-shell-hide-output 'mostly)
- (let ((filtered
- (idlwave-shell-filter-hidden-output
- full-output)))
- (if filtered
- (idlwave-shell-comint-filter
- proc filtered))))))
+ (if (and idlwave-shell-show-if-error
+ (eq idlwave-shell-current-state 'error))
+ (idlwave-shell-comint-filter proc full-output)
+ ;; If it's only *mostly* hidden, filter % lines,
+ ;; and show anything that remains
+ (if (eq idlwave-shell-hide-output 'mostly)
+ (let ((filtered
+ (idlwave-shell-filter-hidden-output
+ full-output)))
+ (if filtered
+ (idlwave-shell-comint-filter
+ proc filtered))))))
- ;; Call the post-command hook
- (if (listp idlwave-shell-post-command-hook)
- (progn
- ;(message "Calling list")
- ;(prin1 idlwave-shell-post-command-hook)
- (eval idlwave-shell-post-command-hook))
- ;(message "Calling command function")
- (funcall idlwave-shell-post-command-hook))
-
- ;; Reset to default state for next command.
- ;; Also we do not want to find this prompt again.
- (setq idlwave-shell-accumulation nil
- idlwave-shell-command-output nil
- idlwave-shell-post-command-hook nil
- idlwave-shell-hide-output nil
- idlwave-shell-show-if-error nil
- idlwave-shell-wait-for-output nil))
- ;; Done with post command. Do pending command if
- ;; any.
- (idlwave-shell-send-command))
- ;; We didn't get the prompt yet... maybe accept more output
- (when idlwave-shell-wait-for-output
-;;; Test/Debug code
-; (save-excursion (set-buffer
-; (get-buffer-create "*idlwave-shell-output*"))
-; (goto-char (point-max))
-; (insert "\n<=== WAITING ON OUTPUT ==>\n"))
- (accept-process-output proc 1))))
- (store-match-data data)))))
+ ;; Call the post-command hook
+ (if (listp idlwave-shell-post-command-hook)
+ (progn
+ ;;(message "Calling list")
+ ;;(prin1 idlwave-shell-post-command-hook)
+ (eval idlwave-shell-post-command-hook))
+ ;;(message "Calling command function")
+ (funcall idlwave-shell-post-command-hook))
+
+ ;; Reset to default state for next command.
+ ;; Also we do not want to find this prompt again.
+ (setq idlwave-shell-accumulation nil
+ idlwave-shell-command-output nil
+ idlwave-shell-post-command-hook nil
+ idlwave-shell-hide-output nil
+ idlwave-shell-show-if-error nil))
+ ;; Done with post command. Do pending command if
+ ;; any.
+ (idlwave-shell-send-command)))
+ (store-match-data data)))))
(defun idlwave-shell-sentinel (process event)
"The sentinel function for the IDLWAVE shell process."
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
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))
(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
;; Otherwise, no particular state
(t (setq idlwave-shell-current-state nil)))))
+
(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)))
;; If we have a file, return the frame list
(if file
(list (idlwave-shell-file-name file)
- (string-to-int number)
+ (string-to-number number)
procedure)
;; No success finding a file
nil))))
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
(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))
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))))
(when (not (string= expression ""))
(setq idlwave-shell-get-object-class nil)
(idlwave-shell-send-command
- (concat "print,obj_class(" expression ")")
+ (concat "if obj_valid(" expression ") then print,obj_class("
+ expression ")")
'idlwave-shell-parse-object-class
'hide 'wait)
;; If we don't know anything about the class, update shell routines
(defun idlwave-shell-parse-object-class ()
"Parse the output of the obj_class command."
- (let ((match "print,obj_class([^\n\r]+[\n\r ]"))
- (if (and
- (not (string-match (concat match match "\\s-*^[\n\r]+"
- "% Syntax error")
- idlwave-shell-command-output))
- (string-match (concat match "\\([A-Za-z_0-9]+\\)")
- idlwave-shell-command-output))
+ (let ((match "obj_class([^\n\r]+[\n\r ]"))
+ (if (string-match (concat match "\\([A-Za-z_0-9]+\\) *[\n\r]\\("
+ idlwave-shell-prompt-pattern "\\)")
+ idlwave-shell-command-output)
(setq idlwave-shell-get-object-class
(match-string 1 idlwave-shell-command-output)))))
(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
- (unless idlwave-shell-electric-debug-mode 'no-debug))
- (message (or message
- (format "In routine %s (stack level %d)"
- idlwave-shell-calling-stack-routine
- (- idlwave-shell-calling-stack-index))))))
+ (if idlwave-shell-electric-debug-mode 'force))
+ (message "%s" (or message
+ (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."
"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)
- ;; 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))
- ;; 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))
- ;; 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.
- (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.
(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))
- ;; 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)))
- ;; Enter the buffer and mark the line
+ ;; enter the buffer and mark the line
(save-excursion
(set-buffer buffer)
(save-restriction
(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 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 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))
- ;; Enter electric debug mode, if not prohibited and not in
+ ;; enter electric debug mode, if not prohibited and not in
;; 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
- ;; 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)))
(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))
(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))
-(defun idlwave-shell-break-here (&optional count cmd condition no-show)
+(defun idlwave-shell-break-here (&optional count cmd condition disabled
+ no-show)
"Set breakpoint at current line.
If Count is nil then an ordinary breakpoint is set. We treat a count
than 1 use the IDL AFTER=count keyword to break only after reaching
the statement count times.
-Optional argument CMD is a list or function to evaluate upon reaching
-the breakpoint."
-
+Optional argument CMD is a list or function to evaluate upon reaching
+the breakpoint. CONDITION is a break condition, and DISABLED, if
+non-nil disables the breakpoint"
(interactive "P")
(when (listp count)
(if (equal (car count) 4)
(idlwave-shell-set-bp
;; Create breakpoint
(idlwave-shell-bp (idlwave-shell-current-frame)
- (list count cmd condition nil)
+ (list count cmd condition disabled)
(idlwave-shell-current-module))
no-show))
Offers to recompile the procedure if we failed. This usually fixes
the problem with not being able to set the breakpoint."
;; Scan for message
- (if (and idlwave-shell-command-output
- (string-match "% BREAKPOINT: *Unable to find code"
- idlwave-shell-command-output))
- ;; Offer to recompile
- (progn
+ (if idlwave-shell-command-output
+ (cond
+ ((string-match "% BREAKPOINT: *Unable to find code"
+ idlwave-shell-command-output)
+ ;; Offer to recompile
(if (progn
(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
- (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))
(beep)
(message "Unable to set breakpoint.")
- (idlwave-shell-command-failure)
- )
- ;; return non-nil if no error found
- nil)
- 'okay))
+ (idlwave-shell-command-failure))
+ nil)
+
+ ((string-match "% Syntax error" idlwave-shell-command-output)
+ (message "Syntax error in condition.")
+ (idlwave-shell-command-failure)
+ nil)
+
+ (t 'okay))))
(defun idlwave-shell-command-failure ()
"Do any necessary clean up when an IDL command fails.
(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)
(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))
(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))
(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))
-(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)))
(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.
(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-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)))
(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 'no-show)
+ (idlwave-shell-break-here 1 nil nil nil 'no-show)
(idlwave-shell-cont 'no-show)
(idlwave-shell-enable-all-bp 'enable 'no-update disabled))
(idlwave-shell-redisplay)) ; sync up everything at the end
for the first line of the corresponding module. If MODULE is `t', set
in the current routine."
(interactive)
- (let (module)
- (save-excursion
- (skip-chars-backward "a-zA-Z0-9_$")
- (if (looking-at idlwave-identifier)
- (setq module (match-string 0))
- (error "No identifier at point")))
- (idlwave-shell-send-command
- idlwave-shell-sources-query
- `(progn
- (idlwave-shell-sources-filter)
- (idlwave-shell-set-bp-in-module ,module))
- 'hide)))
-
-(defun idlwave-shell-set-bp-in-module (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
+ (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"))))
+
+
+(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."
- (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
(funcall orig-func cur-line orig-bp-line)
(or (not bp-line) (funcall closer-func cur-line bp-line)))
(setq bp-line cur-line))))
- (unless bp-line (error "No further breakpoints."))
+ (unless bp-line (error "No further breakpoints"))
(goto-line bp-line)))
;; Examine Commands ------------------------------------------------------
`(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))))
t)
(defun idlwave-xemacs-hack-mouse-track (event)
- (let ((oldfunc (symbol-function 'default-mouse-track-event-is-with-button)))
- (unwind-protect
- (progn
- (fset 'default-mouse-track-event-is-with-button
- 'idlwave-default-mouse-track-event-is-with-button)
- (mouse-track event))
- (fset 'default-mouse-track-event-is-with-button oldfunc))))
+ (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
+ 'idlwave-default-mouse-track-event-is-with-button)
+ (mouse-track event))
+ (fset 'default-mouse-track-event-is-with-button oldfunc)))))
;;; End terrible hack section
(defun idlwave-shell-mouse-print (event)
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)))
(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: ")))
(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)
(while (string-match "\n[ \t]*\\(;.*\\)?\r*\n" expr)
(setq expr (replace-match "\n" t t expr)))
;; Concatenate continuation lines
- (while (string-match "[ \t]*\\$.*\\(;.*\\)?\\(\n[ \t]*\\|$\\)" expr)
+ (while (string-match "[ \t]*\\$[ \t]*\\(;.*\\)?\\(\n[ \t]*\\|$\\)" expr)
(setq expr (replace-match "" t t expr)))
;; Remove final newline
(if (string-match "\n[ \t\r]*\\'" expr)
;;(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
(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)
versions of IDL."
(let ((fetch (- 0 level))
(start 0)
- var rnvar pre post)
+ var fetch-start fetch-end pre post)
;; FIXME: In the following we try to find the variables in expression
;; This is quite empirical - I don't know in what situations this will
(while (string-match
"\\(\\`\\|[^a-zA-Z0-9$_][ \t]*\\)\\([a-zA-Z][a-zA-Z0-9$_]*\\)\\([ \t]*[^a-zA-Z0-9$_]\\|\\'\\)" expr start)
(setq var (match-string 2 expr)
- start (match-beginning 2)
+ start (match-end 2)
pre (substring expr 0 (match-beginning 2))
post (substring expr (match-end 2)))
- (cond
- ;; Exclude identifiers which are not variables
- ((string-match ",[ \t]*/\\'" pre)) ;; a `/' KEYWORD
- ((and (string-match "[,(][ \t]*\\'" pre)
- (string-match "\\`[ \t]*=" post))) ;; a `=' KEYWORD
- ((string-match "\\`(" post)) ;; a function
- ((string-match "->[ \t]*\\'" pre)) ;; a method
- ((string-match "\\.\\'" pre)) ;; structure member
+ (cond
+ ((or
+ ;; Exclude identifiers which are not variables
+ (string-match ",[ \t$\n]*/\\'" pre) ;; a `/' KEYWORD
+ (and (string-match "[,(][ \t\n]*\\'" pre)
+ (string-match "\\`[ \t]*=" post)) ;; a `=' KEYWORD
+ (string-match "\\`(" post) ;; a function
+ (string-match "->[ \t]*\\'" pre) ;; a method
+ (string-match "\\.\\'" pre))) ;; structure member
+
+ ;; Skip over strings
((and (string-match "\\([\"\']\\)[^\1]*$" pre)
(string-match (concat "^[^" (match-string 1 pre) "]*"
- (match-string 1 pre)) post)))
- (t ;; seems to be a variable - replace its name in the
- ;; expression with the fetch.
- (setq rnvar (format "(routine_names('%s',fetch=%d))" var fetch)
- expr (concat pre rnvar post)
- start (+ start (length rnvar))))))
+ (match-string 1 pre)) post))
+ (setq start (+ start (match-end 0))))
+
+
+ ;; seems to be a variable - delimit its name
+ (t
+ (put-text-property start (- start (length var)) 'fetch t expr))))
+
+ (setq start 0)
+ (while (setq fetch-start
+ (next-single-property-change start 'fetch expr))
+ (if (get-text-property start 'fetch expr) ; it's on in range
+ (setq fetch-end fetch-start ;it's off in range
+ fetch-start start)
+ (setq fetch-end (next-single-property-change fetch-start 'fetch expr)))
+ (unless fetch-end (setq fetch-end (length expr)))
+ (remove-text-properties fetch-start fetch-end '(fetch) expr)
+ (setq expr (concat (substring expr 0 fetch-start)
+ (format "(routine_names('%s',fetch=%d))"
+ (substring expr fetch-start fetch-end)
+ fetch)
+ (substring expr fetch-end)))
+ (setq start fetch-end))
+ (if (get-text-property 0 'fetch expr) ; Full expression, left over
+ (setq expr (format "(routine_names('%s',fetch=%d))" expr fetch)))
expr))
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)))))
- (t (concat "help, " expr))))
+ (t
+ (concat "help, " expr))))
(defun idlwave-shell-examine-highlight ()
(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)
'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)))
((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))))))
indmap '(1 6 2 16)))) ; index module line file
;; There seems to be a breakpoint listing here, parse breakpoint lines.
(while (re-search-forward bp-re nil t)
- (setq index (string-to-int (match-string (nth 0 indmap)))
+ (setq index (string-to-number (match-string (nth 0 indmap)))
module (match-string (nth 1 indmap))
- line (string-to-int (match-string (nth 2 indmap)))
+ line (string-to-number (match-string (nth 2 indmap)))
file (idlwave-shell-file-name (match-string (nth 3 indmap))))
(if (eq bp-re bp-re55)
(setq count (if (match-string 10) 1
(if (match-string 8)
- (string-to-int (match-string 8))))
+ (string-to-number (match-string 8))))
condition (match-string 13)
disabled (not (null (match-string 15)))))
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.")
((bp-file (idlwave-shell-bp-get bp 'file))
(bp-module (idlwave-shell-bp-get bp 'module))
(internal-file-list
- (cdr (assoc bp-module idlwave-shell-sources-alist))))
+ (if bp-module
+ (cdr (assoc bp-module idlwave-shell-sources-alist)))))
(if (and internal-file-list
(equal bp-file (nth 0 internal-file-list)))
(nth 1 internal-file-list)
(idlwave-shell-filter-bp (quote ,no-show))
(setq idlwave-shell-old-bp idlwave-shell-bp-alist))
'hide)
- ;; Get sources for IDL compiled procedures followed by setting
- ;; breakpoint.
- (idlwave-shell-send-command
- idlwave-shell-sources-query
- `(progn
- (idlwave-shell-sources-filter)
- (idlwave-shell-set-bp2 (quote ,bp) (quote ,no-show)))
- 'hide))
-(defun idlwave-shell-set-bp2 (bp &optional no-show)
- "Use results of breakpoint and sources query to set bp.
-Use the count argument with IDLs breakpoint command.
-We treat a count of 1 as a temporary breakpoint.
-Counts greater than 1 use the IDL AFTER=count keyword to break
-only after reaching the statement count times."
+ ;; Get sources for this routine in the sources list
+ (idlwave-shell-module-source-query (idlwave-shell-bp-get bp 'module)
+ (idlwave-shell-bp-get bp 'type))
(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))
- (key (concat key
- (if condition (concat ",CONDITION=\"" condition "\""))))
+ (disabled (idlwave-shell-bp-get bp 'disabled))
+ (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,'"
(idlwave-shell-sources-bp bp) "',"
(if (integerp line) (setq line (int-to-string line)))
key)
- ;; Check for failure and look for breakpoint in IDL's list
+ ;; Check for failure and adjust breakpoint to match IDL's list
`(progn
(if (idlwave-shell-set-bp-check (quote ,bp))
- (idlwave-shell-set-bp3 (quote ,bp) (quote ,no-show))))
+ (idlwave-shell-set-bp-adjust (quote ,bp) (quote ,no-show))))
;; hide output?
(idlwave-shell-hide-p 'breakpoint)
'preempt t)))
-(defun idlwave-shell-set-bp3 (bp &optional no-show)
+(defun idlwave-shell-set-bp-adjust (bp &optional no-show)
"Find the breakpoint in IDL's internal list of breakpoints."
- (idlwave-shell-send-command idlwave-shell-bp-query
- `(progn
- (idlwave-shell-filter-bp (quote ,no-show))
- (idlwave-shell-new-bp (quote ,bp))
- (unless (quote ,no-show)
- (idlwave-shell-update-bp-overlays)))
- 'hide
- 'preempt))
+ (idlwave-shell-send-command
+ idlwave-shell-bp-query
+ `(progn
+ (idlwave-shell-filter-bp 'no-show)
+ (idlwave-shell-new-bp (quote ,bp))
+ (unless (quote ,no-show)
+ (idlwave-shell-update-bp-overlays)))
+ 'hide
+ 'preempt))
(defun idlwave-shell-find-bp (frame)
"Return breakpoint from `idlwave-shell-bp-alist' for frame.
"Alist of overlays marking breakpoints")
(defvar idlwave-shell-bp-glyph)
+(defvar idlwave-shell-debug-line-map (make-sparse-keymap))
+(define-key idlwave-shell-debug-line-map
+ (if (featurep 'xemacs) [button3] [mouse-3])
+ 'idlwave-shell-mouse-active-bp)
+
(defun idlwave-shell-update-bp-overlays ()
"Update the overlays which mark breakpoints in the source code.
Existing overlays are recycled, in order to minimize consumption."
- ;(message "Updating Overlays")
(when idlwave-shell-mark-breakpoints
(let ((ov-alist (copy-alist idlwave-shell-bp-overlays))
(bp-list idlwave-shell-bp-alist)
(delq nil
(list
(if count
- (concat "n=" (int-to-string count)))
+ (concat "after:" (int-to-string count)))
(if condition
- (concat "condition: " condition))
+ (concat "condition:" condition))
(if disabled "disabled"))))
- (help-text (if help-list
- (mapconcat 'identity help-list ",")))
+ (help-text (concat
+ "BP "
+ (int-to-string (idlwave-shell-bp-get bp))
+ (if help-list
+ (concat
+ " - "
+ (mapconcat 'identity help-list ", ")))
+ (if (and (not count) (not condition))
+ " (use mouse-3 for breakpoint actions)")))
(full-type (if disabled
(intern (concat (symbol-name type)
"-disabled"))
(ov-existing (assq full-type ov-alist))
(ov (or (and (cdr ov-existing)
(pop (cdr ov-existing)))
- (idlwave-shell-make-new-bp-overlay
- type disabled help-text)))
+ (idlwave-shell-make-new-bp-overlay type disabled)))
match)
+ (if idlwave-shell-breakpoint-popup-menu
+ (overlay-put ov 'help-echo help-text))
(move-overlay ov beg end)
(if (setq match (assq full-type idlwave-shell-bp-overlays))
(push ov (cdr match))
(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 (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 help)
+(defun idlwave-shell-make-new-bp-overlay (&optional type disabled)
"Make a new overlay for highlighting breakpoints.
This stuff is strongly dependant upon the version of Emacs. If TYPE
is passed, make an overlay of that type ('bp or 'bp-cond, currently
-only for glyphs). If HELP is set, use it to make a tooltip with that
-text popup."
+only for glyphs)."
(let ((ov (make-overlay 1 1))
(use-glyph (and (memq idlwave-shell-mark-breakpoints '(t glyph))
idlwave-shell-bp-glyph))
(if (featurep 'xemacs)
;; This is XEmacs
(progn
+ (when idlwave-shell-breakpoint-popup-menu
+ (set-extent-property ov 'mouse-face 'highlight)
+ (set-extent-property ov 'keymap idlwave-shell-debug-line-map))
+
(cond
;; tty's cannot display glyphs
((eq (console-type) 'tty)
(t nil))
(set-extent-priority ov -1)) ; make stop line face prevail
;; This is Emacs
+ (when idlwave-shell-breakpoint-popup-menu
+ (overlay-put ov 'mouse-face 'highlight)
+ (overlay-put ov 'keymap idlwave-shell-debug-line-map))
(cond
(window-system
(if use-glyph
(propertize "@"
'display
(list (list 'margin 'left-margin)
- image-props)
- 'mouse-face 'highlight
- 'help-echo help))
+ image-props)))
(overlay-put ov 'before-string string))
;; just the face
(overlay-put ov 'face face)))
(t nil)))
ov))
+(defun idlwave-shell-mouse-active-bp (ev)
+ "Does right-click mouse action on breakpoint lines."
+ (interactive "e")
+ (if ev (mouse-set-point ev))
+ (let ((bp (idlwave-shell-find-bp (idlwave-shell-current-frame)))
+ index condition count select cmd disabled)
+ (unless bp
+ (error "Breakpoint not found"))
+ (setq index (int-to-string (idlwave-shell-bp-get bp))
+ condition (idlwave-shell-bp-get bp 'condition)
+ cmd (idlwave-shell-bp-get bp 'cmd)
+ count (idlwave-shell-bp-get bp 'count)
+ disabled (idlwave-shell-bp-get bp 'disabled))
+ (setq select (idlwave-popup-select
+ ev
+ (delq nil
+ (list (if disabled "Enable" "Disable")
+ "Clear"
+ "Clear All"
+ (if condition "Remove Condition" "Add Condition")
+ (if condition "Change Condition")
+ (if count "Remove Repeat Count"
+ "Add Repeat Count")
+ (if count "Change Repeat Count")))
+ (concat "BreakPoint " index)))
+ (if select
+ (cond
+ ((string-equal select "Clear All")
+ (idlwave-shell-clear-all-bp))
+ ((string-equal select "Clear")
+ (idlwave-shell-clear-current-bp))
+ ((string-match "Condition" select)
+ (idlwave-shell-break-here count cmd
+ (if (or (not condition)
+ (string-match "Change" select))
+ (read-string "Break Condition: "))
+ disabled))
+ ((string-match "Count" select)
+ (idlwave-shell-break-here (if (or (not count)
+ (string-match "Change" select))
+ (string-to-number
+ (read-string "Break After Count: ")))
+ cmd condition disabled))
+ ((string-match "able$" select)
+ (idlwave-shell-toggle-enable-current-bp))
+ (t
+ (message "Unimplemented: %s" select))))))
+
(defun idlwave-shell-edit-default-command-line (arg)
"Edit the current execute command."
(interactive "P")
((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"
(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)
- (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.")
(module name . (source-file-truename idlwave-internal-filename)).")
+(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
+ (format "print,(routine_info('%s',/SOURCE%s)).PATH" module
+ (if (eq type 'pro) "" ",/FUNCTIONS"))
+ `(idlwave-shell-module-source-filter ,module)
+ '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)
+ (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 IDL compiled procedures.
+ "Determine source files for all IDL compiled procedures.
Queries IDL using the string in `idlwave-shell-sources-query'."
-' (interactive)
+ (interactive)
(idlwave-shell-send-command idlwave-shell-sources-query
'idlwave-shell-sources-filter
'hide))
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 ()
(idlwave-shell-file-name
(buffer-substring (match-beginning 1 )
(match-end 1))))
- (string-to-int
+ (string-to-number
(buffer-substring (match-beginning 2)
(match-end 2)))))
;; Try to find the column of the error
(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."))))
;(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 [(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)
'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")))
;; 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-mode) ; defined by easy-mmode
(defvar idlwave-shell-electric-debug-read-only)
(defvar idlwave-shell-electric-debug-buffers nil)
-(easy-mmode-define-minor-mode idlwave-shell-electric-debug-mode
+(define-minor-mode idlwave-shell-electric-debug-mode
"Toggle Electric Debug mode.
With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode.
(force-mode-line-update))
;; Turn it off in all relevant buffers
+(defvar idlwave-shell-electric-debug-buffers nil)
(defun idlwave-shell-electric-debug-all-off ()
(setq idlwave-shell-suppress-electric-debug nil)
(let ((buffers idlwave-shell-electric-debug-buffers)
(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
["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
- (let ((count (string-to-int (read-string "Break after count: "))))
+ (let ((count (string-to-number (read-string "Break after count: "))))
(if (integerp count) (idlwave-shell-break-here count))))
:active (eq major-mode 'idlwave-mode)]
["Set Condition Breakpoint"