2002-07-18 18:58:07 +00:00
|
|
|
|
;; idlw-shell.el --- run IDL as an inferior process of Emacs.
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; Copyright (c) 1999, 2000, 2001,2002 Free Software Foundation
|
2002-07-18 18:58:07 +00:00
|
|
|
|
|
|
|
|
|
;; Author: Carsten Dominik <dominik@astro.uva.nl>
|
|
|
|
|
;; Chris Chase <chase@att.com>
|
|
|
|
|
;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu>
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; Version: 4.15
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; 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)
|
|
|
|
|
;; any later version.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; 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.
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;;
|
|
|
|
|
;; This mode is for IDL version 5 or later. It should work on
|
|
|
|
|
;; Emacs>20.3 or XEmacs>20.4.
|
|
|
|
|
;;
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; 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,
|
|
|
|
|
;; execution until a certain line, printing expressions under point,
|
|
|
|
|
;; visual line pointer for current execution line, etc.
|
|
|
|
|
;;
|
|
|
|
|
;; Documentation should be available online with `M-x idlwave-info'.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;;
|
|
|
|
|
;; New versions of IDLWAVE, documentation, and more information
|
|
|
|
|
;; available from:
|
|
|
|
|
;; http://idlwave.org
|
|
|
|
|
;;
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; INSTALLATION:
|
|
|
|
|
;; =============
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;;
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Follow the instructions in the INSTALL file of the distribution.
|
|
|
|
|
;; In short, put this file on your load path and add the following
|
|
|
|
|
;; lines to your .emacs file:
|
|
|
|
|
;;
|
|
|
|
|
;; (autoload 'idlwave-shell "idlw-shell" "IDLWAVE Shell" t)
|
|
|
|
|
;;
|
|
|
|
|
;;
|
|
|
|
|
;; SOURCE
|
|
|
|
|
;; ======
|
|
|
|
|
;;
|
|
|
|
|
;; The newest version of this file can be found on the maintainers
|
|
|
|
|
;; web site.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;;
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; http://idlwave.org
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;;
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; DOCUMENTATION
|
|
|
|
|
;; =============
|
|
|
|
|
;;
|
|
|
|
|
;; IDLWAVE is documented online in info format.
|
|
|
|
|
;; A printable version of the documentation is available from the
|
|
|
|
|
;; maintainers webpage (see under SOURCE)
|
|
|
|
|
;;
|
|
|
|
|
;;
|
|
|
|
|
;; KNOWN PROBLEMS
|
|
|
|
|
;; ==============
|
|
|
|
|
;;
|
|
|
|
|
;; Under XEmacs the Debug menu in the shell does not display the
|
|
|
|
|
;; keybindings in the prefix map. There bindings are available anyway - so
|
|
|
|
|
;; it is a bug in XEmacs.
|
2000-02-04 10:10:40 +00:00
|
|
|
|
;; The Debug menu in source buffers *does* display the bindings correctly.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;;
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;;
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; CUSTOMIZATION VARIABLES
|
|
|
|
|
;; =======================
|
|
|
|
|
;;
|
|
|
|
|
;; IDLWAVE has customize support - so if you want to learn about
|
|
|
|
|
;; the variables which control the behavior of the mode, use
|
|
|
|
|
;; `M-x idlwave-customize'.
|
|
|
|
|
;;
|
|
|
|
|
;;--------------------------------------------------------------------------
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
|
|
(require 'comint)
|
|
|
|
|
(require 'idlwave)
|
|
|
|
|
|
|
|
|
|
(eval-when-compile (require 'cl))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-have-new-custom nil)
|
|
|
|
|
(eval-and-compile
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Kludge to allow `defcustom' for Emacs 19.
|
|
|
|
|
(condition-case () (require 'custom) (error nil))
|
|
|
|
|
(if (and (featurep 'custom)
|
|
|
|
|
(fboundp 'custom-declare-variable)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(fboundp 'defface))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; We've got what we needed
|
|
|
|
|
(setq idlwave-shell-have-new-custom t)
|
|
|
|
|
;; We have the old or no custom-library, hack around it!
|
|
|
|
|
(defmacro defgroup (&rest args) nil)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(defmacro defcustom (var value doc &rest args)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
`(defvar ,var ,value ,doc))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
;;; Customizations: idlwave-shell group
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; General/Misc. customizations
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defgroup idlwave-shell-general-setup nil
|
2000-12-11 12:45:42 +00:00
|
|
|
|
"General setup of the Shell interaction for IDLWAVE/Shell."
|
|
|
|
|
:prefix "idlwave-shell"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
:group 'idlwave)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-prompt-pattern "^ ?IDL> "
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"*Regexp to match IDL prompt at beginning of a line.
|
|
|
|
|
For example, \"^IDL> \" or \"^WAVE> \".
|
2000-01-03 14:23:13 +00:00
|
|
|
|
The \"^\" means beginning of line.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
This variable is used to initialise `comint-prompt-regexp' in the
|
2000-01-03 14:23:13 +00:00
|
|
|
|
process buffer.
|
|
|
|
|
|
|
|
|
|
This is a fine thing to set in your `.emacs' file."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'regexp)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-process-name "idl"
|
|
|
|
|
"*Name to be associated with the IDL process. The buffer for the
|
|
|
|
|
process output is made by surrounding this name with `*'s."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
2000-12-11 12:45:42 +00:00
|
|
|
|
;; (defcustom idlwave-shell-automatic-start...) See idlwave.el
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(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
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-frame-parameters
|
|
|
|
|
'((height . 30) (unsplittable . nil))
|
|
|
|
|
"The frame parameters for a dedicated idlwave-shell frame.
|
|
|
|
|
See also `idlwave-shell-use-dedicated-frame'.
|
|
|
|
|
The default makes the frame splittable, so that completion works correctly."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type '(repeat
|
|
|
|
|
(cons symbol sexp)))
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defcustom idlwave-shell-raise-frame t
|
|
|
|
|
"*Non-nil means, `idlwave-shell' raises the frame showing the shell window."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(defcustom idlwave-shell-arrows-do-history t
|
|
|
|
|
"*Non-nil means UP and DOWN arrows move through command history.
|
|
|
|
|
This variable can have 3 values:
|
|
|
|
|
nil Arrows just move the cursor
|
|
|
|
|
t Arrows force the cursor back to the current command line and
|
|
|
|
|
walk the history
|
|
|
|
|
'cmdline When the cursor is in the current command line, arrows walk the
|
|
|
|
|
history. Everywhere else in the buffer, arrows move the cursor."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type '(choice
|
|
|
|
|
(const :tag "never" nil)
|
|
|
|
|
(const :tag "everywhere" t)
|
|
|
|
|
(const :tag "in command line only" cmdline)))
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; FIXME: add comint-input-ring-size?
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defcustom idlwave-shell-use-toolbar t
|
2000-12-11 12:45:42 +00:00
|
|
|
|
"*Non-nil means, use the debugging toolbar in all IDL related buffers.
|
2000-02-04 10:10:40 +00:00
|
|
|
|
Starting the shell will then add the toolbar to all idlwave-mode buffers.
|
|
|
|
|
Exiting the shell will removed everywhere.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
Available on XEmacs and on Emacs 21.x or later.
|
2000-02-04 10:10:40 +00:00
|
|
|
|
At any time you can toggle the display of the toolbar with
|
|
|
|
|
`C-c C-d C-t' (`idlwave-shell-toggle-toolbar')."
|
2000-01-03 14:23:13 +00:00
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-temp-pro-prefix "/tmp/idltemp"
|
|
|
|
|
"*The prefix for temporary IDL files used when compiling regions.
|
|
|
|
|
It should be an absolute pathname.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
The full temporary file name is obtained by using `make-temp-file'
|
2000-01-03 14:23:13 +00:00
|
|
|
|
so that the name will be unique among multiple Emacs processes."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-fix-inserted-breaks nil
|
|
|
|
|
"*OBSOLETE VARIABLE, is no longer used.
|
|
|
|
|
|
|
|
|
|
The documentation of this variable used to be:
|
|
|
|
|
If non-nil then run `idlwave-shell-remove-breaks' to clean up IDL messages.")
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-prefix-key "\C-c\C-d"
|
|
|
|
|
"*The prefix key for the debugging map `idlwave-shell-mode-prefix-map'.
|
|
|
|
|
This variable must already be set when idlwave-shell.el is loaded.
|
2000-12-11 12:45:42 +00:00
|
|
|
|
Setting it in the mode-hook is too late."
|
2000-01-03 14:23:13 +00:00
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-activate-prefix-keybindings t
|
|
|
|
|
"Non-nil means, the debug commands will be bound to the prefix key.
|
|
|
|
|
The prefix key itself is given in the option `idlwave-shell-prefix-key'.
|
|
|
|
|
So by default setting a breakpoint will be on C-c C-d C-b."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2000-12-11 12:45:42 +00:00
|
|
|
|
;; (defcustom idlwave-shell-debug-modifiers... See idlwave.el
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-activate-alt-keybindings nil
|
|
|
|
|
"Obsolete variable. See `idlwave-shell-debug-modifiers'.")
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-use-truename nil
|
|
|
|
|
"*Non-nil means, use use `file-truename' when looking for buffers.
|
|
|
|
|
If this variable is non-nil, Emacs will use the function `file-truename' to
|
|
|
|
|
resolve symbolic links in the file paths printed by e.g., STOP commands.
|
|
|
|
|
This means, unvisited files will be loaded under their truename.
|
2000-06-20 12:49:47 +00:00
|
|
|
|
However, when a file is already visited under a different name, IDLWAVE will
|
2000-01-03 14:23:13 +00:00
|
|
|
|
reuse that buffer.
|
|
|
|
|
This option was once introduced in order to avoid multiple buffers visiting
|
|
|
|
|
the same file. However, IDLWAVE no longer makes this mistake, so it is safe
|
|
|
|
|
to set this option to nil."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defcustom idlwave-shell-file-name-chars "~/A-Za-z0-9+:_.$#%={}\\-"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"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."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-mode-hook '()
|
|
|
|
|
"*Hook for customising `idlwave-shell-mode'."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type 'hook)
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defcustom idlwave-shell-graphics-window-size '(500 400)
|
|
|
|
|
"Size of IDL graphics windows popped up by special IDLWAVE command.
|
|
|
|
|
The command is `C-c C-d C-f' and accepts as a prefix the window nr.
|
|
|
|
|
A command like `WINDOW,N,xsize=XX,ysize=YY' is sent to IDL."
|
|
|
|
|
:group 'idlwave-shell-general-setup
|
|
|
|
|
:type '(list
|
|
|
|
|
(integer :tag "x size")
|
|
|
|
|
(integer :tag "y size")))
|
|
|
|
|
|
|
|
|
|
;; Commands Sent to Shell... etc.
|
|
|
|
|
(defgroup idlwave-shell-command-setup nil
|
|
|
|
|
"Setup for command parameters of the Shell interaction for IDLWAVE."
|
|
|
|
|
:prefix "idlwave-shell"
|
|
|
|
|
:group 'idlwave)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-initial-commands "!more=0"
|
|
|
|
|
"Initial commands, separated by newlines, to send to IDL.
|
|
|
|
|
This string is sent to the IDL process by `idlwave-shell-mode' which is
|
|
|
|
|
invoked by `idlwave-shell'."
|
|
|
|
|
:group 'idlwave-shell-command-setup
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-save-command-history t
|
|
|
|
|
"Non-nil means preserve command history between sessions.
|
|
|
|
|
The file `idlwave-shell-command-history-file' is used to save and restore
|
|
|
|
|
the history."
|
|
|
|
|
:group 'idlwave-shell-command-setup
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-command-history-file "~/.idlwhist"
|
|
|
|
|
"The file in which the command history of the idlwave shell is saved.
|
|
|
|
|
In order to change the size of the history, see the variable
|
|
|
|
|
`comint-input-ring-size'.
|
|
|
|
|
The history is only saved if the variable `idlwave-shell-save-command-history'
|
|
|
|
|
is non-nil."
|
|
|
|
|
:group 'idlwave-shell-command-setup
|
|
|
|
|
:type 'file)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defcustom idlwave-shell-show-commands
|
|
|
|
|
'(run misc breakpoint)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"*A list of command types to show output from in the shell.
|
2002-09-12 17:24:53 +00:00
|
|
|
|
Possibilities are 'run, 'debug, 'breakpoint, and 'misc . Unlisted
|
|
|
|
|
types are not displayed in the shell. The single type 'everything
|
|
|
|
|
causes all the copious shell traffic to be displayed."
|
|
|
|
|
:group 'idlwave-shell-command-setup
|
|
|
|
|
:type '(choice
|
|
|
|
|
(const everything)
|
|
|
|
|
(set :tag "Checklist" :greedy t
|
|
|
|
|
(const :tag "All .run and .compile commands" run)
|
|
|
|
|
(const :tag "All breakpoint commands" breakpoint)
|
|
|
|
|
(const :tag "All debug and stepping commands" debug)
|
|
|
|
|
(const :tag "Return, close, etc. commands" misc))))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(defcustom idlwave-shell-examine-alist
|
2002-07-18 18:58:07 +00:00
|
|
|
|
'(("Print" . "print,___")
|
|
|
|
|
("Help" . "help,___")
|
|
|
|
|
("Structure Help" . "help,___,/STRUCTURE")
|
|
|
|
|
("Dimensions" . "print,size(___,/DIMENSIONS)")
|
|
|
|
|
("Type" . "print,size(___,/TNAME)")
|
|
|
|
|
("N_Elements" . "print,n_elements(___)")
|
|
|
|
|
("All Size Info" . "help,(__IWsz__=size(___,/STRUCTURE)),/STRUCTURE & print,__IWsz__.DIMENSIONS")
|
|
|
|
|
("Ptr Valid" . "print,ptr_valid(___)")
|
|
|
|
|
("Widget Valid" . "print,widget_info(___,/VALID)")
|
|
|
|
|
("Widget Geometry" . "help,widget_info(___,/GEOMETRY)"))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"Alist of special examine commands for popup selection.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
The keys are used in the selection popup created by
|
|
|
|
|
`idlwave-shell-examine-select', and the corresponding value is sent as
|
|
|
|
|
a command to the shell, with special sequence `___' replaced by the
|
|
|
|
|
expression being examined."
|
2002-09-12 17:24:53 +00:00
|
|
|
|
:group 'idlwave-shell-command-setup
|
2002-07-18 18:58:07 +00:00
|
|
|
|
:type '(repeat
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(cons
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(string :tag "Label ")
|
|
|
|
|
(string :tag "Command"))))
|
2000-02-04 10:10:40 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defvar idlwave-shell-print-expression-function nil
|
|
|
|
|
"*OBSOLETE VARIABLE, is no longer used.")
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defcustom idlwave-shell-separate-examine-output t
|
|
|
|
|
"*Non-nil mean, put output of examine commands in their own buffer."
|
2002-09-12 17:24:53 +00:00
|
|
|
|
:group 'idlwave-shell-command-setup
|
2002-07-18 18:58:07 +00:00
|
|
|
|
:type 'boolean)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(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))
|
|
|
|
|
|
|
|
|
|
"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.
|
|
|
|
|
The function `idlwave-shell-mode' will make local variables out of each entry.
|
|
|
|
|
Changes to this variable will only be active when the shell buffer is
|
|
|
|
|
newly created."
|
|
|
|
|
:group 'idlwave-shell-command-setup
|
|
|
|
|
:type '(repeat
|
|
|
|
|
(cons variable sexp)))
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-query-for-class t
|
|
|
|
|
"*Non-nil means query the shell for object class on object completions."
|
|
|
|
|
:group 'idlwave-shell-command-setup
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defcustom idlwave-shell-use-input-mode-magic nil
|
|
|
|
|
"*Non-nil means, IDLWAVE should check for input mode spells in output.
|
|
|
|
|
The spells are strings printed by your IDL program and matched
|
|
|
|
|
by the regular expressions in `idlwave-shell-input-mode-spells'.
|
|
|
|
|
When these expressions match, IDLWAVE switches to character input mode and
|
|
|
|
|
back, respectively. See `idlwave-shell-input-mode-spells' for details."
|
2002-09-12 17:24:53 +00:00
|
|
|
|
:group 'idlwave-shell-command-setup
|
2000-06-20 12:49:47 +00:00
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-input-mode-spells
|
|
|
|
|
'("^<onechar>$" "^<chars>$" "^</chars>$")
|
|
|
|
|
"The three regular expressions which match the magic spells for input modes.
|
|
|
|
|
|
|
|
|
|
When the first regexp matches in the output streem of IDL, IDLWAVE
|
|
|
|
|
prompts for a single character and sends it immediately to IDL, similar
|
|
|
|
|
to the command \\[idlwave-shell-send-char].
|
|
|
|
|
|
|
|
|
|
When the second regexp matches, IDLWAVE switches to a blocking
|
|
|
|
|
single-character input mode. This is the same mode which can be entered
|
|
|
|
|
manually with \\[idlwave-shell-char-mode-loop].
|
|
|
|
|
This input mode exits when the third regexp matches in the output,
|
|
|
|
|
or when the IDL prompt is encountered.
|
|
|
|
|
|
|
|
|
|
The variable `idlwave-shell-use-input-mode-magic' must be non-nil to enable
|
|
|
|
|
scanning for these expressions. If the IDL program produces lots of
|
|
|
|
|
output, shell operation may be slowed down.
|
|
|
|
|
|
|
|
|
|
This mechanism is useful for correct interaction with the IDL function
|
|
|
|
|
GET_KBRD, because in normal operation IDLWAVE only sends \\n terminated
|
2000-12-11 12:45:42 +00:00
|
|
|
|
strings. Here is some example code which makes use of the default spells.
|
2000-06-20 12:49:47 +00:00
|
|
|
|
|
|
|
|
|
print,'<chars>' ; Make IDLWAVE switch to character mode
|
|
|
|
|
REPEAT BEGIN
|
|
|
|
|
A = GET_KBRD(1)
|
|
|
|
|
PRINT, BYTE(A)
|
|
|
|
|
ENDREP UNTIL A EQ 'q'
|
|
|
|
|
print,'</chars>' ; Make IDLWAVE switch back to line mode
|
|
|
|
|
|
|
|
|
|
print,'Quit the program, y or n?'
|
|
|
|
|
print,'<onechar>' ; Ask IDLWAVE to send one character
|
|
|
|
|
answer = GET_KBRD(1)
|
|
|
|
|
|
|
|
|
|
Since the IDLWAVE shell defines the system variable `!IDLWAVE_VERSION',
|
2002-10-17 15:41:01 +00:00
|
|
|
|
you could actually check if you are running under Emacs before printing
|
2000-06-20 12:49:47 +00:00
|
|
|
|
the magic strings. Here is a procedure which uses this.
|
|
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
|
======
|
|
|
|
|
idlwave_char_input ; Make IDLWAVE send one character
|
|
|
|
|
idlwave_char_input,/on ; Start the loop to send characters
|
|
|
|
|
idlwave_char_input,/off ; End the loop to send chracters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pro idlwave_char_input,on=on,off=off
|
|
|
|
|
;; Test if we are running under Emacs
|
|
|
|
|
defsysv,'!idlwave_version',exists=running_emacs
|
|
|
|
|
if running_emacs then begin
|
|
|
|
|
if keyword_set(on) then print,'<chars>' $
|
|
|
|
|
else if keyword_set(off) then print,'</chars>' $
|
|
|
|
|
else print,'<onechar>'
|
2002-10-17 15:41:01 +00:00
|
|
|
|
endif
|
2000-06-20 12:49:47 +00:00
|
|
|
|
end"
|
2002-09-12 17:24:53 +00:00
|
|
|
|
:group 'idlwave-shell-command-setup
|
2000-06-20 12:49:47 +00:00
|
|
|
|
:type '(list
|
|
|
|
|
(regexp :tag "One-char regexp")
|
|
|
|
|
(regexp :tag "Char-mode regexp")
|
|
|
|
|
(regexp :tag "Line-mode regexp")))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; Breakpoint Overlays etc
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defgroup idlwave-shell-highlighting-and-faces nil
|
2000-12-11 12:45:42 +00:00
|
|
|
|
"Highlighting and Faces used by the IDLWAVE Shell mode."
|
|
|
|
|
:prefix "idlwave-shell"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
:group 'idlwave)
|
|
|
|
|
|
|
|
|
|
(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
|
|
|
|
|
are:
|
|
|
|
|
|
|
|
|
|
nil Do not mark the line
|
|
|
|
|
'arrow Use the overlay arrow
|
|
|
|
|
'face Use `idlwave-shell-stop-line-face' to highlight the line.
|
2000-12-11 12:45:42 +00:00
|
|
|
|
t Use what IDLWAVE thinks is best. Will be a face where possible,
|
2000-01-03 14:23:13 +00:00
|
|
|
|
otherwise the overlay arrow.
|
|
|
|
|
The overlay-arrow has the disadvantage to hide the first chars of a line.
|
|
|
|
|
Since many people do not have the main block of IDL programs indented,
|
|
|
|
|
a face highlighting may be better.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
In Emacs 21, the overlay arrow is displayed in a special area and never
|
2000-01-03 14:23:13 +00:00
|
|
|
|
hides any code, so setting this to 'arrow on Emacs 21 sounds like a good idea."
|
|
|
|
|
:group 'idlwave-shell-highlighting-and-faces
|
|
|
|
|
:type '(choice
|
|
|
|
|
(const :tag "No marking" nil)
|
|
|
|
|
(const :tag "Use overlay arrow" arrow)
|
|
|
|
|
(const :tag "Highlight with face" face)
|
|
|
|
|
(const :tag "Face or arrow." t)))
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-overlay-arrow ">"
|
|
|
|
|
"*The overlay arrow to display at source lines where execution halts.
|
|
|
|
|
We use a single character by default, since the main block of IDL procedures
|
|
|
|
|
often has no indentation. Where possible, IDLWAVE will use overlays to
|
|
|
|
|
display the stop-lines. The arrow is only used on character-based terminals.
|
|
|
|
|
See also `idlwave-shell-use-overlay-arrow'."
|
|
|
|
|
:group 'idlwave-shell-highlighting-and-faces
|
|
|
|
|
:type 'string)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-stop-line-face 'highlight
|
|
|
|
|
"*The face for `idlwave-shell-stop-line-overlay'.
|
|
|
|
|
Allows you to choose the font, color and other properties for
|
|
|
|
|
line where IDL is stopped. See also `idlwave-shell-mark-stop-line'."
|
|
|
|
|
:group 'idlwave-shell-highlighting-and-faces
|
|
|
|
|
:type 'symbol)
|
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-mark-breakpoints t
|
|
|
|
|
"*Non-nil means, mark breakpoints in the source files.
|
|
|
|
|
Legal 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
|
|
|
|
|
support glyphs, will use 'face instead.
|
|
|
|
|
t Glyph when possible, otherwise face (same effect as 'glyph)."
|
|
|
|
|
:group 'idlwave-shell-highlighting-and-faces
|
|
|
|
|
:type '(choice
|
|
|
|
|
(const :tag "No marking" nil)
|
|
|
|
|
(const :tag "Highlight with face" face)
|
|
|
|
|
(const :tag "Display glyph (red dot)" glyph)
|
|
|
|
|
(const :tag "Glyph or face." t)))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-use-breakpoint-glyph t
|
2002-09-06 07:16:22 +00:00
|
|
|
|
"Obsolete variable. See `idlwave-shell-mark-breakpoints.")
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defcustom idlwave-shell-breakpoint-face 'idlwave-shell-bp-face
|
|
|
|
|
"*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))
|
|
|
|
|
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(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
|
|
|
|
|
the expression printed by IDL."
|
|
|
|
|
:group 'idlwave-shell-highlighting-and-faces
|
|
|
|
|
:type 'symbol)
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defcustom idlwave-shell-output-face 'secondary-selection
|
|
|
|
|
"*The face for `idlwave-shell-output-overlay'.
|
|
|
|
|
Allows you to choose the font, color and other properties for
|
|
|
|
|
the expression output by IDL."
|
|
|
|
|
:group 'idlwave-shell-highlighting-and-faces
|
|
|
|
|
:type 'symbol)
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;;; End user customization variables
|
|
|
|
|
|
|
|
|
|
;;; External variables
|
|
|
|
|
(defvar comint-last-input-start)
|
|
|
|
|
(defvar comint-last-input-end)
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defun idlwave-shell-temp-file (type)
|
|
|
|
|
"Return a temp file, creating it if necessary.
|
|
|
|
|
|
|
|
|
|
TYPE is either 'pro or 'rinfo, and idlwave-shell-temp-pro-file or
|
|
|
|
|
idlwave-shell-temp-rinfo-save-file is set (respectively)."
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(cond
|
2002-07-18 18:58:07 +00:00
|
|
|
|
((eq type 'rinfo)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(or idlwave-shell-temp-rinfo-save-file
|
|
|
|
|
(setq idlwave-shell-temp-rinfo-save-file
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(idlwave-shell-make-temp-file idlwave-shell-temp-pro-prefix))))
|
|
|
|
|
((eq type 'pro)
|
|
|
|
|
(or idlwave-shell-temp-pro-file
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq idlwave-shell-temp-pro-file
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(idlwave-shell-make-temp-file idlwave-shell-temp-pro-prefix))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(t (error "Wrong argument (idlwave-shell-temp-file): %s"
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(symbol-name type)))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defun idlwave-shell-make-temp-file (prefix)
|
|
|
|
|
"Create a temporary file."
|
|
|
|
|
; Hard coded make-temp-file for Emacs<21
|
|
|
|
|
(if (fboundp 'make-temp-file)
|
|
|
|
|
(make-temp-file prefix)
|
|
|
|
|
(let (file
|
|
|
|
|
(temp-file-dir (if (boundp 'temporary-file-directory)
|
|
|
|
|
temporary-file-directory
|
|
|
|
|
"/tmp")))
|
|
|
|
|
(while (condition-case ()
|
|
|
|
|
(progn
|
|
|
|
|
(setq file
|
|
|
|
|
(make-temp-name
|
|
|
|
|
(expand-file-name prefix temp-file-dir)))
|
|
|
|
|
(if (featurep 'xemacs)
|
|
|
|
|
(write-region "" nil file nil 'silent nil)
|
|
|
|
|
(write-region "" nil file nil 'silent nil 'excl))
|
|
|
|
|
nil)
|
|
|
|
|
(file-already-exists t))
|
|
|
|
|
;; the file was somehow created by someone else between
|
|
|
|
|
;; `make-temp-name' and `write-region', let's try again.
|
|
|
|
|
nil)
|
|
|
|
|
file)))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Other variables
|
|
|
|
|
(defvar idlwave-shell-temp-pro-file
|
|
|
|
|
nil
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"Absolute pathname for temporary IDL file for compiling regions")
|
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defvar idlwave-shell-temp-rinfo-save-file
|
2002-07-18 18:58:07 +00:00
|
|
|
|
nil
|
2000-06-20 12:49:47 +00:00
|
|
|
|
"Absolute pathname for temporary IDL file save file for routine_info.
|
|
|
|
|
This is used to speed up the reloading of the routine info procedure
|
|
|
|
|
before use by the shell.")
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defvar idlwave-shell-dirstack-query "cd,current=___cur & print,___cur"
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"Command used by `idlwave-shell-resync-dirs' to query IDL for
|
2000-01-03 14:23:13 +00:00
|
|
|
|
the directory stack.")
|
|
|
|
|
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(defvar idlwave-shell-path-query "__pa=expand_path(!path,/array)&for i=0,n_elements(__pa)-1 do print,'PATH:<'+__pa[i]+'>'&print,'SYSDIR:<'+!dir+'>'"
|
2000-06-20 12:49:47 +00:00
|
|
|
|
"The command which gets !PATH and !DIR infor from the shell.")
|
|
|
|
|
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(defvar idlwave-shell-mode-line-info nil
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"Additional info displayed in the mode line")
|
2000-02-04 10:10:40 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defvar idlwave-shell-default-directory nil
|
|
|
|
|
"The default directory in the idlwave-shell buffer, of outside use.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-last-save-and-action-file nil
|
|
|
|
|
"The last file which was compiled with `idlwave-shell-save-and-...'.")
|
|
|
|
|
|
|
|
|
|
;; Highlighting uses overlays. When necessary, require the emulation.
|
|
|
|
|
(if (not (fboundp 'make-overlay))
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(require 'overlay)
|
|
|
|
|
(error nil)))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-stop-line-overlay nil
|
|
|
|
|
"The overlay for where IDL is currently stopped.")
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defvar idlwave-shell-is-stopped nil)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defvar idlwave-shell-expression-overlay nil
|
|
|
|
|
"The overlay for where IDL is currently stopped.")
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defvar idlwave-shell-output-overlay nil
|
|
|
|
|
"The overlay for the last IDL output.")
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; If these were already overlays, delete them. This probably means that we
|
|
|
|
|
;; are reloading this file.
|
|
|
|
|
(if (overlayp idlwave-shell-stop-line-overlay)
|
|
|
|
|
(delete-overlay idlwave-shell-stop-line-overlay))
|
|
|
|
|
(if (overlayp idlwave-shell-expression-overlay)
|
|
|
|
|
(delete-overlay idlwave-shell-expression-overlay))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if (overlayp idlwave-shell-output-overlay)
|
|
|
|
|
(delete-overlay idlwave-shell-output-overlay))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Set to nil initially
|
|
|
|
|
(setq idlwave-shell-stop-line-overlay nil
|
2002-07-18 18:58:07 +00:00
|
|
|
|
idlwave-shell-expression-overlay nil
|
|
|
|
|
idlwave-shell-output-overlay nil)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
;; Define the shell stop overlay. When left nil, the arrow will be used.
|
|
|
|
|
(cond
|
|
|
|
|
((or (null idlwave-shell-mark-stop-line)
|
|
|
|
|
(eq idlwave-shell-mark-stop-line 'arrow))
|
|
|
|
|
;; Leave the overlay nil
|
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
((eq idlwave-shell-mark-stop-line 'face)
|
|
|
|
|
;; Try to use a face. If not possible, arrow will be used anyway
|
|
|
|
|
;; So who can display faces?
|
|
|
|
|
(when (or (featurep 'xemacs) ; XEmacs can do also ttys
|
|
|
|
|
(fboundp 'tty-defined-colors) ; Emacs 21 as well
|
|
|
|
|
window-system) ; Window systems always
|
|
|
|
|
(progn
|
|
|
|
|
(setq idlwave-shell-stop-line-overlay (make-overlay 1 1))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(overlay-put idlwave-shell-stop-line-overlay
|
2000-01-03 14:23:13 +00:00
|
|
|
|
'face idlwave-shell-stop-line-face))))
|
|
|
|
|
|
|
|
|
|
(t
|
|
|
|
|
;; IDLWAVE may decide. Will use a face on window systems, arrow elsewhere
|
|
|
|
|
(if window-system
|
|
|
|
|
(progn
|
|
|
|
|
(setq idlwave-shell-stop-line-overlay (make-overlay 1 1))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(overlay-put idlwave-shell-stop-line-overlay
|
2000-01-03 14:23:13 +00:00
|
|
|
|
'face idlwave-shell-stop-line-face)))))
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Now the expression and output overlays
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-expression-overlay (make-overlay 1 1))
|
|
|
|
|
(overlay-put idlwave-shell-expression-overlay
|
|
|
|
|
'face idlwave-shell-expression-face)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(setq idlwave-shell-output-overlay (make-overlay 1 1))
|
|
|
|
|
(overlay-put idlwave-shell-output-overlay
|
|
|
|
|
'face idlwave-shell-output-face)
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defvar idlwave-shell-bp-query "help,/breakpoints"
|
|
|
|
|
"Command to obtain list of breakpoints")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-command-output nil
|
|
|
|
|
"String for accumulating current command output.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-post-command-hook nil
|
|
|
|
|
"Lisp list expression or function to run when an IDL command is finished.
|
|
|
|
|
The current command is finished when the IDL prompt is displayed.
|
|
|
|
|
This is evaluated if it is a list or called with funcall.")
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defvar idlwave-shell-sentinel-hook nil
|
|
|
|
|
"Hook run when the idl process exits.")
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defvar idlwave-shell-hide-output nil
|
|
|
|
|
"If non-nil the process output is not inserted into the output
|
|
|
|
|
buffer.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-accumulation nil
|
|
|
|
|
"Accumulate last line of output.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-command-line-to-execute nil)
|
|
|
|
|
(defvar idlwave-shell-cleanup-hook nil
|
|
|
|
|
"List of functions to do cleanup when the shell exits.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-pending-commands nil
|
|
|
|
|
"List of commands to be sent to IDL.
|
|
|
|
|
Each element of the list is list of \(CMD PCMD HIDE\), where CMD is a
|
|
|
|
|
string to be sent to IDL and PCMD is a post-command to be placed on
|
|
|
|
|
`idlwave-shell-post-command-hook'. If HIDE is non-nil, hide the output
|
|
|
|
|
from command CMD. PCMD and HIDE are optional.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-buffer ()
|
|
|
|
|
"Name of buffer associated with IDL process.
|
|
|
|
|
The name of the buffer is made by surrounding `idlwave-shell-process-name
|
|
|
|
|
with `*'s."
|
|
|
|
|
(concat "*" idlwave-shell-process-name "*"))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-ready nil
|
|
|
|
|
"If non-nil can send next command to IDL process.")
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defvar idlwave-shell-wait-for-output nil
|
|
|
|
|
"Whether to wait for output to accumulate.")
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;;; The following are the types of messages we attempt to catch to
|
|
|
|
|
;;; resync our idea of where IDL execution currently is.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;;;
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-halt-frame nil
|
|
|
|
|
"The frame associated with halt/breakpoint messages.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-step-frame nil
|
|
|
|
|
"The frame associated with step messages.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-trace-frame nil
|
|
|
|
|
"The frame associated with trace messages.")
|
|
|
|
|
|
|
|
|
|
(defconst idlwave-shell-halt-messages
|
|
|
|
|
'("^% Execution halted at"
|
|
|
|
|
"^% Interrupted at:"
|
|
|
|
|
"^% Stepped to:"
|
|
|
|
|
"^% At "
|
|
|
|
|
"^% Stop encountered:"
|
|
|
|
|
)
|
|
|
|
|
"*A list of regular expressions matching IDL messages.
|
|
|
|
|
These are the messages containing file and line information where
|
|
|
|
|
IDL is currently stopped.")
|
|
|
|
|
|
|
|
|
|
(defconst idlwave-shell-halt-messages-re
|
|
|
|
|
(mapconcat 'identity idlwave-shell-halt-messages "\\|")
|
|
|
|
|
"The regular expression computed from idlwave-shell-halt-messages")
|
|
|
|
|
|
|
|
|
|
(defconst idlwave-shell-trace-messages
|
|
|
|
|
'("^% At " ;; First line of a trace message
|
|
|
|
|
)
|
|
|
|
|
"*A list of regular expressions matching IDL trace messages.
|
|
|
|
|
These are the messages containing file and line information where
|
|
|
|
|
IDL will begin looking for the next statement to execute.")
|
|
|
|
|
|
|
|
|
|
(defconst idlwave-shell-step-messages
|
|
|
|
|
'("^% Stepped to:"
|
|
|
|
|
)
|
|
|
|
|
"*A list of regular expressions matching stepped execution messages.
|
|
|
|
|
These are IDL messages containing file and line information where
|
|
|
|
|
IDL has currently stepped.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-break-message "^% Breakpoint at:"
|
|
|
|
|
"*Regular expression matching an IDL breakpoint message line.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-bp-alist)
|
|
|
|
|
;(defvar idlwave-shell-post-command-output)
|
|
|
|
|
(defvar idlwave-shell-sources-alist)
|
|
|
|
|
(defvar idlwave-shell-menu-def)
|
|
|
|
|
(defvar idlwave-shell-mode-menu)
|
|
|
|
|
(defvar idlwave-shell-initial-commands)
|
|
|
|
|
(defvar idlwave-shell-syntax-error)
|
|
|
|
|
(defvar idlwave-shell-other-error)
|
|
|
|
|
(defvar idlwave-shell-error-buffer)
|
|
|
|
|
(defvar idlwave-shell-error-last)
|
|
|
|
|
(defvar idlwave-shell-bp-buffer)
|
|
|
|
|
(defvar idlwave-shell-sources-query)
|
|
|
|
|
(defvar idlwave-shell-mode-map)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(defvar idlwave-shell-calling-stack-index)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-mode ()
|
|
|
|
|
"Major mode for interacting with an inferior IDL process.
|
|
|
|
|
|
|
|
|
|
1. Shell Interaction
|
|
|
|
|
-----------------
|
|
|
|
|
RET after the end of the process' output sends the text from the
|
|
|
|
|
end of process to the end of the current line. RET before end of
|
|
|
|
|
process output copies the current line (except for the prompt) to the
|
|
|
|
|
end of the buffer.
|
|
|
|
|
|
|
|
|
|
Command history, searching of previous commands, command line
|
|
|
|
|
editing are available via the comint-mode key bindings, by default
|
2000-12-11 12:45:42 +00:00
|
|
|
|
mostly on the key `C-c'. Command history is also available with
|
|
|
|
|
the arrow keys UP and DOWN.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
2. Completion
|
|
|
|
|
----------
|
2000-06-20 12:49:47 +00:00
|
|
|
|
TAB and M-TAB do completion of IDL routines, classes and keywords -
|
|
|
|
|
similar to M-TAB in `idlwave-mode'. In executive commands and
|
|
|
|
|
strings, it completes file names. Abbreviations are also expanded
|
|
|
|
|
like in `idlwave-mode'.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
3. Routine Info
|
|
|
|
|
------------
|
|
|
|
|
`\\[idlwave-routine-info]' displays information about an IDL routine near point,
|
|
|
|
|
just like in `idlwave-mode'. The module used is the one at point or
|
|
|
|
|
the one whose argument list is being edited.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
To update IDLWAVE's knowledge about compiled or edited modules, use
|
2000-01-03 14:23:13 +00:00
|
|
|
|
\\[idlwave-update-routine-info].
|
|
|
|
|
\\[idlwave-find-module] find the source of a module.
|
|
|
|
|
\\[idlwave-resolve] tells IDL to compile an unresolved module.
|
2000-06-20 12:49:47 +00:00
|
|
|
|
\\[idlwave-context-help] shows the online help on the item at
|
|
|
|
|
point, if online help has been installed.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
4. Debugging
|
|
|
|
|
---------
|
|
|
|
|
A complete set of commands for compiling and debugging IDL programs
|
2002-10-17 15:41:01 +00:00
|
|
|
|
is available from the menu. Also keybindings starting with a
|
2000-01-03 14:23:13 +00:00
|
|
|
|
`C-c C-d' prefix are available for most commands in the *idl* buffer
|
|
|
|
|
and also in source buffers. The best place to learn about the
|
|
|
|
|
keybindings is again the menu.
|
|
|
|
|
|
|
|
|
|
On Emacs versions where this is possible, a debugging toolbar is
|
|
|
|
|
installed.
|
|
|
|
|
|
|
|
|
|
When IDL is halted in the middle of a procedure, the corresponding
|
|
|
|
|
line of that procedure file is displayed with an overlay in another
|
|
|
|
|
window. Breakpoints are also highlighted in the source.
|
|
|
|
|
|
|
|
|
|
\\[idlwave-shell-resync-dirs] queries IDL in order to change Emacs current directory
|
|
|
|
|
to correspond to the IDL process current directory.
|
|
|
|
|
|
|
|
|
|
5. Hooks
|
|
|
|
|
-----
|
|
|
|
|
Turning on `idlwave-shell-mode' runs `comint-mode-hook' and
|
|
|
|
|
`idlwave-shell-mode-hook' (in that order).
|
|
|
|
|
|
|
|
|
|
6. Documentation and Customization
|
|
|
|
|
-------------------------------
|
|
|
|
|
Info documentation for this package is available. Use \\[idlwave-info]
|
|
|
|
|
to display (complain to your sysadmin if that does not work).
|
|
|
|
|
For Postscript and HTML versions of the documentation, check IDLWAVE's
|
2002-07-18 18:58:07 +00:00
|
|
|
|
homepage at `http://idlwave.org'.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
IDLWAVE has customize support - see the group `idlwave'.
|
|
|
|
|
|
|
|
|
|
7. Keybindings
|
|
|
|
|
-----------
|
|
|
|
|
\\{idlwave-shell-mode-map}"
|
|
|
|
|
|
|
|
|
|
(interactive)
|
2000-12-11 12:45:42 +00:00
|
|
|
|
;; We don't do `kill-all-local-variables' here, because this is done by
|
|
|
|
|
;; comint - idlwave-shell-mode only add on top of that.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq comint-prompt-regexp idlwave-shell-prompt-pattern)
|
|
|
|
|
(setq comint-process-echoes t)
|
|
|
|
|
;; Can not use history expansion because "!" is used for system variables.
|
|
|
|
|
(setq comint-input-autoexpand nil)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
; (setq comint-input-ring-size 64)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(make-local-variable 'comint-completion-addsuffix)
|
|
|
|
|
(set (make-local-variable 'completion-ignore-case) t)
|
|
|
|
|
(setq comint-completion-addsuffix '("/" . ""))
|
|
|
|
|
(setq comint-input-ignoredups t)
|
|
|
|
|
(setq major-mode 'idlwave-shell-mode)
|
|
|
|
|
(setq mode-name "IDL-Shell")
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(setq idlwave-shell-mode-line-info nil)
|
|
|
|
|
(setq mode-line-format
|
|
|
|
|
'(""
|
|
|
|
|
mode-line-modified
|
|
|
|
|
mode-line-buffer-identification
|
|
|
|
|
" "
|
|
|
|
|
global-mode-string
|
|
|
|
|
" %[("
|
|
|
|
|
mode-name
|
|
|
|
|
mode-line-process
|
|
|
|
|
minor-mode-alist
|
|
|
|
|
"%n"
|
|
|
|
|
")%]-"
|
|
|
|
|
idlwave-shell-mode-line-info
|
|
|
|
|
"---"
|
|
|
|
|
(line-number-mode "L%l--")
|
|
|
|
|
(column-number-mode "C%c--")
|
|
|
|
|
(-3 . "%p")
|
|
|
|
|
"-%-"))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; (make-local-variable 'idlwave-shell-bp-alist)
|
|
|
|
|
(setq idlwave-shell-halt-frame nil
|
|
|
|
|
idlwave-shell-trace-frame nil
|
|
|
|
|
idlwave-shell-command-output nil
|
|
|
|
|
idlwave-shell-step-frame nil)
|
|
|
|
|
(idlwave-shell-display-line nil)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(setq idlwave-shell-calling-stack-index 0)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(when idlwave-shell-query-for-class
|
|
|
|
|
(add-to-list (make-local-variable 'idlwave-determine-class-special)
|
|
|
|
|
'idlwave-shell-get-object-class)
|
|
|
|
|
(setq idlwave-store-inquired-class t))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Make sure comint-last-input-end does not go to beginning of
|
|
|
|
|
;; buffer (in case there were other processes already in this buffer).
|
|
|
|
|
(set-marker comint-last-input-end (point))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq idlwave-idlwave_routine_info-compiled nil)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-ready nil)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(setq idlwave-shell-wait-for-output nil)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-bp-alist nil)
|
|
|
|
|
(idlwave-shell-update-bp-overlays) ; Throw away old overlays
|
|
|
|
|
(setq idlwave-shell-sources-alist nil)
|
|
|
|
|
(setq idlwave-shell-default-directory default-directory)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq idlwave-shell-hide-output nil)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
|
|
|
|
|
;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
|
|
|
|
|
(make-local-hook 'kill-buffer-hook)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(add-hook 'kill-buffer-hook 'idlwave-shell-kill-shell-buffer-confirm
|
|
|
|
|
nil 'local)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(add-hook 'kill-buffer-hook 'idlwave-shell-delete-temp-files nil 'local)
|
|
|
|
|
(add-hook 'kill-emacs-hook 'idlwave-shell-delete-temp-files)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(use-local-map idlwave-shell-mode-map)
|
|
|
|
|
(easy-menu-add idlwave-shell-mode-menu idlwave-shell-mode-map)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Set the optional comint variables
|
|
|
|
|
(when idlwave-shell-comint-settings
|
|
|
|
|
(let ((list idlwave-shell-comint-settings) entry)
|
|
|
|
|
(while (setq entry (pop list))
|
|
|
|
|
(set (make-local-variable (car entry)) (cdr entry)))))
|
2000-12-11 12:45:42 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; IDLWAVE syntax, and turn on abbreviations
|
|
|
|
|
(setq local-abbrev-table idlwave-mode-abbrev-table)
|
|
|
|
|
(set-syntax-table idlwave-mode-syntax-table)
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(set (make-local-variable 'comment-start) ";")
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq abbrev-mode t)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
|
|
|
|
|
;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
|
|
|
|
|
(make-local-hook 'post-command-hook)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(add-hook 'post-command-hook 'idlwave-command-hook nil t)
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Read the command history?
|
|
|
|
|
(when (and idlwave-shell-save-command-history
|
|
|
|
|
(stringp idlwave-shell-command-history-file))
|
|
|
|
|
(set (make-local-variable 'comint-input-ring-file-name)
|
|
|
|
|
idlwave-shell-command-history-file)
|
|
|
|
|
(if (file-regular-p idlwave-shell-command-history-file)
|
|
|
|
|
(comint-read-input-ring)))
|
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; Run the hooks.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(run-hooks 'idlwave-shell-mode-hook)
|
|
|
|
|
(idlwave-shell-send-command idlwave-shell-initial-commands nil 'hide)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; Define a system variable which knows the version of IDLWAVE
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(format "defsysv,'!idlwave_version','%s',1" idlwave-mode-version)
|
|
|
|
|
nil 'hide)
|
|
|
|
|
(if (and (not idlwave-path-alist)
|
|
|
|
|
(not idlwave-sys-dir))
|
|
|
|
|
(idlwave-shell-send-command idlwave-shell-path-query
|
|
|
|
|
'idlwave-shell-get-path-info
|
|
|
|
|
'hide)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-get-path-info ()
|
|
|
|
|
(let* ((rpl (idlwave-shell-path-filter))
|
|
|
|
|
(sysdir (car rpl))
|
|
|
|
|
(dirs (cdr rpl)))
|
|
|
|
|
(setq idlwave-sys-dir sysdir)
|
|
|
|
|
(setq idlwave-path-alist (mapcar (lambda(x) (cons x nil))
|
|
|
|
|
dirs))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(if (not (fboundp 'idl-shell))
|
|
|
|
|
(fset 'idl-shell 'idlwave-shell))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-idl-wframe nil
|
|
|
|
|
"Frame for displaying the idl shell window.")
|
|
|
|
|
(defvar idlwave-shell-display-wframe nil
|
|
|
|
|
"Frame for displaying the idl source files.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-calling-stack-index 0)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(defvar idlwave-shell-calling-stack-routine nil)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-source-frame ()
|
|
|
|
|
"Return the frame to be used for source display."
|
|
|
|
|
(if idlwave-shell-use-dedicated-frame
|
|
|
|
|
;; We want separate frames for source and shell
|
|
|
|
|
(if (frame-live-p idlwave-shell-display-wframe)
|
|
|
|
|
;; The frame exists, so we use it.
|
|
|
|
|
idlwave-shell-display-wframe
|
|
|
|
|
;; The frame does not exist. We use the current frame.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; However, if the current is the shell frame, we make a new frame,
|
|
|
|
|
;; or recycle the first existing visible frame
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-display-wframe
|
|
|
|
|
(if (eq (selected-frame) idlwave-shell-idl-wframe)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(or
|
|
|
|
|
(let ((flist (visible-frame-list))
|
|
|
|
|
(frame (selected-frame)))
|
|
|
|
|
(catch 'exit
|
|
|
|
|
(while flist
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (not (eq (car flist)
|
|
|
|
|
idlwave-shell-idl-wframe))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(throw 'exit (car flist))
|
|
|
|
|
(setq flist (cdr flist))))))
|
|
|
|
|
(make-frame))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(selected-frame))))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-shell-frame ()
|
|
|
|
|
"Return the frame to be used for the shell buffer."
|
|
|
|
|
(if idlwave-shell-use-dedicated-frame
|
|
|
|
|
;; We want a dedicated frame
|
|
|
|
|
(if (frame-live-p idlwave-shell-idl-wframe)
|
|
|
|
|
;; It does exist, so we use it.
|
|
|
|
|
idlwave-shell-idl-wframe
|
|
|
|
|
;; It does not exist. Check if we have a source frame.
|
|
|
|
|
(if (not (frame-live-p idlwave-shell-display-wframe))
|
|
|
|
|
;; We do not have a source frame, so we use this one.
|
|
|
|
|
(setq idlwave-shell-display-wframe (selected-frame)))
|
|
|
|
|
;; Return a new frame
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq idlwave-shell-idl-wframe
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(make-frame idlwave-shell-frame-parameters)))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;;;###autoload
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defun idlwave-shell (&optional arg quick)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"Run an inferior IDL, with I/O through buffer `(idlwave-shell-buffer)'.
|
|
|
|
|
If buffer exists but shell process is not running, start new IDL.
|
|
|
|
|
If buffer exists and shell process is running, just switch to the buffer.
|
|
|
|
|
|
|
|
|
|
When called with a prefix ARG, or when `idlwave-shell-use-dedicated-frame'
|
|
|
|
|
is non-nil, the shell buffer and the source buffers will be in
|
|
|
|
|
separate frames.
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
The command to run comes from variable `idlwave-shell-explicit-file-name',
|
|
|
|
|
with options taken from `idlwave-shell-command-line-options'.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
The buffer is put in `idlwave-shell-mode', providing commands for sending
|
|
|
|
|
input and controlling the IDL job. See help on `idlwave-shell-mode'.
|
|
|
|
|
See also the variable `idlwave-shell-prompt-pattern'.
|
|
|
|
|
|
|
|
|
|
\(Type \\[describe-mode] in the shell buffer for a list of commands.)"
|
|
|
|
|
(interactive "P")
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if (eq arg 'quick)
|
|
|
|
|
(progn
|
|
|
|
|
(let ((idlwave-shell-use-dedicated-frame nil))
|
|
|
|
|
(idlwave-shell nil)
|
|
|
|
|
(delete-other-windows))
|
|
|
|
|
(and idlwave-shell-use-dedicated-frame
|
|
|
|
|
(setq idlwave-shell-idl-wframe (selected-frame)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(add-hook 'idlwave-shell-sentinel-hook
|
2002-07-18 18:58:07 +00:00
|
|
|
|
'save-buffers-kill-emacs t))
|
|
|
|
|
|
|
|
|
|
;; A non-nil arg means, we want a dedicated frame. This will last
|
|
|
|
|
;; for the current editing session.
|
|
|
|
|
(if arg (setq idlwave-shell-use-dedicated-frame t))
|
|
|
|
|
(if (equal arg '(16)) (setq idlwave-shell-use-dedicated-frame nil))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Check if the process still exists. If not, create it.
|
|
|
|
|
(unless (comint-check-proc (idlwave-shell-buffer))
|
|
|
|
|
(let* ((prg (or idlwave-shell-explicit-file-name "idl"))
|
|
|
|
|
(buf (apply 'make-comint
|
|
|
|
|
idlwave-shell-process-name prg nil
|
|
|
|
|
(if (stringp idlwave-shell-command-line-options)
|
|
|
|
|
(idlwave-split-string
|
|
|
|
|
idlwave-shell-command-line-options)
|
|
|
|
|
idlwave-shell-command-line-options)))
|
|
|
|
|
(process (get-buffer-process buf)))
|
|
|
|
|
(setq idlwave-idlwave_routine_info-compiled nil)
|
|
|
|
|
(set-process-filter process 'idlwave-shell-filter)
|
|
|
|
|
(set-process-sentinel process 'idlwave-shell-sentinel)
|
|
|
|
|
(set-buffer buf)
|
|
|
|
|
(idlwave-shell-mode)))
|
|
|
|
|
(let ((window (idlwave-display-buffer (idlwave-shell-buffer) nil
|
|
|
|
|
(idlwave-shell-shell-frame)))
|
|
|
|
|
(current-window (selected-window)))
|
|
|
|
|
(select-window window)
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(select-window current-window)
|
|
|
|
|
(if idlwave-shell-ready
|
|
|
|
|
(raise-frame (window-frame window)))
|
|
|
|
|
(if (eq (selected-frame) (window-frame window))
|
|
|
|
|
(select-window window))
|
|
|
|
|
)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-recenter-shell-window (&optional arg)
|
|
|
|
|
"Run `idlwave-shell', but make sure the current window stays selected."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((window (selected-window)))
|
|
|
|
|
(idlwave-shell arg)
|
|
|
|
|
(select-window window)))
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defun idlwave-shell-hide-p (type)
|
|
|
|
|
"Whether to hide this type of command.
|
|
|
|
|
Return either nil or 'hide."
|
|
|
|
|
(if (listp idlwave-shell-show-commands)
|
|
|
|
|
(if (not (memq type idlwave-shell-show-commands)) 'hide)))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-send-command (&optional cmd pcmd hide preempt)
|
|
|
|
|
"Send a command to IDL process.
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
\(CMD PCMD HIDE\) are placed at the end of
|
|
|
|
|
` idlwave-shell-pending-commands'. If IDL is ready the first command,
|
|
|
|
|
CMD, in `idlwave-shell-pending-commands' is sent to the IDL process.
|
|
|
|
|
If optional second argument PCMD is non-nil it will be placed on
|
|
|
|
|
`idlwave-shell-post-command-hook' when CMD is executed. If the
|
|
|
|
|
optional third argument HIDE is non-nil, then hide output from CMD.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
If optional fourth argument PREEMPT is non-nil CMD is put at front of
|
2002-09-12 17:24:53 +00:00
|
|
|
|
`idlwave-shell-pending-commands'. If PREEMPT is 'wait, wait for all
|
|
|
|
|
output to complete and the next prompt to arrive before returning
|
|
|
|
|
\(useful if you need an answer now\). IDL is considered ready if the
|
|
|
|
|
prompt is present and if `idlwave-shell-ready' is non-nil."
|
|
|
|
|
|
|
|
|
|
; (setq hide nil) ; FIXME: turn this on for debugging only
|
2002-10-17 15:41:01 +00:00
|
|
|
|
; (if (null cmd)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
; (progn
|
2002-10-17 15:41:01 +00:00
|
|
|
|
; (message "SENDING Pending commands: %s"
|
2002-09-12 17:24:53 +00:00
|
|
|
|
; (prin1-to-string idlwave-shell-pending-commands)))
|
|
|
|
|
; (message "SENDING %s|||%s" cmd pcmd))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (and (symbolp idlwave-shell-show-commands)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(eq idlwave-shell-show-commands 'everything))
|
|
|
|
|
(setq hide nil))
|
|
|
|
|
(let ((save-buffer (current-buffer))
|
|
|
|
|
buf proc)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Get or make the buffer and its process
|
|
|
|
|
(if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))
|
|
|
|
|
(not (setq proc (get-buffer-process buf))))
|
|
|
|
|
(if (not idlwave-shell-automatic-start)
|
|
|
|
|
(error
|
|
|
|
|
(substitute-command-keys
|
|
|
|
|
"You need to first start an IDL shell with \\[idlwave-shell]"))
|
|
|
|
|
(idlwave-shell-recenter-shell-window)
|
|
|
|
|
(setq buf (get-buffer (idlwave-shell-buffer)))
|
|
|
|
|
(if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))
|
|
|
|
|
(not (setq proc (get-buffer-process buf))))
|
|
|
|
|
;; Still nothing
|
|
|
|
|
(error "Problem with autostarting IDL shell"))))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(when (or cmd idlwave-shell-pending-commands)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(set-buffer buf)
|
|
|
|
|
;; To make this easy, always push CMD onto pending commands
|
|
|
|
|
(if cmd
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(setq idlwave-shell-pending-commands
|
|
|
|
|
(if preempt
|
|
|
|
|
;; Put at front.
|
|
|
|
|
(append (list (list cmd pcmd hide))
|
|
|
|
|
idlwave-shell-pending-commands)
|
|
|
|
|
;; Put at end.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(append idlwave-shell-pending-commands
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(list (list cmd pcmd hide))))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Check if IDL ready
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(let ((save-point (point-marker)))
|
|
|
|
|
(goto-char (process-mark proc))
|
|
|
|
|
(if (and idlwave-shell-ready
|
|
|
|
|
;; Check for IDL prompt
|
|
|
|
|
(prog2
|
|
|
|
|
(forward-line 0)
|
|
|
|
|
;; (beginning-of-line) ; Changed for Emacs 21
|
|
|
|
|
(looking-at idlwave-shell-prompt-pattern)
|
|
|
|
|
(goto-char (process-mark proc))))
|
|
|
|
|
;; IDL ready for command, execute it
|
|
|
|
|
(let* ((lcmd (car idlwave-shell-pending-commands))
|
|
|
|
|
(cmd (car lcmd))
|
|
|
|
|
(pcmd (nth 1 lcmd))
|
|
|
|
|
(hide (nth 2 lcmd)))
|
|
|
|
|
;; If this is an executive command, reset the stack pointer
|
|
|
|
|
(if (eq (string-to-char cmd) ?.)
|
|
|
|
|
(setq idlwave-shell-calling-stack-index 0))
|
|
|
|
|
;; Set post-command
|
|
|
|
|
(setq idlwave-shell-post-command-hook pcmd)
|
|
|
|
|
;; Output hiding
|
|
|
|
|
(setq idlwave-shell-hide-output hide)
|
|
|
|
|
;; Pop command
|
|
|
|
|
(setq idlwave-shell-pending-commands
|
|
|
|
|
(cdr idlwave-shell-pending-commands))
|
|
|
|
|
;; Send command for execution
|
|
|
|
|
(set-marker comint-last-input-start (point))
|
|
|
|
|
(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))))
|
|
|
|
|
(goto-char save-point))
|
|
|
|
|
(set-buffer save-buffer))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defun idlwave-shell-send-char (c &optional no-error)
|
|
|
|
|
"Send one character to the shell, without a newline."
|
|
|
|
|
(interactive "cChar to send to IDL: ")
|
|
|
|
|
(let ((errf (if (interactive-p) 'error 'message))
|
|
|
|
|
buf proc)
|
|
|
|
|
(if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))
|
|
|
|
|
(not (setq proc (get-buffer-process buf))))
|
|
|
|
|
(funcall errf "Shell is not running"))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (equal c ?\C-g)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(funcall errf "Abort")
|
|
|
|
|
(comint-send-string proc (char-to-string c)))))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-char-mode-active)
|
|
|
|
|
(defun idlwave-shell-input-mode-magic (string)
|
|
|
|
|
"Check STRING for magic words and toggle character input mode.
|
|
|
|
|
See also the variable `idlwave-shell-input-mode-spells'."
|
|
|
|
|
(cond
|
|
|
|
|
((string-match (car idlwave-shell-input-mode-spells) string)
|
|
|
|
|
(call-interactively 'idlwave-shell-send-char))
|
|
|
|
|
((and (boundp 'idlwave-shell-char-mode-active)
|
|
|
|
|
(string-match (nth 2 idlwave-shell-input-mode-spells) string))
|
|
|
|
|
(setq idlwave-shell-char-mode-active 'exit))
|
|
|
|
|
((string-match (nth 1 idlwave-shell-input-mode-spells) string)
|
|
|
|
|
;; Set a timer which will soon start the character loop
|
|
|
|
|
(if (fboundp 'start-itimer)
|
|
|
|
|
(start-itimer "IDLWAVE Char Mode" 'idlwave-shell-char-mode-loop 0.5
|
|
|
|
|
nil nil t 'no-error)
|
|
|
|
|
(run-at-time 0.5 nil 'idlwave-shell-char-mode-loop 'no-error)))))
|
|
|
|
|
|
|
|
|
|
(defvar keyboard-quit)
|
|
|
|
|
(defun idlwave-shell-char-mode-loop (&optional no-error)
|
|
|
|
|
"Enter a loop which accepts single characters and sends them to IDL.
|
|
|
|
|
Characters are sent one by one, without newlines. The loop is blocking
|
|
|
|
|
and intercepts all input events to Emacs. You can use this command
|
|
|
|
|
to interact with the IDL command GET_KBRD.
|
|
|
|
|
The loop can be aborted by typing `C-g'. The loop also exits automatically
|
|
|
|
|
when the IDL prompt gets displayed again after the current IDL command."
|
|
|
|
|
(interactive)
|
|
|
|
|
|
|
|
|
|
;; First check if there is a shell waiting for input
|
|
|
|
|
(let ((idlwave-shell-char-mode-active t)
|
|
|
|
|
(errf (if no-error 'message 'error))
|
|
|
|
|
buf proc c)
|
|
|
|
|
(if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))
|
|
|
|
|
(not (setq proc (get-buffer-process buf))))
|
|
|
|
|
(funcall errf "Shell is not running"))
|
|
|
|
|
(if idlwave-shell-ready
|
|
|
|
|
(funcall errf "No IDL program seems to be waiting for input"))
|
|
|
|
|
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; OK, start the loop
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(message "Character mode on: Sending single chars (`C-g' to exit)")
|
|
|
|
|
(message
|
|
|
|
|
(catch 'exit
|
|
|
|
|
(while t
|
|
|
|
|
;; Wait for input
|
|
|
|
|
;; FIXME: Is it too dangerous to inhibit quit here?
|
|
|
|
|
(let ((inhibit-quit t))
|
|
|
|
|
;; We wait and check frequently if we should abort
|
|
|
|
|
(while (sit-for 0.3)
|
|
|
|
|
(and idlwave-shell-ready
|
|
|
|
|
(throw 'exit "Character mode off (prompt displayed)"))
|
|
|
|
|
(and (eq idlwave-shell-char-mode-active 'exit)
|
|
|
|
|
(throw 'exit "Character mode off (closing spell incantation)")))
|
|
|
|
|
;; Interpret input as a character - ignore non-char input
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(setq c (read-char))
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(error (ding) (throw 'exit "Character mode off")))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(cond
|
|
|
|
|
((null c) ; Non-char event: ignore
|
|
|
|
|
(ding))
|
|
|
|
|
((equal c ?\C-g) ; Abort the loop
|
|
|
|
|
(setq keyboard-quit nil)
|
|
|
|
|
(ding)
|
|
|
|
|
(throw 'exit "Character mode off (keyboard quit)"))
|
|
|
|
|
(t ; Send the character and continue the loop
|
|
|
|
|
(comint-send-string proc (char-to-string c))))
|
|
|
|
|
(and (eq idlwave-shell-char-mode-active 'exit)
|
|
|
|
|
(throw 'exit "Single char loop exited"))))))))
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defun idlwave-shell-move-or-history (up &optional arg)
|
2000-12-11 12:45:42 +00:00
|
|
|
|
"When in last line of process buffer, do `comint-previous-input'.
|
2002-09-12 17:24:53 +00:00
|
|
|
|
Otherwise just move the line. Move down unless UP is non-nil."
|
|
|
|
|
(let* ((proc-pos (marker-position
|
|
|
|
|
(process-mark (get-buffer-process (current-buffer)))))
|
|
|
|
|
(arg (or arg 1))
|
|
|
|
|
(arg (if up arg (- arg))))
|
|
|
|
|
(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)
|
|
|
|
|
(and (not (eolp)) (kill-line nil))
|
|
|
|
|
(comint-previous-input arg))
|
|
|
|
|
(previous-line arg))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-up-or-history (&optional arg)
|
|
|
|
|
"When in last line of process buffer, move to previous input.
|
|
|
|
|
Otherwise just go up one line."
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(interactive "p")
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-move-or-history t arg))
|
2000-12-11 12:45:42 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-down-or-history (&optional arg)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
"When in last line of process buffer, move to next input.
|
|
|
|
|
Otherwise just go down one line."
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(interactive "p")
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-move-or-history nil arg))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; Newer versions of comint.el changed the name of comint-filter to
|
|
|
|
|
;; comint-output-filter.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-comint-filter (process string) nil)
|
|
|
|
|
(if (fboundp 'comint-output-filter)
|
|
|
|
|
(fset 'idlwave-shell-comint-filter (symbol-function 'comint-output-filter))
|
|
|
|
|
(fset 'idlwave-shell-comint-filter (symbol-function 'comint-filter)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-is-running ()
|
|
|
|
|
"Return t if the shell process is running."
|
|
|
|
|
(eq (process-status idlwave-shell-process-name) 'run))
|
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defvar idlwave-shell-hidden-output-buffer " *idlwave-shell-hidden-output*"
|
|
|
|
|
"Buffer containing hidden output from IDL commands.")
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-filter (proc string)
|
|
|
|
|
"Replace Carriage returns in output. Watch for prompt.
|
|
|
|
|
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.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(let ((data (match-data)) p)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
;; May change the original match data.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(while (setq p (string-match "\C-M" string))
|
|
|
|
|
(aset string p ?\ ))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;;
|
|
|
|
|
;; Keep output
|
|
|
|
|
|
|
|
|
|
; Should not keep output because the concat is costly. If hidden put
|
|
|
|
|
; the output in a hide-buffer. Then when the output is needed in post
|
|
|
|
|
; processing can access either the hide buffer or the idlwave-shell
|
|
|
|
|
; buffer. Then watching for the prompt is easier. Furthermore, if it
|
|
|
|
|
; is hidden and there is no post command, could throw away output.
|
|
|
|
|
; (setq idlwave-shell-command-output
|
|
|
|
|
; (concat idlwave-shell-command-output string))
|
|
|
|
|
;; Insert the string. Do this before getting the
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; state.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(while (setq p (string-match "\C-G" string))
|
|
|
|
|
(ding)
|
|
|
|
|
(aset string p ?\C-j ))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(if idlwave-shell-hide-output
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(get-buffer-create idlwave-shell-hidden-output-buffer))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(insert string))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-comint-filter proc string))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Watch for magic - need to accumulate the current line
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; since it may not be sent all at once.
|
|
|
|
|
(if (string-match "\n" string)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(progn
|
|
|
|
|
(if idlwave-shell-use-input-mode-magic
|
|
|
|
|
(idlwave-shell-input-mode-magic
|
|
|
|
|
(concat idlwave-shell-accumulation string)))
|
|
|
|
|
(setq idlwave-shell-accumulation
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(substring string
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(progn (string-match "\\(.*\n\\)*" string)
|
|
|
|
|
(match-end 0)))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-accumulation
|
|
|
|
|
(concat idlwave-shell-accumulation string)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;;; Test/Debug code
|
|
|
|
|
; (save-excursion (set-buffer
|
|
|
|
|
; (get-buffer-create "*idlwave-shell-output*"))
|
|
|
|
|
; (goto-char (point-max))
|
|
|
|
|
; (insert "\nSTRING===>\n" string "\n<====\n"))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; Check for prompt in current accumulating output
|
|
|
|
|
(if (setq idlwave-shell-ready
|
|
|
|
|
(string-match idlwave-shell-prompt-pattern
|
|
|
|
|
idlwave-shell-accumulation))
|
|
|
|
|
(progn
|
|
|
|
|
(if idlwave-shell-hide-output
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer idlwave-shell-hidden-output-buffer)
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(re-search-backward idlwave-shell-prompt-pattern nil t)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(goto-char (match-end 0))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(setq idlwave-shell-command-output
|
|
|
|
|
(buffer-substring (point-min) (point)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;;; Test/Debug
|
2002-07-18 18:58:07 +00:00
|
|
|
|
; (save-excursion (set-buffer
|
|
|
|
|
; (get-buffer-create "*idlwave-shell-output*"))
|
|
|
|
|
; (goto-char (point-max))
|
|
|
|
|
; (insert "\nOUPUT===>\n" idlwave-shell-command-output "\n<===\n"))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(delete-region (point-min) (point)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-command-output
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(with-current-buffer (process-buffer proc)
|
|
|
|
|
(buffer-substring
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (process-mark proc))
|
|
|
|
|
(beginning-of-line nil)
|
|
|
|
|
(point))
|
|
|
|
|
comint-last-input-end))))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Scan for state and do post command - bracket them
|
|
|
|
|
;; with idlwave-shell-ready=nil since they
|
|
|
|
|
;; may call idlwave-shell-send-command.
|
|
|
|
|
(let ((idlwave-shell-ready nil))
|
|
|
|
|
(idlwave-shell-scan-for-state)
|
|
|
|
|
;; Unset idlwave-shell-ready to prevent sending
|
|
|
|
|
;; commands to IDL while running hook.
|
|
|
|
|
(if (listp idlwave-shell-post-command-hook)
|
|
|
|
|
(eval idlwave-shell-post-command-hook)
|
|
|
|
|
(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
|
2002-09-12 17:24:53 +00:00
|
|
|
|
idlwave-shell-hide-output nil
|
|
|
|
|
idlwave-shell-wait-for-output nil))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Done with post command. Do pending command if
|
|
|
|
|
;; any.
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(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 nil 100))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(store-match-data data)))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-sentinel (process event)
|
|
|
|
|
"The sentinel function for the IDLWAVE shell process."
|
|
|
|
|
(let* ((buf (idlwave-shell-buffer))
|
|
|
|
|
(win (get-buffer-window buf)))
|
|
|
|
|
(when (get-buffer buf)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (idlwave-shell-buffer))
|
|
|
|
|
(goto-char (point-max))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(insert (format "\n\n Process %s %s" process event))
|
|
|
|
|
(if (and idlwave-shell-save-command-history
|
|
|
|
|
(stringp idlwave-shell-command-history-file))
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(comint-write-input-ring)
|
|
|
|
|
(error nil)))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(when (and (> (length (frame-list)) 1)
|
|
|
|
|
(frame-live-p idlwave-shell-idl-wframe))
|
|
|
|
|
(delete-frame idlwave-shell-idl-wframe)
|
|
|
|
|
(setq idlwave-shell-idl-wframe nil
|
|
|
|
|
idlwave-shell-display-wframe nil))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(when (and (window-live-p win)
|
|
|
|
|
(not (one-window-p 'nomini)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(delete-window win))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(idlwave-shell-cleanup)
|
|
|
|
|
;; Run the hook, if possible in the shell buffer.
|
|
|
|
|
(if (get-buffer buf)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buf)
|
|
|
|
|
(run-hooks 'idlwave-shell-sentinel-hook))
|
|
|
|
|
(run-hooks 'idlwave-shell-sentinel-hook))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(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 interested in are
|
|
|
|
|
execution halted, stepped, breakpoint, interrupted at and trace
|
|
|
|
|
messages. We ignore error messages otherwise.
|
|
|
|
|
For breakpoint messages process any attached count or command
|
|
|
|
|
parameters.
|
|
|
|
|
Update the windows if a message is found."
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(cond
|
|
|
|
|
;; Make sure we have output
|
|
|
|
|
((not idlwave-shell-command-output))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; First Priority: Syntax and other errors
|
2002-10-17 15:41:01 +00:00
|
|
|
|
((or
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(string-match idlwave-shell-syntax-error 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))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(insert idlwave-shell-command-output)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(setq idlwave-shell-error-last (point)))
|
|
|
|
|
(idlwave-shell-goto-next-error))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; Second Priority: Various types of HALT messages.
|
|
|
|
|
((string-match idlwave-shell-halt-messages-re
|
|
|
|
|
idlwave-shell-command-output)
|
|
|
|
|
;; Grab the file and line state info.
|
|
|
|
|
(setq idlwave-shell-calling-stack-index 0)
|
|
|
|
|
(setq idlwave-shell-halt-frame
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-parse-line
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(substring idlwave-shell-command-output (match-end 0))))
|
|
|
|
|
(idlwave-shell-display-line (idlwave-shell-pc-frame)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
|
|
|
|
;; Last Priority: Breakpoints
|
2002-09-12 17:24:53 +00:00
|
|
|
|
((string-match idlwave-shell-break-message
|
|
|
|
|
idlwave-shell-command-output)
|
|
|
|
|
(setq idlwave-shell-calling-stack-index 0)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq idlwave-shell-halt-frame
|
|
|
|
|
(idlwave-shell-parse-line
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(substring idlwave-shell-command-output (match-end 0))))
|
|
|
|
|
;; We used to count hits on breakpoints
|
|
|
|
|
;; this is no longer supported since IDL breakpoints
|
|
|
|
|
;; have learned counting.
|
|
|
|
|
;; Do breakpoint command processing
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(let ((bp (assoc
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(list
|
|
|
|
|
(nth 0 idlwave-shell-halt-frame)
|
|
|
|
|
(nth 1 idlwave-shell-halt-frame))
|
|
|
|
|
idlwave-shell-bp-alist)))
|
|
|
|
|
(if bp
|
|
|
|
|
(let ((cmd (idlwave-shell-bp-get bp 'cmd)))
|
|
|
|
|
(if cmd
|
|
|
|
|
;; Execute command
|
|
|
|
|
(if (listp cmd) (eval cmd) (funcall cmd))))
|
|
|
|
|
;; A breakpoint that we did not know about - perhaps it was
|
|
|
|
|
;; set by the user or IDL isn't reporting breakpoints like
|
|
|
|
|
;; we expect. Lets update our list.
|
|
|
|
|
(idlwave-shell-bp-query)))
|
|
|
|
|
(idlwave-shell-display-line (idlwave-shell-pc-frame)))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defvar idlwave-shell-error-buffer " *idlwave-shell-errors*"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"Buffer containing syntax errors from IDL compilations.")
|
|
|
|
|
|
|
|
|
|
;; FIXME: the following two variables do not currently allow line breaks
|
|
|
|
|
;; in module and file names. I am not sure if it will be necessary to
|
|
|
|
|
;; change this. Currently it seems to work the way it is.
|
|
|
|
|
(defvar idlwave-shell-syntax-error
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"^% Syntax error.\\s-*\n\\s-*At:\\s-*\\(.*\\),\\s-*Line\\s-*\\(.*\\)"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"A regular expression to match an IDL syntax error.
|
|
|
|
|
The first \(..\) pair should match the file name. The second pair
|
|
|
|
|
should match the line number.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-other-error
|
|
|
|
|
"^% .*\n\\s-*At:\\s-*\\(.*\\),\\s-*Line\\s-*\\(.*\\)"
|
|
|
|
|
"A regular expression to match any IDL error.
|
|
|
|
|
The first \(..\) pair should match the file name. The second pair
|
|
|
|
|
should match the line number.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-file-line-message
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(concat
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"\\(" ; program name group (1)
|
|
|
|
|
"\\<[a-zA-Z][a-zA-Z0-9_$:]*" ; start with a letter, followed by [..]
|
|
|
|
|
"\\([ \t]*\n[ \t]*[a-zA-Z0-9_$:]+\\)*"; continuation lines program name (2)
|
|
|
|
|
"\\)" ; end program name group (1)
|
|
|
|
|
"[ \t\n]+" ; white space
|
|
|
|
|
"\\(" ; line number group (3)
|
|
|
|
|
"[0-9]+" ; the line number (the fix point)
|
|
|
|
|
"\\([ \t]*\n[ \t]*[0-9]+\\)*" ; continuation lines number (4)
|
|
|
|
|
"\\)" ; end line number group (3)
|
|
|
|
|
"[ \t\n]+" ; white space
|
|
|
|
|
"\\(" ; file name group (5)
|
|
|
|
|
"[^ \t\n]+" ; file names can contain any non-white
|
|
|
|
|
"\\([ \t]*\n[ \t]*[^ \t\n]+\\)*" ; continuation lines file name (6)
|
|
|
|
|
"\\)" ; end line number group (5)
|
|
|
|
|
)
|
|
|
|
|
"*A regular expression to parse out the file name and line number.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
The 1st group should match the subroutine name.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
The 3rd group is the line number.
|
|
|
|
|
The 5th group is the file name.
|
|
|
|
|
All parts may contain linebreaks surrounded by spaces. This is important
|
|
|
|
|
in IDL5 which inserts random linebreaks in long module and file names.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-parse-line (string)
|
|
|
|
|
"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
|
2002-10-17 15:41:01 +00:00
|
|
|
|
to be pretty good though.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
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."
|
|
|
|
|
|
|
|
|
|
(let (number procedure file)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(when (and (not (string-match ":\\s-*\\$MAIN" string))
|
|
|
|
|
(string-match idlwave-shell-file-line-message string))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq procedure (match-string 1 string)
|
|
|
|
|
number (match-string 3 string)
|
|
|
|
|
file (match-string 5 string))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Repair the strings
|
|
|
|
|
(setq procedure (idlwave-shell-repair-string procedure))
|
|
|
|
|
(setq number (idlwave-shell-repair-string number))
|
|
|
|
|
(setq file (idlwave-shell-repair-file-name file))
|
|
|
|
|
|
|
|
|
|
;; If we have a file, return the frame list
|
|
|
|
|
(if file
|
|
|
|
|
(list (idlwave-shell-file-name file)
|
|
|
|
|
(string-to-int number)
|
|
|
|
|
procedure)
|
|
|
|
|
;; No success finding a file
|
|
|
|
|
nil))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-repair-string (string)
|
|
|
|
|
"Repair a string by taking out all linebreaks. This is destructive!"
|
|
|
|
|
(while (string-match "[ \t]*\n[ \t]*" string)
|
|
|
|
|
(setq string (replace-match "" t t string)))
|
|
|
|
|
string)
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-repair-file-name (file)
|
|
|
|
|
"Repair a file name string by taking out all linebreaks.
|
|
|
|
|
The last line of STRING may be garbage - we check which one makes a valid
|
|
|
|
|
file name."
|
|
|
|
|
(let ((file1 "") (file2 "") (start 0))
|
|
|
|
|
;; We scan no further than to the next "^%" line
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (string-match "^%" file)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq file (substring file 0 (match-beginning 0))))
|
|
|
|
|
;; Take out the line breaks
|
|
|
|
|
(while (string-match "[ \t]*\n[ \t]*" file start)
|
|
|
|
|
(setq file1 (concat file1 (substring file start (match-beginning 0)))
|
|
|
|
|
start (match-end 0)))
|
|
|
|
|
(setq file2 (concat file1 (substring file start)))
|
|
|
|
|
(cond
|
|
|
|
|
((file-regular-p file2) file2)
|
|
|
|
|
((file-regular-p file1) file1)
|
|
|
|
|
;; If we cannot veryfy the existence of the file, we return the shorter
|
|
|
|
|
;; name. The idea behind this is that this may be a relative file name
|
|
|
|
|
;; and our idea about the current working directory may be wrong.
|
|
|
|
|
;; If it is a relative file name, it hopefully is short.
|
|
|
|
|
((not (string= "" file1)) file1)
|
|
|
|
|
((not (string= "" file2)) file2)
|
|
|
|
|
(t nil))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-cleanup ()
|
|
|
|
|
"Do necessary cleanup for a terminated IDL process."
|
|
|
|
|
(setq idlwave-shell-step-frame nil
|
|
|
|
|
idlwave-shell-halt-frame nil
|
|
|
|
|
idlwave-shell-pending-commands nil
|
|
|
|
|
idlwave-shell-command-line-to-execute nil
|
|
|
|
|
idlwave-shell-bp-alist nil
|
2000-06-20 12:49:47 +00:00
|
|
|
|
idlwave-shell-calling-stack-index 0
|
2002-09-13 06:18:53 +00:00
|
|
|
|
idlwave-idlwave_routine_info-compiled nil)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(idlwave-shell-delete-temp-files)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-display-line nil)
|
|
|
|
|
(idlwave-shell-update-bp-overlays) ; kill old overlays
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(idlwave-shell-kill-buffer idlwave-shell-hidden-output-buffer)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-kill-buffer idlwave-shell-bp-buffer)
|
|
|
|
|
(idlwave-shell-kill-buffer idlwave-shell-error-buffer)
|
|
|
|
|
;; (idlwave-shell-kill-buffer (idlwave-shell-buffer))
|
|
|
|
|
(and (get-buffer (idlwave-shell-buffer))
|
|
|
|
|
(bury-buffer (get-buffer (idlwave-shell-buffer))))
|
|
|
|
|
(run-hooks 'idlwave-shell-cleanup-hook))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-kill-buffer (buf)
|
|
|
|
|
"Kill buffer BUF if it exists."
|
|
|
|
|
(if (setq buf (get-buffer buf))
|
|
|
|
|
(kill-buffer buf)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-kill-shell-buffer-confirm ()
|
|
|
|
|
(when (idlwave-shell-is-running)
|
|
|
|
|
(ding)
|
|
|
|
|
(unless (y-or-n-p "IDL shell is running. Are you sure you want to kill the buffer? ")
|
|
|
|
|
(error "Abort"))
|
|
|
|
|
(message "Killing buffer *idl* and the associated process")))
|
|
|
|
|
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(defun idlwave-shell-window (n)
|
|
|
|
|
"Issue a `window,N' command to IDL, with special window size.
|
|
|
|
|
The size is given by `idlwave-shell-graphics-window-size'."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((n (if n (prefix-numeric-value n) 0)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(apply 'format "window,%d,xs=%d,ys=%d"
|
2002-09-12 17:24:53 +00:00
|
|
|
|
n idlwave-shell-graphics-window-size)
|
|
|
|
|
nil (idlwave-shell-hide-p 'misc))))
|
2000-12-11 12:45:42 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-resync-dirs ()
|
2002-09-12 17:24:53 +00:00
|
|
|
|
"Resync the buffer's idea of the current directory.
|
|
|
|
|
This command queries IDL with the command bound to
|
|
|
|
|
`idlwave-shell-dirstack-query', reads the output for the new
|
|
|
|
|
directory."
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-send-command idlwave-shell-dirstack-query
|
|
|
|
|
'idlwave-shell-filter-directory
|
2002-09-12 17:24:53 +00:00
|
|
|
|
'hide 'wait))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-retall (&optional arg)
|
|
|
|
|
"Return from the entire calling stack."
|
|
|
|
|
(interactive "P")
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command "retall" nil (idlwave-shell-hide-p 'misc)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-closeall (&optional arg)
|
|
|
|
|
"Close all open files."
|
|
|
|
|
(interactive "P")
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command "close,/all" nil (idlwave-shell-hide-p 'misc)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-quit (&optional arg)
|
|
|
|
|
"Exit the idl process after confirmation.
|
|
|
|
|
With prefix ARG, exit without confirmation."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (not (idlwave-shell-is-running))
|
|
|
|
|
(error "Shell is not running")
|
|
|
|
|
(if (or arg (y-or-n-p "Exit the IDLWAVE Shell? "))
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(idlwave-shell-send-command "exit")
|
|
|
|
|
(error nil)))))
|
|
|
|
|
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(defun idlwave-shell-reset (&optional hidden)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
"Reset IDL. Return to main level and destroy the leftover variables.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
This issues the following commands:
|
2000-01-03 14:23:13 +00:00
|
|
|
|
RETALL
|
|
|
|
|
WIDGET_CONTROL,/RESET
|
|
|
|
|
CLOSE, /ALL
|
|
|
|
|
HEAP_GC, /VERBOSE"
|
|
|
|
|
;; OBJ_DESTROY, OBJ_VALID() FIXME: should this be added?
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(message "Resetting IDL")
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(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))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defun idlwave-shell-path-filter ()
|
|
|
|
|
;; Convert the output of the path query into a list of directories
|
|
|
|
|
(let ((path-string idlwave-shell-command-output)
|
|
|
|
|
(case-fold-search t)
|
|
|
|
|
(start 0)
|
|
|
|
|
dirs sysdir)
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(while (string-match "^PATH:[ \t]*<\\(.*\\)>[ \t]*\n" path-string start)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(push (match-string 1 path-string) dirs)
|
|
|
|
|
(setq start (match-end 0)))
|
|
|
|
|
(setq dirs (mapcar 'file-name-as-directory dirs))
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(if (string-match "^SYSDIR:[ \t]*<\\(.*\\)>[ \t]*\n" path-string)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq sysdir (file-name-as-directory
|
|
|
|
|
(match-string 1 path-string))))
|
|
|
|
|
(cons sysdir (nreverse dirs))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-routine-info-filter ()
|
|
|
|
|
"Function which parses the special output from idlwave_routine_info.pro."
|
|
|
|
|
(let ((text idlwave-shell-command-output)
|
|
|
|
|
(start 0)
|
|
|
|
|
sep sep-re file type spec specs name cs key keys class entry)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
; (message "GOT: %s" text) ;??????????????????????
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; Initialize variables
|
|
|
|
|
(setq idlwave-compiled-routines nil
|
|
|
|
|
idlwave-unresolved-routines nil)
|
|
|
|
|
;; Cut out the correct part of the output.
|
|
|
|
|
(if (string-match
|
|
|
|
|
"^>>>BEGIN OF IDLWAVE ROUTINE INFO (\"\\(.+\\)\" IS THE SEPARATOR.*"
|
|
|
|
|
text)
|
|
|
|
|
(setq sep (match-string 1 text)
|
|
|
|
|
sep-re (concat (regexp-quote sep) " *")
|
|
|
|
|
text (substring text (match-end 0)))
|
|
|
|
|
;; Set dummy values and kill the text
|
|
|
|
|
(setq sep "@" sep-re "@ *" text "")
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(message "Routine Info warning: No match for BEGIN line in \n>>>>\n%s\n<<<<\n"
|
2002-07-18 18:58:07 +00:00
|
|
|
|
idlwave-shell-command-output))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(if (string-match "^>>>END OF IDLWAVE ROUTINE INFO.*" text)
|
|
|
|
|
(setq text (substring text 0 (match-beginning 0)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(message "Routine Info warning: No match for END line in \n>>>>\n%s\n<<<<\n"
|
2002-07-18 18:58:07 +00:00
|
|
|
|
idlwave-shell-command-output))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(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))
|
|
|
|
|
(setq type (match-string 1 text)
|
|
|
|
|
spec (match-string 2 text)
|
|
|
|
|
specs (idlwave-split-string spec sep-re)
|
|
|
|
|
name (nth 0 specs)
|
|
|
|
|
class (if (equal (nth 1 specs) "") nil (nth 1 specs))
|
|
|
|
|
file (nth 2 specs)
|
|
|
|
|
cs (nth 3 specs)
|
|
|
|
|
key (nth 4 specs)
|
|
|
|
|
keys (if (and (stringp key)
|
|
|
|
|
(not (string-match "\\` *\\'" key)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(mapcar 'list
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(delete "" (idlwave-split-string key " +")))))
|
|
|
|
|
(setq name (idlwave-sintern-routine-or-method name class t)
|
|
|
|
|
class (idlwave-sintern-class class t)
|
|
|
|
|
file (if (equal file "") nil file)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
keys (mapcar (lambda (x)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(list (idlwave-sintern-keyword (car x) t))) keys))
|
|
|
|
|
;; Make sure we use the same string object for the same file
|
|
|
|
|
(setq file (idlwave-sintern-file file t))
|
|
|
|
|
;; FIXME: What should I do with routines from the temp file???
|
|
|
|
|
;; Maybe just leave it in - there is a chance that the
|
|
|
|
|
;; routine is still in there.
|
|
|
|
|
;; (if (equal file idlwave-shell-temp-pro-file)
|
|
|
|
|
;; (setq file nil))
|
|
|
|
|
|
|
|
|
|
;; In the following ignore routines already defined in buffers,
|
|
|
|
|
;; assuming that if the buffer stuff differs, it is a "new"
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; version.
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; We could do the same for the library to avoid duplicates -
|
|
|
|
|
;; but I think frequently a user might have several versions of
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; the same function in different programs, and in this case the
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; compiled one will be the best guess of all version.
|
|
|
|
|
;; Therefore, we leave duplicates of library routines in.
|
|
|
|
|
|
|
|
|
|
(cond ((string= name "$MAIN$")) ; ignore this one
|
|
|
|
|
((and (string= type "PRO")
|
|
|
|
|
;; FIXME: is it OK to make the buffer routines dominate?
|
|
|
|
|
(or t (null file)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(not (idlwave-rinfo-assq name 'pro class
|
2000-06-20 12:49:47 +00:00
|
|
|
|
idlwave-buffer-routines)))
|
|
|
|
|
;; FIXME: is it OK to make the library routines dominate?
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;;(not (idlwave-rinfo-assq name 'pro class
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; idlwave-library-routines))
|
|
|
|
|
)
|
|
|
|
|
(setq entry (list name 'pro class (cons 'compiled file) cs keys))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if file
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(push entry idlwave-compiled-routines)
|
|
|
|
|
(push entry idlwave-unresolved-routines)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
((and (string= type "FUN")
|
|
|
|
|
;; FIXME: is it OK to make the buffer routines dominate?
|
|
|
|
|
(or t (not file)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(not (idlwave-rinfo-assq name 'fun class
|
2000-06-20 12:49:47 +00:00
|
|
|
|
idlwave-buffer-routines)))
|
|
|
|
|
;; FIXME: is it OK to make the library routines dominate?
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; (not (idlwave-rinfo-assq name 'fun class
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; idlwave-library-routines))
|
|
|
|
|
)
|
|
|
|
|
(setq entry (list name 'fun class (cons 'compiled file) cs keys))
|
|
|
|
|
(if file
|
|
|
|
|
(push entry idlwave-compiled-routines)
|
|
|
|
|
(push entry idlwave-unresolved-routines))))))
|
|
|
|
|
;; Reverse the definitions so that they are alphabetically sorted.
|
|
|
|
|
(setq idlwave-compiled-routines (nreverse idlwave-compiled-routines)
|
|
|
|
|
idlwave-unresolved-routines (nreverse idlwave-unresolved-routines)))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-filter-directory ()
|
|
|
|
|
"Get the current directory from `idlwave-shell-command-output'.
|
|
|
|
|
Change the default directory for the process buffer to concur."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (idlwave-shell-buffer))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(if (string-match ",___cur[\n\r]\\(\\S-*\\) *[\n\r]"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
idlwave-shell-command-output)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(let ((dir (substring idlwave-shell-command-output
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(match-beginning 1) (match-end 1))))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
; (message "Setting Emacs working dir to %s" dir)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-default-directory dir)
|
|
|
|
|
(setq default-directory (file-name-as-directory dir))))))
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defvar idlwave-shell-get-object-class nil)
|
|
|
|
|
(defun idlwave-shell-get-object-class (apos)
|
|
|
|
|
"Query the shell for the class of the object before point."
|
|
|
|
|
(let ((bos (save-excursion (idlwave-start-of-substatement 'pre) (point)))
|
|
|
|
|
(bol (save-excursion (forward-line 0) (point)))
|
|
|
|
|
expression)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char apos)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq expression (buffer-substring
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(catch 'exit
|
|
|
|
|
(while t
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (not (re-search-backward
|
2002-09-12 17:24:53 +00:00
|
|
|
|
"[^][.A-Za-z0-9_() ]" bos t))
|
|
|
|
|
(throw 'exit bos)) ;ran into bos
|
|
|
|
|
(if (not (idlwave-is-pointer-dereference bol))
|
|
|
|
|
(throw 'exit (1+ (point))))))
|
|
|
|
|
apos)))
|
|
|
|
|
(when (not (string= expression ""))
|
|
|
|
|
(setq idlwave-shell-get-object-class nil)
|
|
|
|
|
(idlwave-shell-send-command
|
|
|
|
|
(concat "print,obj_class(" expression ")")
|
|
|
|
|
'idlwave-shell-parse-object-class
|
|
|
|
|
'hide 'wait)
|
|
|
|
|
;; If we don't know anything about the class, update shell routines
|
|
|
|
|
(if (and idlwave-shell-get-object-class
|
2004-05-22 21:50:03 +00:00
|
|
|
|
(not (assoc-string idlwave-shell-get-object-class
|
|
|
|
|
(idlwave-class-alist) t)))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-maybe-update-routine-info))
|
|
|
|
|
idlwave-shell-get-object-class)))
|
|
|
|
|
|
|
|
|
|
(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))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq idlwave-shell-get-object-class
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(match-string 1 idlwave-shell-command-output)))))
|
|
|
|
|
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-complete (&optional arg)
|
|
|
|
|
"Do completion in the idlwave-shell buffer.
|
|
|
|
|
Calls `idlwave-shell-complete-filename' after some executive commands or
|
|
|
|
|
in strings. Otherwise, calls `idlwave-complete' to complete modules and
|
|
|
|
|
keywords."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let (cmd)
|
|
|
|
|
(cond
|
|
|
|
|
((setq cmd (idlwave-shell-executive-command))
|
|
|
|
|
;; We are in a command line with an executive command
|
|
|
|
|
(if (member (upcase cmd)
|
|
|
|
|
'(".R" ".RU" ".RUN" ".RN" ".RNE" ".RNEW"
|
|
|
|
|
".COM" ".COMP" ".COMPI" ".COMPIL" ".COMPILE"))
|
|
|
|
|
;; This command expects file names
|
|
|
|
|
(idlwave-shell-complete-filename)))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
|
|
|
|
|
((idlwave-shell-batch-command)
|
|
|
|
|
(idlwave-shell-complete-filename))
|
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
((and (idlwave-shell-filename-string)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(let ((case-fold-search t))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(not (looking-at ".*obj_new")))))
|
|
|
|
|
(idlwave-shell-complete-filename))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(t
|
|
|
|
|
;; Default completion of modules and keywords
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(idlwave-complete arg)))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-complete-filename (&optional arg)
|
|
|
|
|
"Complete a file name at point if after a file name.
|
|
|
|
|
We assume that we are after a file name when completing one of the
|
2002-09-12 17:24:53 +00:00
|
|
|
|
args of an executive .run, .rnew or .compile."
|
|
|
|
|
;; CWD might have changed, resync, to set default directory
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-resync-dirs)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(let ((comint-file-name-chars idlwave-shell-file-name-chars))
|
|
|
|
|
(comint-dynamic-complete-as-filename)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-executive-command ()
|
|
|
|
|
"Return the name of the current executive command, if any."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(idlwave-beginning-of-statement)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(if (looking-at "[ \t]*\\([.][^ \t\n\r]+\\)")
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(match-string 1))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-filename-string ()
|
|
|
|
|
"Return t if in a string and after what could be a file name."
|
|
|
|
|
(let ((limit (save-excursion (beginning-of-line) (point))))
|
|
|
|
|
(save-excursion
|
|
|
|
|
;; Skip backwards over file name chars
|
|
|
|
|
(skip-chars-backward idlwave-shell-file-name-chars limit)
|
|
|
|
|
;; Check of the next char is a string delimiter
|
|
|
|
|
(memq (preceding-char) '(?\' ?\")))))
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defun idlwave-shell-batch-command ()
|
|
|
|
|
"Returns t if we're in a batch command statement like @foo"
|
|
|
|
|
(let ((limit (save-excursion (beginning-of-line) (point))))
|
|
|
|
|
(save-excursion
|
|
|
|
|
;; Skip backwards over filename
|
|
|
|
|
(skip-chars-backward idlwave-shell-file-name-chars limit)
|
|
|
|
|
(skip-chars-backward " \t" limit)
|
|
|
|
|
(and (eq (preceding-char) ?@) (not (idlwave-in-quote))))))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;;;
|
|
|
|
|
;;; This section contains code for debugging IDL programs. --------------------
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-redisplay (&optional hide)
|
|
|
|
|
"Tries to resync the display with where execution has stopped.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
Issues a \"help,/trace\" command followed by a call to
|
2000-01-03 14:23:13 +00:00
|
|
|
|
`idlwave-shell-display-line'. Also updates the breakpoint
|
|
|
|
|
overlays."
|
|
|
|
|
(interactive)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(setq idlwave-shell-calling-stack-index 0)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-send-command
|
|
|
|
|
"help,/trace"
|
|
|
|
|
'(idlwave-shell-display-line
|
|
|
|
|
(idlwave-shell-pc-frame))
|
|
|
|
|
hide)
|
|
|
|
|
(idlwave-shell-bp-query))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-display-level-in-calling-stack (&optional hide)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"help,/trace"
|
2000-02-04 10:10:40 +00:00
|
|
|
|
`(progn
|
|
|
|
|
;; scanning for the state will reset the stack level - restore it
|
|
|
|
|
(setq idlwave-shell-calling-stack-index
|
|
|
|
|
,idlwave-shell-calling-stack-index)
|
|
|
|
|
;; parse the stack and visit the selected frame
|
|
|
|
|
(idlwave-shell-parse-stack-and-display))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
hide))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-parse-stack-and-display ()
|
|
|
|
|
(let* ((lines (delete "" (idlwave-split-string
|
|
|
|
|
idlwave-shell-command-output "^%")))
|
|
|
|
|
(stack (delq nil (mapcar 'idlwave-shell-parse-line lines)))
|
|
|
|
|
(nmax (1- (length stack)))
|
|
|
|
|
(nmin 0) message)
|
|
|
|
|
(cond
|
|
|
|
|
((< nmax nmin)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq idlwave-shell-calling-stack-index 0)
|
|
|
|
|
(ding)
|
|
|
|
|
(message "Problem with calling stack"))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
((> idlwave-shell-calling-stack-index nmax)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(ding)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-calling-stack-index nmax
|
2000-02-04 10:10:40 +00:00
|
|
|
|
message (format "%d is the highest calling stack level - can't go further up"
|
|
|
|
|
(- nmax))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
((< idlwave-shell-calling-stack-index nmin)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(ding)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-calling-stack-index nmin
|
2000-02-04 10:10:40 +00:00
|
|
|
|
message (format "%d is the current calling stack level - can't go further down"
|
|
|
|
|
(- nmin)))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq idlwave-shell-calling-stack-routine
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(nth 2 (nth idlwave-shell-calling-stack-index stack)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-display-line
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(nth idlwave-shell-calling-stack-index stack))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(message (or message
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(format "In routine %s (stack level %d)"
|
|
|
|
|
idlwave-shell-calling-stack-routine
|
|
|
|
|
(- idlwave-shell-calling-stack-index))))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-stack-up ()
|
|
|
|
|
"Display the source code one step up the calling stack."
|
|
|
|
|
(interactive)
|
|
|
|
|
(incf idlwave-shell-calling-stack-index)
|
|
|
|
|
(idlwave-shell-display-level-in-calling-stack 'hide))
|
|
|
|
|
(defun idlwave-shell-stack-down ()
|
|
|
|
|
"Display the source code one step down the calling stack."
|
|
|
|
|
(interactive)
|
|
|
|
|
(decf idlwave-shell-calling-stack-index)
|
|
|
|
|
(idlwave-shell-display-level-in-calling-stack 'hide))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-goto-frame (&optional frame)
|
|
|
|
|
"Set buffer to FRAME with point at the frame line.
|
|
|
|
|
If the optional argument FRAME is nil then idlwave-shell-pc-frame is
|
|
|
|
|
used. Does nothing if the resulting frame is nil."
|
|
|
|
|
(if frame ()
|
|
|
|
|
(setq frame (idlwave-shell-pc-frame)))
|
|
|
|
|
(cond
|
|
|
|
|
(frame
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(set-buffer (idlwave-find-file-noselect (car frame) 'shell))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(widen)
|
|
|
|
|
(goto-line (nth 1 frame)))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-pc-frame ()
|
|
|
|
|
"Returns the frame for IDL execution."
|
|
|
|
|
(and idlwave-shell-halt-frame
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(list (nth 0 idlwave-shell-halt-frame)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(nth 1 idlwave-shell-halt-frame)
|
|
|
|
|
(nth 2 idlwave-shell-halt-frame))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-valid-frame (frame)
|
|
|
|
|
"Check that frame is for an existing file."
|
|
|
|
|
(file-readable-p (car frame)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-display-line (frame &optional col)
|
|
|
|
|
"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 (not frame)
|
|
|
|
|
;; Remove stop-line overlay from old position
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(progn
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq overlay-arrow-string nil)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(setq idlwave-shell-mode-line-info nil)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq idlwave-shell-is-stopped nil)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(if idlwave-shell-stop-line-overlay
|
|
|
|
|
(delete-overlay idlwave-shell-stop-line-overlay)))
|
|
|
|
|
(if (not (idlwave-shell-valid-frame frame))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; FIXME: errors are dangerous in shell filters. But I think I
|
|
|
|
|
;; have never encountered this one.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(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.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;;;
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(setq idlwave-shell-mode-line-info
|
|
|
|
|
(if (nth 2 frame)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(format "[%d:%s]"
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(- idlwave-shell-calling-stack-index)
|
|
|
|
|
(nth 2 frame))))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(let* ((buffer (idlwave-find-file-noselect (car frame) 'shell))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(select-shell (equal (buffer-name) (idlwave-shell-buffer)))
|
|
|
|
|
window pos)
|
|
|
|
|
|
|
|
|
|
;; 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.
|
|
|
|
|
(setq window (idlwave-display-buffer buffer
|
|
|
|
|
nil (idlwave-shell-source-frame)))
|
|
|
|
|
|
|
|
|
|
;; Enter the buffer and mark the line
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
|
|
|
|
(goto-line (nth 1 frame))
|
|
|
|
|
(setq pos (point))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq idlwave-shell-is-stopped t)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(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.
|
|
|
|
|
(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)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; 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 col (move-to-column col))
|
|
|
|
|
(setq pos (point)))
|
|
|
|
|
|
|
|
|
|
;; Make sure pos is really displayed in the window.
|
|
|
|
|
(set-window-point window pos)
|
|
|
|
|
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; If we came from the shell, go back there. Otherwise select
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; the window where the error is displayed.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (and (equal (buffer-name) (idlwave-shell-buffer))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(not select-shell))
|
|
|
|
|
(select-window window))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-step (arg)
|
|
|
|
|
"Step one source line. If given prefix argument ARG, step ARG source lines."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(or (not arg) (< arg 1)
|
|
|
|
|
(setq arg 1))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(concat ".s " (if (integerp arg) (int-to-string arg) arg))
|
|
|
|
|
nil (idlwave-shell-hide-p 'debug)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-stepover (arg)
|
|
|
|
|
"Stepover one source line.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
If given prefix argument ARG, step ARG source lines.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
Uses IDL's stepover executive command which does not enter called functions."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(or (not arg) (< arg 1)
|
|
|
|
|
(setq arg 1))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(concat ".so " (if (integerp arg) (int-to-string arg) arg))
|
|
|
|
|
nil (idlwave-shell-hide-p 'debug)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defun idlwave-shell-break-here (&optional count cmd condition)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"Set breakpoint at current line.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
If Count is nil then an ordinary breakpoint is set. We treat a count
|
|
|
|
|
of 1 as a temporary breakpoint using the ONCE keyword. Counts greater
|
|
|
|
|
than 1 use the IDL AFTER=count keyword to break only after reaching
|
|
|
|
|
the statement count times.
|
|
|
|
|
|
2002-10-17 15:41:01 +00:00
|
|
|
|
Optional argument CMD is a list or function to evaluate upon reaching
|
2000-01-03 14:23:13 +00:00
|
|
|
|
the breakpoint."
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(interactive "P")
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(when (listp count)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (equal (car count) 4)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(setq condition (read-string "Break Condition: ")))
|
|
|
|
|
(setq count nil))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-set-bp
|
|
|
|
|
;; Create breakpoint
|
|
|
|
|
(idlwave-shell-bp (idlwave-shell-current-frame)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(list count cmd condition)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-current-module))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-set-bp-check (bp)
|
|
|
|
|
"Check for failure to set breakpoint.
|
|
|
|
|
This is run on `idlwave-shell-post-command-hook'.
|
|
|
|
|
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 (progn
|
|
|
|
|
(beep)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(y-or-n-p
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(concat "Okay to recompile file "
|
|
|
|
|
(idlwave-shell-bp-get bp 'file) " ")))
|
|
|
|
|
;; Recompile
|
|
|
|
|
(progn
|
|
|
|
|
;; Clean up before retrying
|
|
|
|
|
(idlwave-shell-command-failure)
|
|
|
|
|
(idlwave-shell-send-command
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(concat ".run " (idlwave-shell-bp-get bp 'file)) nil
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-hide-p 'run))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; 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))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-command-failure ()
|
|
|
|
|
"Do any necessary clean up when an IDL command fails.
|
|
|
|
|
Call this from a function attached to `idlwave-shell-post-command-hook'
|
|
|
|
|
that detects the failure of a command.
|
|
|
|
|
For example, this is called from `idlwave-shell-set-bp-check' when a
|
|
|
|
|
breakpoint can not be set."
|
|
|
|
|
;; Clear pending commands
|
|
|
|
|
(setq idlwave-shell-pending-commands nil))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-cont ()
|
|
|
|
|
"Continue executing."
|
|
|
|
|
(interactive)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command ".c" '(idlwave-shell-redisplay 'hide)
|
|
|
|
|
(idlwave-shell-hide-p 'debug)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-go ()
|
|
|
|
|
"Run .GO. This starts the main program of the last compiled file."
|
|
|
|
|
(interactive)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command ".go" '(idlwave-shell-redisplay 'hide)
|
|
|
|
|
(idlwave-shell-hide-p 'debug)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-return ()
|
|
|
|
|
"Run .RETURN (continue to next return, but stay in subprogram)."
|
|
|
|
|
(interactive)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command ".return" '(idlwave-shell-redisplay 'hide)
|
|
|
|
|
(idlwave-shell-hide-p 'debug)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-skip ()
|
|
|
|
|
"Run .SKIP (skip one line, then step)."
|
|
|
|
|
(interactive)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command ".skip" '(idlwave-shell-redisplay 'hide)
|
|
|
|
|
(idlwave-shell-hide-p 'debug)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-clear-bp (bp)
|
|
|
|
|
"Clear breakpoint BP.
|
|
|
|
|
Clears in IDL and in `idlwave-shell-bp-alist'."
|
|
|
|
|
(let ((index (idlwave-shell-bp-get bp)))
|
|
|
|
|
(if index
|
|
|
|
|
(progn
|
|
|
|
|
(idlwave-shell-send-command
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(concat "breakpoint,/clear,"
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(if (integerp index) (int-to-string index) index))
|
|
|
|
|
nil (idlwave-shell-hide-p 'breakpoint))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-bp-query)))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-current-frame ()
|
|
|
|
|
"Return a list containing the current file name and line point is in.
|
|
|
|
|
If in the IDL shell buffer, returns `idlwave-shell-pc-frame'."
|
|
|
|
|
(if (eq (current-buffer) (get-buffer (idlwave-shell-buffer)))
|
|
|
|
|
;; In IDL shell
|
|
|
|
|
(idlwave-shell-pc-frame)
|
|
|
|
|
;; In source
|
|
|
|
|
(list (idlwave-shell-file-name (buffer-file-name))
|
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(1+ (count-lines 1 (point))))))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-current-module ()
|
|
|
|
|
"Return the name of the module for the current file.
|
|
|
|
|
Returns nil if unable to obtain a module name."
|
|
|
|
|
(if (eq (current-buffer) (get-buffer (idlwave-shell-buffer)))
|
|
|
|
|
;; In IDL shell
|
|
|
|
|
(nth 2 idlwave-shell-halt-frame)
|
|
|
|
|
;; In pro file
|
|
|
|
|
(save-restriction
|
|
|
|
|
(widen)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(if (idlwave-prev-index-position)
|
|
|
|
|
(upcase (idlwave-unit-name)))))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-clear-current-bp ()
|
|
|
|
|
"Remove breakpoint at current line.
|
|
|
|
|
This command can be called from the shell buffer if IDL is currently stopped
|
|
|
|
|
at a breakpoint."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((bp (idlwave-shell-find-bp (idlwave-shell-current-frame))))
|
|
|
|
|
(if bp (idlwave-shell-clear-bp bp)
|
|
|
|
|
;; Try moving to beginning of statement
|
|
|
|
|
(save-excursion
|
|
|
|
|
(idlwave-shell-goto-frame)
|
|
|
|
|
(idlwave-beginning-of-statement)
|
|
|
|
|
(setq bp (idlwave-shell-find-bp (idlwave-shell-current-frame)))
|
|
|
|
|
(if bp (idlwave-shell-clear-bp bp)
|
|
|
|
|
(beep)
|
|
|
|
|
(message "Cannot identify breakpoint for this line"))))))
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defun idlwave-shell-disable-all-bp (&optional enable)
|
|
|
|
|
"Disable all breakpoints we know about.
|
|
|
|
|
If ENABLE is non-nil, enable them instead."
|
|
|
|
|
(let ((bpl idlwave-shell-bp-alist))
|
|
|
|
|
(while bpl
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(concat "breakpoint,"
|
|
|
|
|
(if enable "/enable," "/disable," )
|
|
|
|
|
(idlwave-shell-bp-get (car bpl)))
|
|
|
|
|
nil (idlwave-shell-hide-p 'breakpoint))
|
|
|
|
|
(setq bpl (cdr bpl)))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-to-here ()
|
|
|
|
|
"Set a breakpoint with count 1 then continue."
|
|
|
|
|
(interactive)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-disable-all-bp)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-break-here 1)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-cont)
|
|
|
|
|
(idlwave-shell-disable-all-bp 'enable))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-break-in (&optional module)
|
|
|
|
|
"Look for a module name near point and set a break point for it.
|
|
|
|
|
The command looks for an identifier near point and sets a breakpoint
|
|
|
|
|
for the first line of the corresponding module."
|
|
|
|
|
(interactive)
|
|
|
|
|
;; get the identifier
|
|
|
|
|
(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)
|
|
|
|
|
"Set breakpoint in module. Assumes that `idlwave-shell-sources-alist'
|
|
|
|
|
contains an entry for that module."
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(let ((source-file (car-safe
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(cdr-safe
|
|
|
|
|
(assoc (upcase module)
|
|
|
|
|
idlwave-shell-sources-alist))))
|
|
|
|
|
buf)
|
|
|
|
|
(if (or (not source-file)
|
|
|
|
|
(not (file-regular-p source-file))
|
|
|
|
|
(not (setq buf
|
|
|
|
|
(or (idlwave-get-buffer-visiting source-file)
|
|
|
|
|
(find-file-noselect source-file)))))
|
|
|
|
|
(progn
|
|
|
|
|
(message "The source file for module %s is probably not compiled"
|
|
|
|
|
module)
|
|
|
|
|
(beep))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buf)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(let ((case-fold-search t))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (re-search-forward
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(concat "^[ \t]*\\(pro\\|function\\)[ \t]+"
|
|
|
|
|
(downcase module)
|
|
|
|
|
"[ \t\n,]") nil t)
|
|
|
|
|
(progn
|
|
|
|
|
(goto-char (match-beginning 1))
|
|
|
|
|
(message "Setting breakpoint for module %s" module)
|
|
|
|
|
(idlwave-shell-break-here))
|
|
|
|
|
(message "Cannot find module %s in file %s" module source-file)
|
|
|
|
|
(beep))))))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-up ()
|
|
|
|
|
"Run to end of current block.
|
|
|
|
|
Sets a breakpoint with count 1 at end of block, then continues."
|
|
|
|
|
(interactive)
|
|
|
|
|
(if (idlwave-shell-pc-frame)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(idlwave-shell-goto-frame)
|
|
|
|
|
;; find end of subprogram
|
|
|
|
|
(let ((eos (save-excursion
|
|
|
|
|
(idlwave-beginning-of-subprogram)
|
|
|
|
|
(idlwave-forward-block)
|
|
|
|
|
(point))))
|
|
|
|
|
(idlwave-backward-up-block -1)
|
|
|
|
|
;; move beyond end block line - IDL will not break there.
|
|
|
|
|
;; That is, you can put a breakpoint there but when IDL does
|
|
|
|
|
;; break it will report that it is at the next line.
|
|
|
|
|
(idlwave-next-statement)
|
|
|
|
|
(idlwave-end-of-statement)
|
|
|
|
|
;; Make sure we are not beyond subprogram
|
|
|
|
|
(if (< (point) eos)
|
|
|
|
|
;; okay
|
|
|
|
|
()
|
|
|
|
|
;; Move back inside subprogram
|
|
|
|
|
(goto-char eos)
|
|
|
|
|
(idlwave-previous-statement))
|
|
|
|
|
(idlwave-shell-to-here)))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-out ()
|
|
|
|
|
"Attempt to run until this procedure exits.
|
|
|
|
|
Runs to the last statement and then steps 1 statement. Use the .out command."
|
|
|
|
|
(interactive)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command ".o" nil (idlwave-shell-hide-p 'debug)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defun idlwave-shell-help-expression (arg)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"Print help on current expression. See `idlwave-shell-print'."
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(idlwave-shell-print arg 'help))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defmacro idlwave-shell-mouse-examine (help &optional ev)
|
|
|
|
|
"Create a function for generic examination of expressions."
|
|
|
|
|
`(lambda (event)
|
|
|
|
|
"Expansion function for expression examination."
|
|
|
|
|
(interactive "e")
|
|
|
|
|
(let ((transient-mark-mode t)
|
|
|
|
|
(zmacs-regions t)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(tracker (if (featurep 'xemacs) 'mouse-track
|
2002-07-18 18:58:07 +00:00
|
|
|
|
'mouse-drag-region)))
|
|
|
|
|
(funcall tracker event)
|
|
|
|
|
(idlwave-shell-print (if (idlwave-region-active-p) '(16) nil)
|
|
|
|
|
,help ,ev))))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-mouse-print (event)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
"Print value of variable at the mouse position, with `help'"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(interactive "e")
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(funcall (idlwave-shell-mouse-examine nil) event))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-mouse-help (event)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
"Print value of variable at the mouse position, with `print'."
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(interactive "e")
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(funcall (idlwave-shell-mouse-examine 'help) event))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-examine-select (event)
|
|
|
|
|
"Pop-up a list to select from for examining the expression"
|
|
|
|
|
(interactive "e")
|
|
|
|
|
(funcall (idlwave-shell-mouse-examine nil event) event))
|
|
|
|
|
|
|
|
|
|
(defmacro idlwave-shell-examine (help)
|
|
|
|
|
"Create a function for key-driven expression examination."
|
|
|
|
|
`(lambda ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-print nil ,help)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-define-key-both (key hook)
|
|
|
|
|
"Define a key in both the shell and buffer mode maps."
|
|
|
|
|
(define-key idlwave-mode-map key hook)
|
|
|
|
|
(define-key idlwave-shell-mode-map key hook))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-examine-label nil
|
|
|
|
|
"Label to include with examine text if separate.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-print (arg &optional help ev)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
"Print current expression.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
|
|
|
|
|
With HELP non-nil, show help on expression. If HELP is a string,
|
|
|
|
|
the expression will be put in place of ___, e.g.:
|
|
|
|
|
|
|
|
|
|
print,size(___,/DIMENSIONS)
|
|
|
|
|
|
|
|
|
|
Otherwise, print is called on the expression.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
An expression is an identifier plus 1 pair of matched parentheses
|
2002-07-18 18:58:07 +00:00
|
|
|
|
directly following the identifier - an array or function call.
|
|
|
|
|
Alternatively, an expression is the contents of any matched
|
|
|
|
|
parentheses when the open parenthesis is not directly preceded by an
|
2000-01-03 14:23:13 +00:00
|
|
|
|
identifier. If point is at the beginning or within an expression
|
|
|
|
|
return the inner-most containing expression, otherwise, return the
|
2000-06-20 12:49:47 +00:00
|
|
|
|
preceding expression.
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
With prefix arg ARG prompt for an expression.
|
|
|
|
|
|
|
|
|
|
With double prefix arg, use the current region.
|
|
|
|
|
|
|
|
|
|
If EV is a valid event passed, pop-up a list from
|
|
|
|
|
idlw-shell-examine-alist from which to select the help command text."
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(interactive "P")
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(save-excursion
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(let* ((process (get-buffer-process (current-buffer)))
|
|
|
|
|
(process-mark (if process (process-mark process)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(stack-label
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if (and (integerp idlwave-shell-calling-stack-index)
|
|
|
|
|
(> idlwave-shell-calling-stack-index 0))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(format " [-%d:%s]"
|
|
|
|
|
idlwave-shell-calling-stack-index
|
2002-07-18 18:58:07 +00:00
|
|
|
|
idlwave-shell-calling-stack-routine)))
|
|
|
|
|
expr beg end cmd examine-hook)
|
|
|
|
|
(cond
|
|
|
|
|
((and (equal arg '(16))
|
|
|
|
|
(< (- (region-end) (region-beginning)) 2000))
|
|
|
|
|
(setq beg (region-beginning)
|
|
|
|
|
end (region-end)))
|
|
|
|
|
(arg
|
|
|
|
|
(setq expr (read-string "Expression: ")))
|
|
|
|
|
(t
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-with-special-syntax
|
2000-12-11 12:45:42 +00:00
|
|
|
|
;; Move to beginning of current or previous expression
|
|
|
|
|
(if (looking-at "\\<\\|(")
|
|
|
|
|
;; At beginning of expression, don't move backwards unless
|
|
|
|
|
;; this is at the end of an indentifier.
|
|
|
|
|
(if (looking-at "\\>")
|
|
|
|
|
(backward-sexp))
|
|
|
|
|
(backward-sexp))
|
|
|
|
|
(if (looking-at "\\>")
|
|
|
|
|
;; Move to beginning of identifier - must be an array or
|
|
|
|
|
;; function expression.
|
|
|
|
|
(backward-sexp))
|
|
|
|
|
;; Move to end of expression
|
|
|
|
|
(setq beg (point))
|
|
|
|
|
(forward-sexp)
|
|
|
|
|
(while (looking-at "\\>[[(]\\|\\.")
|
|
|
|
|
;; an array
|
|
|
|
|
(forward-sexp))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(setq end (point)))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Get expression, but first move the begin mark if a
|
|
|
|
|
;; process-mark is inside the region, to keep the overlay from
|
|
|
|
|
;; wandering in the Shell.
|
|
|
|
|
(when (and beg end)
|
|
|
|
|
(if (and process-mark (> process-mark beg) (< process-mark end))
|
|
|
|
|
(setq beg (marker-position process-mark)))
|
|
|
|
|
(setq expr (buffer-substring beg end)))
|
|
|
|
|
|
|
|
|
|
;; Show the overlay(s) and attach any necessary hooks and filters
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(when (and beg end idlwave-shell-expression-overlay)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(move-overlay idlwave-shell-expression-overlay beg end
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(current-buffer))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(add-hook 'pre-command-hook
|
2002-07-18 18:58:07 +00:00
|
|
|
|
'idlwave-shell-delete-expression-overlay))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq examine-hook
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if idlwave-shell-separate-examine-output
|
|
|
|
|
'idlwave-shell-examine-display
|
|
|
|
|
'idlwave-shell-examine-highlight))
|
|
|
|
|
(add-hook 'pre-command-hook
|
|
|
|
|
'idlwave-shell-delete-output-overlay)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Remove empty or comment-only lines
|
|
|
|
|
(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)
|
|
|
|
|
(setq expr (replace-match "" t t expr)))
|
|
|
|
|
;; Remove final newline
|
|
|
|
|
(if (string-match "\n[ \t\r]*\\'" expr)
|
|
|
|
|
(setq expr (replace-match "" t t expr)))
|
|
|
|
|
;; Pop-up the examine selection list, if appropriate
|
|
|
|
|
(if (and ev idlwave-shell-examine-alist)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(let* ((help-cons
|
|
|
|
|
(assoc
|
|
|
|
|
(idlwave-popup-select
|
2002-07-18 18:58:07 +00:00
|
|
|
|
ev (mapcar 'car idlwave-shell-examine-alist)
|
|
|
|
|
"Examine with")
|
|
|
|
|
idlwave-shell-examine-alist)))
|
|
|
|
|
(setq help (cdr help-cons))
|
|
|
|
|
(if idlwave-shell-separate-examine-output
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq idlwave-shell-examine-label
|
|
|
|
|
(concat
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(format "==>%s<==\n%s:" expr (car help-cons))
|
|
|
|
|
stack-label "\n"))))
|
|
|
|
|
(setq idlwave-shell-examine-label
|
|
|
|
|
(concat
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(format "==>%s<==\n%s:" expr
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(cond ((null help) "print")
|
|
|
|
|
((stringp help) help)
|
|
|
|
|
(t (symbol-name help))))
|
|
|
|
|
stack-label "\n")))
|
|
|
|
|
|
|
|
|
|
;; Send the command
|
|
|
|
|
(if stack-label
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(setq cmd (idlwave-retrieve-expression-from-level
|
|
|
|
|
expr
|
|
|
|
|
idlwave-shell-calling-stack-index
|
|
|
|
|
idlwave-shell-calling-stack-routine
|
|
|
|
|
help))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(setq cmd (idlwave-shell-help-statement help expr)))
|
|
|
|
|
;(idlwave-shell-recenter-shell-window)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
|
|
|
|
cmd
|
|
|
|
|
examine-hook
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if idlwave-shell-separate-examine-output 'hide)))))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-examine-window-alist nil
|
|
|
|
|
"Variable to hold the win/height pairs for all *Examine* windows.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-examine-display ()
|
|
|
|
|
"View the examine command output in a separate buffer."
|
|
|
|
|
(let (win cur-beg cur-end)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (get-buffer-create "*Examine*"))
|
|
|
|
|
(use-local-map idlwave-shell-examine-map)
|
|
|
|
|
(setq buffer-read-only nil)
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region (point) (point))
|
|
|
|
|
(if (string-match "^% Syntax error." idlwave-shell-command-output)
|
|
|
|
|
(insert "% Syntax error.\n")
|
|
|
|
|
(insert idlwave-shell-command-output)
|
|
|
|
|
;; Just take the last bit between the prompts (if more than one).
|
|
|
|
|
(let* ((end (or
|
|
|
|
|
(re-search-backward idlwave-shell-prompt-pattern nil t)
|
|
|
|
|
(point-max)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(beg (progn
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(goto-char
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(or (progn (if (re-search-backward
|
2002-07-18 18:58:07 +00:00
|
|
|
|
idlwave-shell-prompt-pattern nil t)
|
|
|
|
|
(match-end 0)))
|
|
|
|
|
(point-min)))
|
|
|
|
|
(re-search-forward "\n")))
|
|
|
|
|
(str (buffer-substring beg end)))
|
|
|
|
|
(delete-region (point-min) (point-max))
|
|
|
|
|
(insert str)
|
|
|
|
|
(if idlwave-shell-examine-label
|
|
|
|
|
(progn (goto-char (point-min))
|
|
|
|
|
(insert idlwave-shell-examine-label)
|
|
|
|
|
(setq idlwave-shell-examine-label nil)))))
|
|
|
|
|
(setq cur-beg (point-min)
|
|
|
|
|
cur-end (point-max))
|
|
|
|
|
(setq buffer-read-only t)
|
|
|
|
|
(move-overlay idlwave-shell-output-overlay cur-beg cur-end
|
|
|
|
|
(current-buffer))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Look for the examine buffer in all windows. If one is
|
|
|
|
|
;; found in a frame all by itself, use that, otherwise, switch
|
|
|
|
|
;; to or create an examine window in this frame, and resize if
|
|
|
|
|
;; it's a newly created window
|
|
|
|
|
(let* ((winlist (get-buffer-window-list "*Examine*" nil 'visible)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq win (idlwave-display-buffer
|
|
|
|
|
"*Examine*"
|
2002-07-18 18:58:07 +00:00
|
|
|
|
nil
|
|
|
|
|
(let ((list winlist) thiswin)
|
|
|
|
|
(catch 'exit
|
|
|
|
|
(save-selected-window
|
|
|
|
|
(while (setq thiswin (pop list))
|
|
|
|
|
(select-window thiswin)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (one-window-p)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(throw 'exit (window-frame thiswin)))))))))
|
|
|
|
|
(set-window-start win (point-min)) ; Ensure the point is visible.
|
|
|
|
|
(save-selected-window
|
|
|
|
|
(select-window win)
|
|
|
|
|
(let ((elt (assoc win idlwave-shell-examine-window-alist)))
|
|
|
|
|
(when (and (not (one-window-p))
|
|
|
|
|
(or (not (memq win winlist)) ;a newly created window
|
|
|
|
|
(eq (window-height) (cdr elt))))
|
|
|
|
|
;; Autosize it.
|
|
|
|
|
(enlarge-window (- (/ (frame-height) 2)
|
|
|
|
|
(window-height)))
|
|
|
|
|
(shrink-window-if-larger-than-buffer)
|
|
|
|
|
;; Clean the window list of dead windows
|
|
|
|
|
(setq idlwave-shell-examine-window-alist
|
|
|
|
|
(delq nil
|
|
|
|
|
(mapcar (lambda (x) (if (window-live-p (car x)) x))
|
|
|
|
|
idlwave-shell-examine-window-alist)))
|
|
|
|
|
;; And add the new value.
|
|
|
|
|
(if (setq elt (assoc win idlwave-shell-examine-window-alist))
|
|
|
|
|
(setcdr elt (window-height))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(add-to-list 'idlwave-shell-examine-window-alist
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(cons win (window-height)))))))))
|
|
|
|
|
;; Recenter for maximum output, after widened
|
|
|
|
|
(save-selected-window
|
|
|
|
|
(select-window win)
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(skip-chars-backward "\n")
|
|
|
|
|
(recenter -1)))))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-examine-map (make-sparse-keymap))
|
|
|
|
|
(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-examine-display-quit ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((win (selected-window)))
|
|
|
|
|
(if (one-window-p)
|
|
|
|
|
(delete-frame (window-frame win))
|
|
|
|
|
(delete-window win))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-examine-display-clear ()
|
|
|
|
|
(interactive)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(save-excursion
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(let ((buf (get-buffer "*Examine*")))
|
|
|
|
|
(when (bufferp buf)
|
|
|
|
|
(set-buffer buf)
|
|
|
|
|
(setq buffer-read-only nil)
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(setq buffer-read-only t)))))
|
2000-02-04 10:10:40 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-retrieve-expression-from-level (expr level routine help)
|
|
|
|
|
"Return IDL command to print the expression EXPR from stack level LEVEL.
|
|
|
|
|
|
|
|
|
|
It does not seem possible to evaluate an expression on a differnt
|
|
|
|
|
level than the current. Therefore, this function retrieves *copies* of
|
|
|
|
|
the variables involved in the expression from the desired level in the
|
|
|
|
|
calling stack. The copies are given some unlikely names on the
|
|
|
|
|
*current* level, and the expression is then evaluated on the *current*
|
|
|
|
|
level.
|
|
|
|
|
|
|
|
|
|
Since this function depends upon the undocumented IDL routine routine_names,
|
2002-07-18 18:58:07 +00:00
|
|
|
|
there is no guarantee that this will work with future versions of IDL."
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(let ((prefix "___") ;; No real variables should starts with this.
|
|
|
|
|
(fetch (- 0 level))
|
|
|
|
|
(start 0)
|
|
|
|
|
var tvar fetch-vars pre post)
|
|
|
|
|
|
|
|
|
|
;; FIXME: In the following we try to find the variables in expression
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; This is quite empirical - I don't know in what situations this will
|
|
|
|
|
;; break. We will look for identifiers and exclude cases where we
|
|
|
|
|
;; know it is not a variable. To distinguish array references from
|
|
|
|
|
;; function calls, we require that arrays use [] instead of ()
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(while (string-match
|
|
|
|
|
"\\(\\`\\|[^a-zA-Z0-9$_]\\)\\([a-zA-Z][a-zA-Z0-9$_]*\\)\\([^a-zA-Z0-9$_]\\|\\'\\)" expr start)
|
|
|
|
|
(setq var (match-string 2 expr)
|
|
|
|
|
tvar (concat prefix var)
|
|
|
|
|
start (match-beginning 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
|
|
|
|
|
(t ;; seems to be a variable - arrange to get it and replace
|
|
|
|
|
;; its name in the expression with the temproary name.
|
|
|
|
|
(push (cons var tvar) fetch-vars)
|
|
|
|
|
(setq expr (concat pre tvar post))))
|
|
|
|
|
(if (= start 0) (setq start 1)))
|
2000-02-04 10:10:40 +00:00
|
|
|
|
;; Make a command line that first copies the relevant variables
|
|
|
|
|
;; and then prints the expression.
|
|
|
|
|
(concat
|
|
|
|
|
(mapconcat
|
|
|
|
|
(lambda (x)
|
|
|
|
|
(format "%s = routine_names('%s',fetch=%d)" (cdr x) (car x) fetch))
|
|
|
|
|
(nreverse fetch-vars)
|
|
|
|
|
" & ")
|
2002-07-18 18:58:07 +00:00
|
|
|
|
"\n"
|
|
|
|
|
(idlwave-shell-help-statement help expr)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(format " ; [-%d:%s]" level routine))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defun idlwave-shell-help-statement (help expr)
|
|
|
|
|
"Construct a help statement for printing expression EXPR.
|
|
|
|
|
|
|
|
|
|
HELP can be non-nil for `help,', nil for 'print,' or any string into which
|
|
|
|
|
to insert expression in place of the marker ___, e.g.: print,
|
|
|
|
|
size(___,/DIMENSIONS)"
|
|
|
|
|
(cond
|
|
|
|
|
((null help) (concat "print, " expr))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
((stringp help)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if (string-match "\\(^\\|[^_]\\)\\(___\\)\\([^_]\\|$\\)" help)
|
|
|
|
|
(concat (substring help 0 (match-beginning 2))
|
|
|
|
|
expr
|
|
|
|
|
(substring help (match-end 2)))))
|
|
|
|
|
(t (concat "help, " expr))))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-examine-highlight ()
|
|
|
|
|
"Highlight the most recent IDL output."
|
|
|
|
|
(let* ((buffer (get-buffer (idlwave-shell-buffer)))
|
|
|
|
|
(process (get-buffer-process buffer))
|
|
|
|
|
(process-mark (if process (process-mark process)))
|
|
|
|
|
output-begin output-end)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(save-excursion
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(set-buffer buffer)
|
|
|
|
|
(goto-char process-mark)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(setq output-end (point))
|
|
|
|
|
(re-search-backward idlwave-shell-prompt-pattern nil t)
|
|
|
|
|
(beginning-of-line 2)
|
|
|
|
|
(setq output-begin (point)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; First make sure the shell window is visible
|
|
|
|
|
(idlwave-display-buffer (idlwave-shell-buffer)
|
|
|
|
|
nil (idlwave-shell-shell-frame))
|
|
|
|
|
(if (and idlwave-shell-output-overlay process-mark)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(move-overlay idlwave-shell-output-overlay
|
2002-07-18 18:58:07 +00:00
|
|
|
|
output-begin output-end buffer))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-delete-output-overlay ()
|
|
|
|
|
(if (eq this-command 'idlwave-shell-mouse-nop)
|
|
|
|
|
nil
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(if idlwave-shell-output-overlay
|
|
|
|
|
(delete-overlay idlwave-shell-output-overlay))
|
|
|
|
|
(error nil))
|
|
|
|
|
(remove-hook 'pre-command-hook 'idlwave-shell-delete-output-overlay)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-delete-expression-overlay ()
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if (eq this-command 'idlwave-shell-mouse-nop)
|
|
|
|
|
nil
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(if idlwave-shell-expression-overlay
|
|
|
|
|
(delete-overlay idlwave-shell-expression-overlay))
|
|
|
|
|
(error nil))
|
|
|
|
|
(remove-hook 'pre-command-hook 'idlwave-shell-delete-expression-overlay)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-bp-alist nil
|
|
|
|
|
"Alist of breakpoints.
|
|
|
|
|
A breakpoint is a cons cell \(\(file line\) . \(\(index module\) data\)\)
|
|
|
|
|
|
|
|
|
|
The car is the frame for the breakpoint:
|
|
|
|
|
file - full path file name.
|
|
|
|
|
line - line number of breakpoint - integer.
|
|
|
|
|
|
|
|
|
|
The first element of the cdr is a list of internal IDL data:
|
|
|
|
|
index - the index number of the breakpoint internal to IDL.
|
|
|
|
|
module - the module for breakpoint internal to IDL.
|
|
|
|
|
|
|
|
|
|
Remaining elements of the cdr:
|
|
|
|
|
data - Data associated with the breakpoint by idlwave-shell currently
|
|
|
|
|
contains two items:
|
|
|
|
|
|
|
|
|
|
count - number of times to execute breakpoint. When count reaches 0
|
|
|
|
|
the breakpoint is cleared and removed from the alist.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
command - command to execute when breakpoint is reached, either a
|
2000-01-03 14:23:13 +00:00
|
|
|
|
lisp function to be called with `funcall' with no arguments or a
|
|
|
|
|
list to be evaluated with `eval'.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-run-region (beg end &optional n)
|
|
|
|
|
"Compile and run the region using the IDL process.
|
|
|
|
|
Copies the region to a temporary file `idlwave-shell-temp-pro-file'
|
|
|
|
|
and issues the IDL .run command for the file. Because the
|
|
|
|
|
region is compiled and run as a main program there is no
|
|
|
|
|
problem with begin-end blocks extending over multiple
|
|
|
|
|
lines - which would be a problem if `idlwave-shell-evaluate-region'
|
|
|
|
|
was used. An END statement is appended to the region if necessary.
|
|
|
|
|
|
|
|
|
|
If there is a prefix argument, display IDL process."
|
|
|
|
|
(interactive "r\nP")
|
|
|
|
|
(let ((oldbuf (current-buffer)))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (idlwave-find-file-noselect
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(idlwave-shell-temp-file 'pro) 'tmp))
|
|
|
|
|
(set (make-local-variable 'comment-start-skip) ";+[ \t]*")
|
|
|
|
|
(set (make-local-variable 'comment-start) ";")
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(erase-buffer)
|
|
|
|
|
(insert-buffer-substring oldbuf beg end)
|
|
|
|
|
(if (not (save-excursion
|
|
|
|
|
(idlwave-previous-statement)
|
|
|
|
|
(idlwave-look-at "\\<end\\>")))
|
|
|
|
|
(insert "\nend\n"))
|
|
|
|
|
(save-buffer 0)))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-send-command (concat ".run " idlwave-shell-temp-pro-file)
|
|
|
|
|
nil (idlwave-shell-hide-p 'run))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(if n
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-display-buffer (idlwave-shell-buffer)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
nil (idlwave-shell-shell-frame))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-evaluate-region (beg end &optional n)
|
|
|
|
|
"Send region to the IDL process.
|
|
|
|
|
If there is a prefix argument, display IDL process.
|
|
|
|
|
Does not work for a region with multiline blocks - use
|
|
|
|
|
`idlwave-shell-run-region' for this."
|
|
|
|
|
(interactive "r\nP")
|
|
|
|
|
(idlwave-shell-send-command (buffer-substring beg end))
|
|
|
|
|
(if n
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-display-buffer (idlwave-shell-buffer)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
nil (idlwave-shell-shell-frame))))
|
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defun idlwave-shell-delete-temp-files ()
|
|
|
|
|
"Delete the temporary files and kill associated buffers."
|
|
|
|
|
(if (stringp idlwave-shell-temp-pro-file)
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(let ((buf (idlwave-get-buffer-visiting
|
|
|
|
|
idlwave-shell-temp-pro-file)))
|
|
|
|
|
(if (buffer-live-p buf)
|
|
|
|
|
(kill-buffer buf))
|
|
|
|
|
(delete-file idlwave-shell-temp-pro-file))
|
|
|
|
|
(error nil)))
|
|
|
|
|
(if (stringp idlwave-shell-temp-rinfo-save-file)
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(delete-file idlwave-shell-temp-rinfo-save-file)
|
|
|
|
|
(error nil))))
|
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-display-buffer (buf not-this-window-p &optional frame)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(if (featurep 'xemacs)
|
|
|
|
|
;; The XEmacs version enforces the frame
|
|
|
|
|
(display-buffer buf not-this-window-p frame)
|
|
|
|
|
;; For Emacs, we need to force the frame ourselves.
|
|
|
|
|
(let ((this-frame (selected-frame)))
|
|
|
|
|
(if (frame-live-p frame)
|
|
|
|
|
(select-frame frame))
|
|
|
|
|
(if (eq this-frame (selected-frame))
|
|
|
|
|
;; same frame: use display buffer, to make sure the current
|
|
|
|
|
;; window stays.
|
|
|
|
|
(display-buffer buf)
|
|
|
|
|
;; different frame
|
|
|
|
|
(if (one-window-p)
|
|
|
|
|
;; only window: switch
|
|
|
|
|
(progn
|
|
|
|
|
(switch-to-buffer buf)
|
|
|
|
|
(selected-window)) ; must return the window.
|
|
|
|
|
;; several windows - use display-buffer
|
|
|
|
|
(display-buffer buf not-this-window-p))))))
|
|
|
|
|
; (if (not (frame-live-p frame)) (setq frame nil))
|
|
|
|
|
; (display-buffer buf not-this-window-p frame))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(defvar idlwave-shell-bp-buffer " *idlwave-shell-bp*"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"Scratch buffer for parsing IDL breakpoint lists and other stuff.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-bp-query ()
|
|
|
|
|
"Reconcile idlwave-shell's breakpoint list with IDL's.
|
|
|
|
|
Queries IDL using the string in `idlwave-shell-bp-query'."
|
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-send-command idlwave-shell-bp-query
|
|
|
|
|
'idlwave-shell-filter-bp
|
|
|
|
|
'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, or 'data.
|
|
|
|
|
'data returns a list of 'count and 'cmd.
|
|
|
|
|
Defaults to 'index."
|
|
|
|
|
(cond
|
|
|
|
|
;; Frame
|
|
|
|
|
((eq item 'line) (nth 1 (car bp)))
|
|
|
|
|
((eq item 'file) (nth 0 (car bp)))
|
|
|
|
|
;; idlwave-shell breakpoint data
|
|
|
|
|
((eq item 'data) (cdr (cdr bp)))
|
|
|
|
|
((eq item 'count) (nth 0 (cdr (cdr bp))))
|
|
|
|
|
((eq item 'cmd) (nth 1 (cdr (cdr bp))))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
((eq item 'condition) (nth 2 (cdr (cdr bp))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; IDL breakpoint info
|
|
|
|
|
((eq item 'module) (nth 1 (car (cdr bp))))
|
|
|
|
|
;; index - default
|
|
|
|
|
(t (nth 0 (car (cdr bp))))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-filter-bp ()
|
|
|
|
|
"Get the breakpoints from `idlwave-shell-command-output'.
|
|
|
|
|
Create `idlwave-shell-bp-alist' updating breakpoint count and command data
|
|
|
|
|
from previous breakpoint list."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (get-buffer-create idlwave-shell-bp-buffer))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(insert idlwave-shell-command-output)
|
|
|
|
|
(goto-char (point-min))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(let ((old-bp-alist idlwave-shell-bp-alist)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Searching the breakpoints
|
|
|
|
|
;; In IDL 5.5, the breakpoint reporting format changed.
|
|
|
|
|
(bp-re54 "^[ \t]*\\([0-9]+\\)[ \t]+\\(\\S-+\\)?[ \t]+\\([0-9]+\\)[ \t]+\\(\\S-+\\)")
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(bp-re55 "^\\s-*\\([0-9]+\\)\\s-+\\([0-9]+\\)\\s-+\\(Uncompiled\\|Func=\\|Pro=\\)\\([a-zA-Z][a-zA-Z0-9$_:]*\\)\\(,[^\n]*\n\\)?\\s-+\\(\\S-+\\)")
|
2002-10-17 15:41:01 +00:00
|
|
|
|
file line index module
|
2002-07-18 18:58:07 +00:00
|
|
|
|
bp-re indmap)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-bp-alist (list nil))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; Search for either header type, and set the correct regexp
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(when (or
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if (re-search-forward "^\\s-*Index.*\n\\s-*-" nil t)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq bp-re bp-re54 ; versions <= 5.4
|
2002-07-18 18:58:07 +00:00
|
|
|
|
indmap '(1 2 3 4)))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (re-search-forward
|
2002-07-18 18:58:07 +00:00
|
|
|
|
"^\\s-*Index\\s-*Line\\s-*Attributes\\s-*File" nil t)
|
|
|
|
|
(setq bp-re bp-re55 ; versions >= 5.5
|
2002-09-12 17:24:53 +00:00
|
|
|
|
indmap '(1 4 2 6))))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; There seems to be a breakpoint listing here.
|
|
|
|
|
;; Parse breakpoint lines.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; Breakpoints have the form
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; for IDL<=v5.4:
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; Index Module Line File
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; All separated by whitespace.
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; Module may be missing if the file is not compiled.
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; for IDL>=v5.5:
|
|
|
|
|
;; Index Line Attributes File
|
|
|
|
|
;; (attributes replaces module, "Uncompiled" included)
|
|
|
|
|
(while (re-search-forward bp-re nil t)
|
|
|
|
|
(setq index (match-string (nth 0 indmap))
|
|
|
|
|
module (match-string (nth 1 indmap))
|
|
|
|
|
line (string-to-int (match-string (nth 2 indmap)))
|
|
|
|
|
file (idlwave-shell-file-name (match-string (nth 3 indmap))))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
;; Add the breakpoint info to the list
|
|
|
|
|
(nconc idlwave-shell-bp-alist
|
|
|
|
|
(list (cons (list file line)
|
|
|
|
|
(list
|
|
|
|
|
(list index module)
|
|
|
|
|
;; idlwave-shell data: count, command
|
|
|
|
|
nil nil))))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-bp-alist (cdr idlwave-shell-bp-alist))
|
|
|
|
|
;; Update count, commands of breakpoints
|
|
|
|
|
(mapcar 'idlwave-shell-update-bp old-bp-alist)))
|
|
|
|
|
;; Update the breakpoint overlays
|
|
|
|
|
(idlwave-shell-update-bp-overlays)
|
|
|
|
|
;; Return the new list
|
|
|
|
|
idlwave-shell-bp-alist)
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-update-bp (bp)
|
|
|
|
|
"Update BP data in breakpoint list.
|
|
|
|
|
If BP frame is in `idlwave-shell-bp-alist' updates the breakpoint data."
|
|
|
|
|
(let ((match (assoc (car bp) idlwave-shell-bp-alist)))
|
|
|
|
|
(if match (setcdr (cdr match) (cdr (cdr bp))))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-set-bp-data (bp data)
|
|
|
|
|
"Set the data of BP to DATA."
|
|
|
|
|
(setcdr (cdr bp) data))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-bp (frame &optional data module)
|
|
|
|
|
"Create a breakpoint structure containing FRAME and DATA. Second
|
|
|
|
|
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)))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-old-bp nil
|
|
|
|
|
"List of breakpoints previous to setting a new breakpoint.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-sources-bp (bp)
|
|
|
|
|
"Check `idlwave-shell-sources-alist' for source of breakpoint using BP.
|
|
|
|
|
If an equivalency is found, return the IDL internal source name.
|
|
|
|
|
Otherwise return the filename in bp."
|
|
|
|
|
(let*
|
|
|
|
|
((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 (and internal-file-list
|
|
|
|
|
(equal bp-file (nth 0 internal-file-list)))
|
|
|
|
|
(nth 1 internal-file-list)
|
|
|
|
|
bp-file)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-set-bp (bp)
|
|
|
|
|
"Try to set a breakpoint BP.
|
|
|
|
|
|
|
|
|
|
The breakpoint will be placed at the beginning of the statement on the
|
|
|
|
|
line specified by BP or at the next IDL statement if that line is not
|
|
|
|
|
a statement.
|
2002-09-12 17:24:53 +00:00
|
|
|
|
Determines IDL's internal representation for the breakpoint which may
|
2002-10-17 15:41:01 +00:00
|
|
|
|
have occurred at a different line then used with the breakpoint
|
2000-01-03 14:23:13 +00:00
|
|
|
|
command."
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; Get and save the old breakpoints
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(idlwave-shell-send-command
|
2000-01-03 14:23:13 +00:00
|
|
|
|
idlwave-shell-bp-query
|
|
|
|
|
'(progn
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(idlwave-shell-filter-bp)
|
|
|
|
|
(setq idlwave-shell-old-bp idlwave-shell-bp-alist))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
'hide)
|
|
|
|
|
;; Get sources for IDL compiled procedures followed by setting
|
|
|
|
|
;; breakpoint.
|
|
|
|
|
(idlwave-shell-send-command
|
|
|
|
|
idlwave-shell-sources-query
|
2001-11-27 15:52:52 +00:00
|
|
|
|
`(progn
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(idlwave-shell-sources-filter)
|
|
|
|
|
(idlwave-shell-set-bp2 (quote ,bp)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
'hide))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-set-bp2 (bp)
|
|
|
|
|
"Use results of breakpoint and sources query to set bp.
|
|
|
|
|
Use the count argument with IDLs breakpoint command.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
We treat a count of 1 as a temporary breakpoint.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
Counts greater than 1 use the IDL AFTER=count keyword to break
|
|
|
|
|
only after reaching the statement count times."
|
|
|
|
|
(let*
|
|
|
|
|
((arg (idlwave-shell-bp-get bp 'count))
|
|
|
|
|
(key (cond
|
2001-11-27 15:52:52 +00:00
|
|
|
|
((not (and arg (numberp arg))) "")
|
|
|
|
|
((= arg 1)
|
|
|
|
|
",/once")
|
|
|
|
|
((> arg 1)
|
|
|
|
|
(format ",after=%d" arg))))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(condition (idlwave-shell-bp-get bp 'condition))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(key (concat key
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(if condition (concat ",CONDITION=\"" condition "\""))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(line (idlwave-shell-bp-get bp 'line)))
|
|
|
|
|
(idlwave-shell-send-command
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(concat "breakpoint,'"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(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
|
2001-11-27 15:52:52 +00:00
|
|
|
|
`(progn
|
|
|
|
|
(if (idlwave-shell-set-bp-check (quote ,bp))
|
|
|
|
|
(idlwave-shell-set-bp3 (quote ,bp))))
|
2002-09-12 17:24:53 +00:00
|
|
|
|
;; hide output?
|
|
|
|
|
(idlwave-shell-hide-p 'breakpoint)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
'preempt)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-set-bp3 (bp)
|
|
|
|
|
"Find the breakpoint in IDL's internal list of breakpoints."
|
|
|
|
|
(idlwave-shell-send-command idlwave-shell-bp-query
|
2001-11-27 15:52:52 +00:00
|
|
|
|
`(progn
|
|
|
|
|
(idlwave-shell-filter-bp)
|
|
|
|
|
(idlwave-shell-new-bp (quote ,bp)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
'hide
|
|
|
|
|
'preempt))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-find-bp (frame)
|
|
|
|
|
"Return breakpoint from `idlwave-shell-bp-alist' for frame.
|
|
|
|
|
Returns nil if frame not found."
|
|
|
|
|
(assoc frame idlwave-shell-bp-alist))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-new-bp (bp)
|
|
|
|
|
"Find the new breakpoint in IDL's list and update with DATA.
|
|
|
|
|
The actual line number for a breakpoint in IDL may be different than
|
|
|
|
|
the line number used with the IDL breakpoint command.
|
|
|
|
|
Looks for a new breakpoint index number in the list. This is
|
|
|
|
|
considered the new breakpoint if the file name of frame matches."
|
|
|
|
|
(let ((obp-index (mapcar 'idlwave-shell-bp-get idlwave-shell-old-bp))
|
|
|
|
|
(bpl idlwave-shell-bp-alist))
|
|
|
|
|
(while (and (member (idlwave-shell-bp-get (car bpl)) obp-index)
|
|
|
|
|
(setq bpl (cdr bpl))))
|
|
|
|
|
(if (and
|
|
|
|
|
(not bpl)
|
|
|
|
|
;; No additional breakpoint.
|
|
|
|
|
;; Need to check if we are just replacing a breakpoint.
|
|
|
|
|
(setq bpl (assoc (car bp) idlwave-shell-bp-alist)))
|
|
|
|
|
(setq bpl (list bpl)))
|
|
|
|
|
(if (and bpl
|
|
|
|
|
(equal (idlwave-shell-bp-get (setq bpl (car bpl)) 'file)
|
|
|
|
|
(idlwave-shell-bp-get bp 'file)))
|
|
|
|
|
;; Got the breakpoint - add count, command to it.
|
|
|
|
|
;; This updates `idlwave-shell-bp-alist' because a deep copy was
|
|
|
|
|
;; not done for bpl.
|
|
|
|
|
(idlwave-shell-set-bp-data bpl (idlwave-shell-bp-get bp 'data))
|
|
|
|
|
(beep)
|
|
|
|
|
(message "Failed to identify breakpoint in IDL"))))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-bp-overlays nil
|
|
|
|
|
"List of overlays marking breakpoints")
|
|
|
|
|
|
|
|
|
|
(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."
|
|
|
|
|
(when idlwave-shell-mark-breakpoints
|
|
|
|
|
(let ((bp-list idlwave-shell-bp-alist)
|
|
|
|
|
(ov-list idlwave-shell-bp-overlays)
|
|
|
|
|
ov bp)
|
|
|
|
|
;; Delete the old overlays from their buffers
|
|
|
|
|
(while (setq ov (pop ov-list))
|
|
|
|
|
(delete-overlay ov))
|
|
|
|
|
(setq ov-list idlwave-shell-bp-overlays
|
|
|
|
|
idlwave-shell-bp-overlays nil)
|
|
|
|
|
(while (setq bp (pop bp-list))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(idlwave-shell-goto-frame (car bp))
|
|
|
|
|
(let* ((end (progn (end-of-line 1) (point)))
|
|
|
|
|
(beg (progn (beginning-of-line 1) (point)))
|
|
|
|
|
(ov (or (pop ov-list)
|
|
|
|
|
(idlwave-shell-make-new-bp-overlay))))
|
|
|
|
|
(move-overlay ov beg end)
|
|
|
|
|
(push ov idlwave-shell-bp-overlays)))))))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-bp-glyph)
|
|
|
|
|
(defun idlwave-shell-make-new-bp-overlay ()
|
|
|
|
|
"Make a new overlay for highlighting breakpoints.
|
|
|
|
|
This stuff is stringly dependant upon the version of Emacs."
|
|
|
|
|
(let ((ov (make-overlay 1 1)))
|
|
|
|
|
(if (featurep 'xemacs)
|
|
|
|
|
;; This is XEmacs
|
|
|
|
|
(progn
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(cond
|
2000-01-03 14:23:13 +00:00
|
|
|
|
((eq (console-type) 'tty)
|
|
|
|
|
;; tty's cannot display glyphs
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(set-extent-property ov 'face idlwave-shell-breakpoint-face))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
((and (memq idlwave-shell-mark-breakpoints '(t glyph))
|
|
|
|
|
idlwave-shell-bp-glyph)
|
|
|
|
|
;; use the glyph
|
|
|
|
|
(set-extent-property ov 'begin-glyph idlwave-shell-bp-glyph))
|
|
|
|
|
(idlwave-shell-mark-breakpoints
|
|
|
|
|
;; use the face
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(set-extent-property ov 'face idlwave-shell-breakpoint-face))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(t
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; no marking
|
|
|
|
|
nil))
|
|
|
|
|
(set-extent-priority ov -1)) ; make stop line face prevail
|
|
|
|
|
;; This is Emacs
|
|
|
|
|
(cond
|
|
|
|
|
(window-system
|
|
|
|
|
(if (and (memq idlwave-shell-mark-breakpoints '(t glyph))
|
|
|
|
|
idlwave-shell-bp-glyph) ; this var knows if glyph's possible
|
|
|
|
|
;; use a glyph
|
|
|
|
|
(let ((string "@"))
|
|
|
|
|
(put-text-property 0 1
|
2000-02-04 10:10:40 +00:00
|
|
|
|
'display idlwave-shell-bp-glyph
|
2000-01-03 14:23:13 +00:00
|
|
|
|
string)
|
|
|
|
|
(overlay-put ov 'before-string string))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(overlay-put ov 'face idlwave-shell-breakpoint-face)))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-mark-breakpoints
|
|
|
|
|
;; use a face
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(overlay-put ov 'face idlwave-shell-breakpoint-face))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(t
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; No marking
|
|
|
|
|
nil)))
|
|
|
|
|
ov))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-edit-default-command-line (arg)
|
|
|
|
|
"Edit the current execute command."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq idlwave-shell-command-line-to-execute
|
|
|
|
|
(read-string "IDL> " idlwave-shell-command-line-to-execute)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-execute-default-command-line (arg)
|
|
|
|
|
"Execute a command line. On first use, ask for the command.
|
|
|
|
|
Also with prefix arg, ask for the command. You can also uase the command
|
|
|
|
|
`idlwave-shell-edit-default-command-line' to edit the line."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (or (not idlwave-shell-command-line-to-execute)
|
|
|
|
|
arg)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(setq idlwave-shell-command-line-to-execute
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(read-string "IDL> " idlwave-shell-command-line-to-execute)))
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(idlwave-shell-reset 'hidden)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-send-command idlwave-shell-command-line-to-execute
|
|
|
|
|
'(idlwave-shell-redisplay 'hide)))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-save-and-run ()
|
|
|
|
|
"Save file and run it in IDL.
|
|
|
|
|
Runs `save-buffer' and sends a '.RUN' command for the associated file to IDL.
|
|
|
|
|
When called from the shell buffer, re-run the file which was last handled by
|
2002-10-17 15:41:01 +00:00
|
|
|
|
one of the save-and-.. commands."
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-save-and-action 'run))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-save-and-compile ()
|
|
|
|
|
"Save file and run it in IDL.
|
|
|
|
|
Runs `save-buffer' and sends '.COMPILE' command for the associated file to IDL.
|
|
|
|
|
When called from the shell buffer, re-compile the file which was last handled by
|
|
|
|
|
one of the save-and-.. commands."
|
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-save-and-action 'compile))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-save-and-batch ()
|
|
|
|
|
"Save file and batch it in IDL.
|
|
|
|
|
Runs `save-buffer' and sends a '@file' command for the associated file to IDL.
|
|
|
|
|
When called from the shell buffer, re-batch the file which was last handled by
|
2002-10-17 15:41:01 +00:00
|
|
|
|
one of the save-and-.. commands."
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-save-and-action 'batch))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-save-and-action (action)
|
|
|
|
|
"Save file and compile it in IDL.
|
|
|
|
|
Runs `save-buffer' and sends a '.RUN' command for the associated file to IDL.
|
|
|
|
|
When called from the shell buffer, re-compile the file which was last
|
|
|
|
|
handled by this command."
|
|
|
|
|
;; Remove the stop overlay.
|
|
|
|
|
(if idlwave-shell-stop-line-overlay
|
|
|
|
|
(delete-overlay idlwave-shell-stop-line-overlay))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq idlwave-shell-is-stopped nil)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq overlay-arrow-string nil)
|
|
|
|
|
(let (buf)
|
|
|
|
|
(cond
|
|
|
|
|
((eq major-mode 'idlwave-mode)
|
|
|
|
|
(save-buffer)
|
|
|
|
|
(setq idlwave-shell-last-save-and-action-file (buffer-file-name)))
|
|
|
|
|
(idlwave-shell-last-save-and-action-file
|
|
|
|
|
(if (setq buf (idlwave-get-buffer-visiting
|
|
|
|
|
idlwave-shell-last-save-and-action-file))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer buf)
|
|
|
|
|
(save-buffer))))
|
|
|
|
|
(t (setq idlwave-shell-last-save-and-action-file
|
|
|
|
|
(read-file-name "File: ")))))
|
|
|
|
|
(if (file-regular-p idlwave-shell-last-save-and-action-file)
|
|
|
|
|
(progn
|
|
|
|
|
(idlwave-shell-send-command
|
|
|
|
|
(concat (cond ((eq action 'run) ".run ")
|
|
|
|
|
((eq action 'compile) ".compile ")
|
|
|
|
|
((eq action 'batch) "@")
|
|
|
|
|
(t (error "Unknown action %s" action)))
|
|
|
|
|
idlwave-shell-last-save-and-action-file)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
'idlwave-shell-maybe-update-routine-info
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-hide-p 'run))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(idlwave-shell-bp-query))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(let ((msg (format "No such file %s"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
idlwave-shell-last-save-and-action-file)))
|
|
|
|
|
(setq idlwave-shell-last-save-and-action-file nil)
|
|
|
|
|
(error msg))))
|
|
|
|
|
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(defun idlwave-shell-maybe-update-routine-info (&optional wait)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
"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)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(idlwave-shell-update-routine-info t nil 'wait)))
|
2000-06-20 12:49:47 +00:00
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(defvar idlwave-shell-sources-query "help,/source,/full"
|
2000-01-03 14:23:13 +00:00
|
|
|
|
"IDL command to obtain source files for compiled procedures.")
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-sources-alist nil
|
|
|
|
|
"Alist of IDL procedure names and compiled source files.
|
|
|
|
|
Elements of the alist have the form:
|
|
|
|
|
|
|
|
|
|
(module name . (source-file-truename idlwave-internal-filename)).")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-sources-query ()
|
|
|
|
|
"Determine source files for IDL compiled procedures.
|
|
|
|
|
Queries IDL using the string in `idlwave-shell-sources-query'."
|
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-send-command idlwave-shell-sources-query
|
|
|
|
|
'idlwave-shell-sources-filter
|
|
|
|
|
'hide))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-sources-filter ()
|
|
|
|
|
"Get source files from `idlwave-shell-sources-query' output.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
Create `idlwave-shell-sources-alist' consisting of
|
2000-01-03 14:23:13 +00:00
|
|
|
|
list elements of the form:
|
|
|
|
|
(module name . (source-file-truename idlwave-internal-filename))."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (get-buffer-create idlwave-shell-bp-buffer))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(insert idlwave-shell-command-output)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(let (cpro cfun)
|
|
|
|
|
(if (re-search-forward "Compiled Procedures:" nil t)
|
|
|
|
|
(progn
|
|
|
|
|
(forward-line) ; Skip $MAIN$
|
|
|
|
|
(setq cpro (point))))
|
|
|
|
|
(if (re-search-forward "Compiled Functions:" nil t)
|
|
|
|
|
(progn
|
|
|
|
|
(setq cfun (point))
|
|
|
|
|
(setq idlwave-shell-sources-alist
|
|
|
|
|
(append
|
|
|
|
|
;; compiled procedures
|
|
|
|
|
(progn
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(narrow-to-region cpro (point))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(idlwave-shell-sources-grep))
|
|
|
|
|
;; compiled functions
|
|
|
|
|
(progn
|
|
|
|
|
(widen)
|
|
|
|
|
(goto-char cfun)
|
|
|
|
|
(idlwave-shell-sources-grep)))))))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-sources-grep ()
|
|
|
|
|
(save-excursion
|
|
|
|
|
(let ((al (list nil)))
|
|
|
|
|
(while (and
|
|
|
|
|
(not (progn (forward-line) (eobp)))
|
|
|
|
|
(re-search-forward
|
|
|
|
|
"\\s-*\\(\\S-+\\)\\s-+\\(\\S-+\\)" nil t))
|
|
|
|
|
(nconc al
|
|
|
|
|
(list
|
|
|
|
|
(cons
|
|
|
|
|
(buffer-substring ; name
|
|
|
|
|
(match-beginning 1) (match-end 1))
|
|
|
|
|
(let ((internal-filename
|
|
|
|
|
(buffer-substring ; source
|
|
|
|
|
(match-beginning 2) (match-end 2))))
|
|
|
|
|
(list
|
|
|
|
|
(idlwave-shell-file-name internal-filename)
|
|
|
|
|
internal-filename))
|
|
|
|
|
))))
|
|
|
|
|
(cdr al))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-clear-all-bp ()
|
|
|
|
|
"Remove all breakpoints in IDL."
|
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-send-command
|
|
|
|
|
idlwave-shell-bp-query
|
|
|
|
|
'(progn
|
|
|
|
|
(idlwave-shell-filter-bp)
|
|
|
|
|
(mapcar 'idlwave-shell-clear-bp idlwave-shell-bp-alist))
|
|
|
|
|
'hide))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-list-all-bp ()
|
|
|
|
|
"List all breakpoints in IDL."
|
|
|
|
|
(interactive)
|
|
|
|
|
(idlwave-shell-send-command
|
|
|
|
|
idlwave-shell-bp-query))
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-error-last 0
|
|
|
|
|
"Position of last syntax error in `idlwave-shell-error-buffer'.")
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-goto-next-error ()
|
|
|
|
|
"Move point to next IDL syntax error."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let (frame col)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer idlwave-shell-error-buffer)
|
|
|
|
|
(goto-char idlwave-shell-error-last)
|
|
|
|
|
(if (or (re-search-forward idlwave-shell-syntax-error nil t)
|
|
|
|
|
(re-search-forward idlwave-shell-other-error nil t))
|
|
|
|
|
(progn
|
|
|
|
|
(setq frame
|
|
|
|
|
(list
|
|
|
|
|
(save-match-data
|
|
|
|
|
(idlwave-shell-file-name
|
|
|
|
|
(buffer-substring (match-beginning 1) (match-end 1))))
|
|
|
|
|
(string-to-int
|
|
|
|
|
(buffer-substring (match-beginning 2)
|
|
|
|
|
(match-end 2)))))
|
|
|
|
|
;; Try to find the column of the error
|
|
|
|
|
(save-excursion
|
|
|
|
|
(setq col
|
|
|
|
|
(if (re-search-backward "\\^" nil t)
|
|
|
|
|
(current-column)
|
|
|
|
|
0)))))
|
|
|
|
|
(setq idlwave-shell-error-last (point)))
|
|
|
|
|
(if frame
|
|
|
|
|
(progn
|
|
|
|
|
(idlwave-shell-display-line frame col))
|
|
|
|
|
(beep)
|
|
|
|
|
(message "No more errors."))))
|
|
|
|
|
|
|
|
|
|
(defun idlwave-shell-file-name (name)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
"If `idlwave-shell-use-truename' is non-nil, convert file name to true name.
|
2000-01-03 14:23:13 +00:00
|
|
|
|
Otherwise, just expand the file name."
|
|
|
|
|
(let ((def-dir (if (eq major-mode 'idlwave-shell-mode)
|
|
|
|
|
default-directory
|
|
|
|
|
idlwave-shell-default-directory)))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if idlwave-shell-use-truename
|
|
|
|
|
(file-truename name def-dir)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(expand-file-name name def-dir))))
|
|
|
|
|
|
|
|
|
|
;; Keybindings --------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-mode-map (copy-keymap comint-mode-map)
|
|
|
|
|
"Keymap for idlwave-mode.")
|
|
|
|
|
(defvar idlwave-shell-mode-prefix-map (make-sparse-keymap))
|
|
|
|
|
(fset 'idlwave-shell-mode-prefix-map idlwave-shell-mode-prefix-map)
|
|
|
|
|
|
|
|
|
|
;(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 "\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)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map "\C-g" 'idlwave-keyboard-quit)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map "\M-?" 'idlwave-context-help)
|
2002-09-12 17:24:53 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map [(control meta ?\?)] 'idlwave-online-help)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map "\C-c\C-i" 'idlwave-update-routine-info)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(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)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map "\C-c=" 'idlwave-resolve)
|
|
|
|
|
(define-key idlwave-shell-mode-map "\C-c\C-v" 'idlwave-find-module)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map "\C-c\C-k" 'idlwave-kill-autoloaded-buffers)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map idlwave-shell-prefix-key
|
|
|
|
|
'idlwave-shell-debug-map)
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map [(up)] 'idlwave-shell-up-or-history)
|
|
|
|
|
(define-key idlwave-shell-mode-map [(down)] 'idlwave-shell-down-or-history)
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(define-key idlwave-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
|
|
|
|
|
(define-key idlwave-mode-map "\C-c\C-x" 'idlwave-shell-send-char)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
|
|
|
|
|
;; The mouse bindings for PRINT and HELP
|
|
|
|
|
(idlwave-shell-define-key-both
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (featurep 'xemacs)
|
|
|
|
|
[(shift button2)]
|
2002-07-18 18:58:07 +00:00
|
|
|
|
[(shift down-mouse-2)])
|
|
|
|
|
'idlwave-shell-mouse-print)
|
|
|
|
|
(idlwave-shell-define-key-both
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(if (featurep 'xemacs)
|
|
|
|
|
[(control meta button2)]
|
2002-07-18 18:58:07 +00:00
|
|
|
|
[(control meta down-mouse-2)])
|
2000-06-20 12:49:47 +00:00
|
|
|
|
'idlwave-shell-mouse-help)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(idlwave-shell-define-key-both
|
|
|
|
|
(if (featurep 'xemacs)
|
|
|
|
|
[(control shift button2)]
|
|
|
|
|
[(control shift down-mouse-2)])
|
|
|
|
|
'idlwave-shell-examine-select)
|
|
|
|
|
;; Add this one from the idlwave-mode-map
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(define-key idlwave-shell-mode-map
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(if (featurep 'xemacs)
|
|
|
|
|
[(shift button3)]
|
|
|
|
|
[(shift mouse-3)])
|
2000-06-20 12:49:47 +00:00
|
|
|
|
'idlwave-mouse-context-help)
|
|
|
|
|
|
2002-07-18 18:58:07 +00:00
|
|
|
|
;; For Emacs, we need to turn off the button release events.
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(defun idlwave-shell-mouse-nop (event)
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(interactive "e"))
|
|
|
|
|
(unless (featurep 'xemacs)
|
|
|
|
|
(idlwave-shell-define-key-both
|
|
|
|
|
[(shift mouse-2)] 'idlwave-shell-mouse-nop)
|
|
|
|
|
(idlwave-shell-define-key-both
|
|
|
|
|
[(shift control mouse-2)] 'idlwave-shell-mouse-nop)
|
|
|
|
|
(idlwave-shell-define-key-both
|
|
|
|
|
[(control meta mouse-2)] 'idlwave-shell-mouse-nop))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;; The following set of bindings is used to bind the debugging keys.
|
|
|
|
|
;; If `idlwave-shell-activate-prefix-keybindings' is non-nil, the first key
|
|
|
|
|
;; in the list gets bound the C-c C-d prefix map.
|
2000-12-11 12:45:42 +00:00
|
|
|
|
;; If `idlwave-shell-debug-modifiers' is non-nil, the second key
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; in the list gets bound with the specified modifiers in both
|
2000-12-11 12:45:42 +00:00
|
|
|
|
;; `idlwave-mode-map' and `idlwave-shell-mode-map'.
|
|
|
|
|
|
2002-10-17 15:41:01 +00:00
|
|
|
|
;; Used keys: abcdef hi klmnopqrs u wxyz
|
|
|
|
|
;; Unused keys: g j t v
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(let* ((specs
|
|
|
|
|
'(([(control ?b)] ?b idlwave-shell-break-here)
|
|
|
|
|
([(control ?i)] ?i idlwave-shell-break-in)
|
|
|
|
|
([(control ?d)] ?d idlwave-shell-clear-current-bp)
|
|
|
|
|
([(control ?a)] ?a idlwave-shell-clear-all-bp)
|
|
|
|
|
([(control ?s)] ?s idlwave-shell-step)
|
|
|
|
|
([(control ?n)] ?n idlwave-shell-stepover)
|
|
|
|
|
([(control ?k)] ?k idlwave-shell-skip)
|
|
|
|
|
([(control ?u)] ?u idlwave-shell-up)
|
|
|
|
|
([(control ?o)] ?o idlwave-shell-out)
|
|
|
|
|
([(control ?m)] ?m idlwave-shell-return)
|
|
|
|
|
([(control ?h)] ?h idlwave-shell-to-here)
|
|
|
|
|
([(control ?r)] ?r idlwave-shell-cont)
|
|
|
|
|
([(control ?y)] ?y idlwave-shell-execute-default-command-line)
|
|
|
|
|
([(control ?z)] ?z idlwave-shell-reset)
|
|
|
|
|
([(control ?q)] ?q idlwave-shell-quit)
|
|
|
|
|
([(control ?p)] ?p idlwave-shell-print)
|
|
|
|
|
([(??)] ?? idlwave-shell-help-expression)
|
|
|
|
|
([(control ?c)] ?c idlwave-shell-save-and-run)
|
|
|
|
|
([( ?@)] ?@ idlwave-shell-save-and-batch)
|
|
|
|
|
([(control ?x)] ?x idlwave-shell-goto-next-error)
|
|
|
|
|
([(control ?e)] ?e idlwave-shell-run-region)
|
|
|
|
|
([(control ?w)] ?w idlwave-shell-resync-dirs)
|
|
|
|
|
([(control ?l)] ?l idlwave-shell-redisplay)
|
|
|
|
|
([(control ?t)] ?t idlwave-shell-toggle-toolbar)
|
|
|
|
|
([(control up)] up idlwave-shell-stack-up)
|
|
|
|
|
([(control down)] down idlwave-shell-stack-down)
|
|
|
|
|
([(control ?f)] ?f idlwave-shell-window)))
|
|
|
|
|
(mod (cond ((and idlwave-shell-debug-modifiers
|
|
|
|
|
(listp idlwave-shell-debug-modifiers)
|
|
|
|
|
(not (equal '() idlwave-shell-debug-modifiers)))
|
|
|
|
|
idlwave-shell-debug-modifiers)
|
|
|
|
|
(idlwave-shell-activate-alt-keybindings
|
|
|
|
|
'(alt))))
|
|
|
|
|
(shift (memq 'shift mod))
|
|
|
|
|
(mod-noshift (delete 'shift (copy-sequence mod)))
|
|
|
|
|
s k1 c2 k2 cmd)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(while (setq s (pop specs))
|
|
|
|
|
(setq k1 (nth 0 s)
|
2000-12-11 12:45:42 +00:00
|
|
|
|
c2 (nth 1 s)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
cmd (nth 2 s))
|
|
|
|
|
(when idlwave-shell-activate-prefix-keybindings
|
|
|
|
|
(and k1 (define-key idlwave-shell-mode-prefix-map k1 cmd)))
|
2000-12-11 12:45:42 +00:00
|
|
|
|
(when (and mod window-system)
|
|
|
|
|
(if (char-or-string-p c2)
|
|
|
|
|
(setq k2 (vector (append mod-noshift
|
|
|
|
|
(list (if shift (upcase c2) c2)))))
|
|
|
|
|
(setq k2 (vector (append mod (list c2)))))
|
|
|
|
|
(define-key idlwave-mode-map k2 cmd)
|
|
|
|
|
(define-key idlwave-shell-mode-map k2 cmd))))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
;; Enter the prefix map at the two places.
|
|
|
|
|
(fset 'idlwave-debug-map idlwave-shell-mode-prefix-map)
|
|
|
|
|
(fset 'idlwave-shell-debug-map idlwave-shell-mode-prefix-map)
|
|
|
|
|
|
|
|
|
|
;; The Menus --------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-menu-def
|
|
|
|
|
'("Debug"
|
|
|
|
|
["Save and .RUN" idlwave-shell-save-and-run
|
|
|
|
|
(or (eq major-mode 'idlwave-mode)
|
|
|
|
|
idlwave-shell-last-save-and-action-file)]
|
|
|
|
|
["Save and .COMPILE" idlwave-shell-save-and-compile
|
|
|
|
|
(or (eq major-mode 'idlwave-mode)
|
|
|
|
|
idlwave-shell-last-save-and-action-file)]
|
|
|
|
|
["Save and @Batch" idlwave-shell-save-and-batch
|
|
|
|
|
(or (eq major-mode 'idlwave-mode)
|
|
|
|
|
idlwave-shell-last-save-and-action-file)]
|
|
|
|
|
["Goto Next Error" idlwave-shell-goto-next-error t]
|
|
|
|
|
"--"
|
|
|
|
|
["Execute Default Cmd" idlwave-shell-execute-default-command-line t]
|
|
|
|
|
["Edit Default Cmd" idlwave-shell-edit-default-command-line t]
|
|
|
|
|
"--"
|
|
|
|
|
["Set Breakpoint" idlwave-shell-break-here
|
|
|
|
|
(eq major-mode 'idlwave-mode)]
|
|
|
|
|
["Break in Module" idlwave-shell-break-in t]
|
|
|
|
|
["Clear Breakpoint" idlwave-shell-clear-current-bp t]
|
|
|
|
|
["Clear All Breakpoints" idlwave-shell-clear-all-bp t]
|
|
|
|
|
["List All Breakpoints" idlwave-shell-list-all-bp t]
|
|
|
|
|
"--"
|
|
|
|
|
["Step (into)" idlwave-shell-step t]
|
|
|
|
|
["Step (over)" idlwave-shell-stepover t]
|
|
|
|
|
["Skip One Statement" idlwave-shell-skip t]
|
|
|
|
|
["Continue" idlwave-shell-cont t]
|
|
|
|
|
("Continue to"
|
|
|
|
|
["End of Block" idlwave-shell-up t]
|
|
|
|
|
["End of Subprog" idlwave-shell-return t]
|
|
|
|
|
["End of Subprog+1" idlwave-shell-out t]
|
|
|
|
|
["Here (Cursor Line)" idlwave-shell-to-here
|
|
|
|
|
(eq major-mode 'idlwave-mode)])
|
|
|
|
|
"--"
|
|
|
|
|
["Print expression" idlwave-shell-print t]
|
|
|
|
|
["Help on expression" idlwave-shell-help-expression t]
|
2002-10-17 15:41:01 +00:00
|
|
|
|
["Evaluate Region" idlwave-shell-evaluate-region
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(eq major-mode 'idlwave-mode)]
|
|
|
|
|
["Run Region" idlwave-shell-run-region (eq major-mode 'idlwave-mode)]
|
|
|
|
|
"--"
|
|
|
|
|
["Redisplay" idlwave-shell-redisplay t]
|
|
|
|
|
["Stack Up" idlwave-shell-stack-up t]
|
|
|
|
|
["Stack Down" idlwave-shell-stack-down t]
|
|
|
|
|
"--"
|
|
|
|
|
["Update Working Dir" idlwave-shell-resync-dirs t]
|
|
|
|
|
["Reset IDL" idlwave-shell-reset t]
|
|
|
|
|
"--"
|
|
|
|
|
["Toggle Toolbar" idlwave-shell-toggle-toolbar t]
|
|
|
|
|
["Exit IDL" idlwave-shell-quit t]))
|
2000-12-11 12:45:42 +00:00
|
|
|
|
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(setq idlwave-shell-menu-def
|
|
|
|
|
'("Debug"
|
|
|
|
|
("Compile & Run"
|
|
|
|
|
["Save and .RUN" idlwave-shell-save-and-run
|
|
|
|
|
(or (eq major-mode 'idlwave-mode)
|
|
|
|
|
idlwave-shell-last-save-and-action-file)]
|
|
|
|
|
["Save and .COMPILE" idlwave-shell-save-and-compile
|
|
|
|
|
(or (eq major-mode 'idlwave-mode)
|
|
|
|
|
idlwave-shell-last-save-and-action-file)]
|
|
|
|
|
["Save and @Batch" idlwave-shell-save-and-batch
|
|
|
|
|
(or (eq major-mode 'idlwave-mode)
|
|
|
|
|
idlwave-shell-last-save-and-action-file)]
|
|
|
|
|
["Goto Next Error" idlwave-shell-goto-next-error t]
|
|
|
|
|
"--"
|
|
|
|
|
["Run Region" idlwave-shell-run-region (eq major-mode 'idlwave-mode)]
|
|
|
|
|
"--"
|
|
|
|
|
["Execute Default Cmd" idlwave-shell-execute-default-command-line t]
|
|
|
|
|
["Edit Default Cmd" idlwave-shell-edit-default-command-line t])
|
|
|
|
|
("Breakpoints"
|
|
|
|
|
["Set Breakpoint" idlwave-shell-break-here
|
|
|
|
|
(eq major-mode 'idlwave-mode)]
|
|
|
|
|
["Break in Module" idlwave-shell-break-in t]
|
|
|
|
|
["Clear Breakpoint" idlwave-shell-clear-current-bp t]
|
|
|
|
|
["Clear All Breakpoints" idlwave-shell-clear-all-bp t]
|
|
|
|
|
["List All Breakpoints" idlwave-shell-list-all-bp t])
|
2000-12-11 12:45:42 +00:00
|
|
|
|
("Continue/Step"
|
2000-06-20 12:49:47 +00:00
|
|
|
|
["Step (into)" idlwave-shell-step t]
|
|
|
|
|
["Step (over)" idlwave-shell-stepover t]
|
|
|
|
|
["Skip One Statement" idlwave-shell-skip t]
|
|
|
|
|
["Continue" idlwave-shell-cont t]
|
|
|
|
|
["... to End of Block" idlwave-shell-up t]
|
|
|
|
|
["... to End of Subprog" idlwave-shell-return t]
|
|
|
|
|
["... to End of Subprog+1" idlwave-shell-out t]
|
|
|
|
|
["... to Here (Cursor Line)" idlwave-shell-to-here
|
|
|
|
|
(eq major-mode 'idlwave-mode)])
|
|
|
|
|
("Print Expression"
|
|
|
|
|
["Print expression" idlwave-shell-print t]
|
|
|
|
|
["Help on expression" idlwave-shell-help-expression t]
|
2002-10-17 15:41:01 +00:00
|
|
|
|
["Evaluate Region" idlwave-shell-evaluate-region
|
2000-06-20 12:49:47 +00:00
|
|
|
|
(eq major-mode 'idlwave-mode)]
|
|
|
|
|
"--"
|
|
|
|
|
["Redisplay" idlwave-shell-redisplay t]
|
|
|
|
|
["Stack Up" idlwave-shell-stack-up t]
|
|
|
|
|
["Stack Down" idlwave-shell-stack-down t])
|
|
|
|
|
("Input Mode"
|
|
|
|
|
["Send one char" idlwave-shell-send-char t]
|
|
|
|
|
["Temporary Character Mode" idlwave-shell-char-mode-loop t]
|
|
|
|
|
"--"
|
|
|
|
|
["Use Input Mode Magic"
|
|
|
|
|
(setq idlwave-shell-use-input-mode-magic
|
|
|
|
|
(not idlwave-shell-use-input-mode-magic))
|
|
|
|
|
:style toggle :selected idlwave-shell-use-input-mode-magic])
|
|
|
|
|
"--"
|
|
|
|
|
["Update Working Dir" idlwave-shell-resync-dirs t]
|
|
|
|
|
["Reset IDL" idlwave-shell-reset t]
|
|
|
|
|
"--"
|
|
|
|
|
["Toggle Toolbar" idlwave-shell-toggle-toolbar t]
|
|
|
|
|
["Exit IDL" idlwave-shell-quit t]))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
(if (or (featurep 'easymenu) (load "easymenu" t))
|
|
|
|
|
(progn
|
|
|
|
|
(easy-menu-define
|
|
|
|
|
idlwave-shell-mode-menu idlwave-shell-mode-map "IDL shell menus"
|
|
|
|
|
idlwave-shell-menu-def)
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(easy-menu-define
|
2000-01-03 14:23:13 +00:00
|
|
|
|
idlwave-mode-debug-menu idlwave-mode-map "IDL debugging menus"
|
|
|
|
|
idlwave-shell-menu-def)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(mapcar (lambda (buf)
|
|
|
|
|
(set-buffer buf)
|
|
|
|
|
(if (eq major-mode 'idlwave-mode)
|
|
|
|
|
(progn
|
|
|
|
|
(easy-menu-remove idlwave-mode-debug-menu)
|
|
|
|
|
(easy-menu-add idlwave-mode-debug-menu))))
|
|
|
|
|
(buffer-list)))))
|
|
|
|
|
|
|
|
|
|
;; The Breakpoint Glyph -------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
(defvar idlwave-shell-bp-glyph nil
|
|
|
|
|
"The glyph to mark breakpoint lines in the source code.")
|
|
|
|
|
|
|
|
|
|
(let ((image-string "/* XPM */
|
|
|
|
|
static char * file[] = {
|
|
|
|
|
\"14 12 3 1\",
|
2002-07-18 18:58:07 +00:00
|
|
|
|
\" c None s backgroundColor\",
|
2000-01-03 14:23:13 +00:00
|
|
|
|
\". c #4B4B4B4B4B4B\",
|
|
|
|
|
\"R c #FFFF00000000\",
|
|
|
|
|
\" \",
|
|
|
|
|
\" \",
|
|
|
|
|
\" RRRR \",
|
|
|
|
|
\" RRRRRR \",
|
|
|
|
|
\" RRRRRRRR \",
|
|
|
|
|
\" RRRRRRRR \",
|
|
|
|
|
\" RRRRRRRR \",
|
|
|
|
|
\" RRRRRRRR \",
|
|
|
|
|
\" RRRRRR \",
|
|
|
|
|
\" RRRR \",
|
|
|
|
|
\" \",
|
|
|
|
|
\" \"};"))
|
2002-10-17 15:41:01 +00:00
|
|
|
|
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(setq idlwave-shell-bp-glyph
|
|
|
|
|
(cond ((and (featurep 'xemacs)
|
|
|
|
|
(featurep 'xpm))
|
|
|
|
|
(make-glyph image-string))
|
|
|
|
|
((and (not (featurep 'xemacs))
|
|
|
|
|
(fboundp 'image-type-available-p)
|
|
|
|
|
(image-type-available-p 'xpm))
|
2002-07-18 18:58:07 +00:00
|
|
|
|
(list 'image :type 'xpm :data image-string :ascent 'center))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(t nil))))
|
|
|
|
|
|
|
|
|
|
(provide 'idlw-shell)
|
2000-01-05 08:50:31 +00:00
|
|
|
|
(provide 'idlwave-shell)
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
|
|
|
|
;;; Load the toolbar when wanted by the user.
|
|
|
|
|
|
2002-10-17 15:41:01 +00:00
|
|
|
|
(autoload 'idlwave-toolbar-toggle "idlw-toolbar"
|
2000-02-04 10:10:40 +00:00
|
|
|
|
"Toggle the IDLWAVE toolbar")
|
|
|
|
|
(autoload 'idlwave-toolbar-add-everywhere "idlw-toolbar"
|
|
|
|
|
"Add IDLWAVE toolbar")
|
2000-01-03 14:23:13 +00:00
|
|
|
|
(defun idlwave-shell-toggle-toolbar ()
|
|
|
|
|
"Toggle the display of the debugging toolbar."
|
|
|
|
|
(interactive)
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(idlwave-toolbar-toggle))
|
2000-01-03 14:23:13 +00:00
|
|
|
|
|
2000-02-04 10:10:40 +00:00
|
|
|
|
(if idlwave-shell-use-toolbar
|
|
|
|
|
(add-hook 'idlwave-shell-mode-hook 'idlwave-toolbar-add-everywhere))
|
2003-09-01 15:45:59 +00:00
|
|
|
|
|
|
|
|
|
;;; arch-tag: 20c2e8ce-0709-41d8-a5b6-bb039148440a
|
2000-01-03 14:23:13 +00:00
|
|
|
|
;;; idlw-shell.el ends here
|