Mercurial > emacs
diff lisp/progmodes/idlw-shell.el @ 69822:84de63539ab8
Update to IDLWAVE version 6.0; see idlwave.org. Includes code to
obsolete idlw-rinfo.el.
author | J.D. Smith <jdsmith@as.arizona.edu> |
---|---|
date | Thu, 06 Apr 2006 18:47:37 +0000 |
parents | dc49655f57ae |
children | b79a60a5fdeb 81f2d90dee68 65ca8fb66a0d |
line wrap: on
line diff
--- a/lisp/progmodes/idlw-shell.el Thu Apr 06 18:46:56 2006 +0000 +++ b/lisp/progmodes/idlw-shell.el Thu Apr 06 18:47:37 2006 +0000 @@ -1,12 +1,12 @@ ;; 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. +;; Free Software Foundation ;; 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.0_em22 ;; Keywords: processes ;; This file is part of GNU Emacs. @@ -138,6 +138,11 @@ ;; (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 @@ -313,8 +318,15 @@ (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)") @@ -322,6 +334,7 @@ ("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. @@ -437,6 +450,11 @@ :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." @@ -488,11 +506,11 @@ (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 @@ -553,6 +571,7 @@ "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 @@ -652,7 +671,7 @@ "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.") @@ -700,10 +719,21 @@ (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") @@ -823,6 +853,7 @@ ? 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. @@ -998,6 +1029,8 @@ (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) @@ -1040,6 +1073,8 @@ (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? @@ -1061,23 +1096,25 @@ (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)) - (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) @@ -1086,11 +1123,13 @@ (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)))) @@ -1199,12 +1238,14 @@ (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 @@ -1518,10 +1559,10 @@ ;;; 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 @@ -1536,14 +1577,14 @@ (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) - (buffer-substring + (buffer-substring-no-properties (save-excursion (goto-char (process-mark proc)) - (forward-line 0) + (forward-line 0) ; Emacs 21 (beginning-of-line nil) (point)) comint-last-input-end)))) @@ -1570,10 +1611,10 @@ ;; 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)) - ;(message "Calling command function") + ;;(message "Calling command function") (funcall idlwave-shell-post-command-hook)) ;; Reset to default state for next command. @@ -1668,6 +1709,8 @@ 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 @@ -1688,9 +1731,8 @@ 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)) @@ -1723,8 +1765,10 @@ (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 @@ -1763,29 +1807,29 @@ (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))) @@ -1926,14 +1970,17 @@ 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 @@ -1978,9 +2025,6 @@ (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)) @@ -2208,7 +2252,6 @@ (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. @@ -2259,14 +2302,14 @@ (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)) + (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)))))) + (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." @@ -2302,30 +2345,38 @@ "Check that frame is for an existing file." (file-readable-p (car frame))) +(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)))) + (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. - -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." +(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. @@ -2339,15 +2390,15 @@ (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 @@ -2358,45 +2409,53 @@ (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))) @@ -2408,6 +2467,7 @@ (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)) @@ -2419,6 +2479,7 @@ (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)) @@ -2462,13 +2523,13 @@ (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)) @@ -2496,6 +2557,7 @@ (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) @@ -2504,6 +2566,7 @@ (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)) @@ -2511,6 +2574,7 @@ (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)) @@ -2518,6 +2582,7 @@ (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)) @@ -2603,6 +2668,7 @@ (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) @@ -2739,13 +2805,18 @@ `(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)))) @@ -2756,8 +2827,9 @@ 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 @@ -2822,6 +2894,11 @@ 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))) @@ -2831,7 +2908,7 @@ (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: "))) @@ -2874,10 +2951,6 @@ (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) @@ -2939,7 +3012,7 @@ ;;(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 @@ -2949,6 +3022,15 @@ (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) @@ -3121,13 +3203,16 @@ 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 () @@ -3221,7 +3306,8 @@ (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) @@ -3822,8 +3908,11 @@ ((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" @@ -3831,14 +3920,14 @@ (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.") @@ -3983,7 +4072,7 @@ (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.")))) @@ -4158,6 +4247,8 @@ '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"))) @@ -4181,9 +4272,11 @@ ;; 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) @@ -4196,9 +4289,9 @@ 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 @@ -4249,7 +4342,7 @@ (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