/[emacs]/emacs/lisp/progmodes/idlw-shell.el
ViewVC logotype

Diff of /emacs/lisp/progmodes/idlw-shell.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3.15 by lektu, Thu May 16 11:58:49 2002 UTC revision 3.15.2.1 by miles, Fri Apr 4 06:20:33 2003 UTC
# Line 1  Line 1 
1  ;;; idlw-shell.el --- run IDL or WAVE as an inferior process of Emacs  ;; idlw-shell.el --- run IDL as an inferior process of Emacs.
2  ;; Copyright (c) 1999, 2000 Free Software Foundation  ;; Copyright (c) 1999, 2000, 2001,2002 Free Software Foundation
3    
4  ;; Author: Chris Chase <chase@att.com>  ;; Author: Carsten Dominik <dominik@astro.uva.nl>
5  ;; Maintainer: John-David Smith <jdsmith@astro.cornell.edu>  ;;         Chris Chase <chase@att.com>
6  ;; Version: 4.7  ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu>
7    ;; Version: 4.15
8  ;; Date: $Date$  ;; Date: $Date$
9  ;; Keywords: processes  ;; Keywords: processes
10    
# Line 25  Line 26 
26  ;; Boston, MA 02111-1307, USA.  ;; Boston, MA 02111-1307, USA.
27    
28  ;;; Commentary:  ;;; Commentary:
29    ;;
30  ;; This mode is for IDL version 4 or later.  It should work on Emacs  ;; This mode is for IDL version 5 or later.  It should work on
31  ;; or XEmacs version 19 or later.  ;; Emacs>20.3 or XEmacs>20.4.
32    ;;
33  ;; Runs IDL as an inferior process of Emacs, much like the emacs  ;; Runs IDL as an inferior process of Emacs, much like the emacs
34  ;; `shell' or `telnet' commands.  Provides command history and  ;; `shell' or `telnet' commands.  Provides command history and
35  ;; searching.  Provides debugging commands available in buffers  ;; searching.  Provides debugging commands available in buffers
# Line 37  Line 38 
38  ;; visual line pointer for current execution line, etc.  ;; visual line pointer for current execution line, etc.
39  ;;  ;;
40  ;; Documentation should be available online with `M-x idlwave-info'.  ;; Documentation should be available online with `M-x idlwave-info'.
41    ;;
42    ;; New versions of IDLWAVE, documentation, and more information
43    ;; available from:
44    ;;                 http://idlwave.org
45    ;;
46  ;; INSTALLATION:  ;; INSTALLATION:
47  ;; =============  ;; =============
48  ;;  ;;
49  ;; Follow the instructions in the INSTALL file of the distribution.  ;; Follow the instructions in the INSTALL file of the distribution.
50  ;; In short, put this file on your load path and add the following  ;; In short, put this file on your load path and add the following
51  ;; lines to your .emacs file:  ;; lines to your .emacs file:
# Line 53  Line 58 
58  ;;  ;;
59  ;;   The newest version of this file can be found on the maintainers  ;;   The newest version of this file can be found on the maintainers
60  ;;   web site.  ;;   web site.
61  ;;  ;;
62  ;;     http://www.strw.leidenuniv.el/~dominik/Tools/idlwave  ;;     http://idlwave.org
63  ;;  ;;
64  ;; DOCUMENTATION  ;; DOCUMENTATION
65  ;; =============  ;; =============
66  ;;  ;;
# Line 67  Line 72 
72  ;; KNOWN PROBLEMS  ;; KNOWN PROBLEMS
73  ;; ==============  ;; ==============
74  ;;  ;;
 ;; I don't plan on implementing directory tracking by watching the IDL  
 ;; commands entered at the prompt, since too often an IDL procedure  
 ;; will change the current directory. If you want the idl process  
 ;; buffer to match the IDL current working just execute `M-x  
 ;; idlwave-shell-resync-dirs' (bound to "\C-c\C-d\C-w" by default.)  
 ;;  
75  ;; Under XEmacs the Debug menu in the shell does not display the  ;; Under XEmacs the Debug menu in the shell does not display the
76  ;; keybindings in the prefix map.  There bindings are available anyway - so  ;; keybindings in the prefix map.  There bindings are available anyway - so
77  ;; it is a bug in XEmacs.  ;; it is a bug in XEmacs.
78  ;; The Debug menu in source buffers *does* display the bindings correctly.  ;; The Debug menu in source buffers *does* display the bindings correctly.
79  ;;  ;;
80  ;;  ;;
81  ;; CUSTOMIZATION VARIABLES  ;; CUSTOMIZATION VARIABLES
82  ;; =======================  ;; =======================
83  ;;  ;;
# Line 88  Line 87 
87  ;;  ;;
88  ;;--------------------------------------------------------------------------  ;;--------------------------------------------------------------------------
89  ;;  ;;
 ;;  
90    
91  ;;; Code:  ;;; Code:
92    
# Line 99  Line 97 
97    
98  (defvar idlwave-shell-have-new-custom nil)  (defvar idlwave-shell-have-new-custom nil)
99  (eval-and-compile  (eval-and-compile
100   ;; Kludge to allow `defcustom' for Emacs 19.    ;; Kludge to allow `defcustom' for Emacs 19.
101   (condition-case () (require 'custom) (error nil))    (condition-case () (require 'custom) (error nil))
102   (if (and (featurep 'custom)    (if (and (featurep 'custom)
103            (fboundp 'custom-declare-variable)             (fboundp 'custom-declare-variable)
104            (fboundp 'defface))                   (fboundp 'defface))
105       ;; We've got what we needed        ;; We've got what we needed
106       (setq idlwave-shell-have-new-custom t)        (setq idlwave-shell-have-new-custom t)
107       ;; We have the old or no custom-library, hack around it!      ;; We have the old or no custom-library, hack around it!
108       (defmacro defgroup (&rest args) nil)      (defmacro defgroup (&rest args) nil)
109       (defmacro defcustom (var value doc &rest args)      (defmacro defcustom (var value doc &rest args)
110         `(defvar ,var ,value ,doc))))        `(defvar ,var ,value ,doc))))
111    
112  ;;; Customizations: idlwave-shell group  ;;; Customizations: idlwave-shell group
113    
114    ;; General/Misc. customizations
115  (defgroup idlwave-shell-general-setup nil  (defgroup idlwave-shell-general-setup nil
116    "General setup of the Shell interaction for IDLWAVE/Shell."    "General setup of the Shell interaction for IDLWAVE/Shell."
117    :prefix "idlwave-shell"    :prefix "idlwave-shell"
118    :group 'idlwave)    :group 'idlwave)
119    
120  (defcustom idlwave-shell-prompt-pattern "^ ?IDL> "  (defcustom idlwave-shell-prompt-pattern "^ ?IDL> "
121    "*Regexp to match IDL prompt at beginning of a line.    "*Regexp to match IDL prompt at beginning of a line.
122  For example, \"^IDL> \" or \"^WAVE> \".  For example, \"^IDL> \" or \"^WAVE> \".
123  The \"^\" means beginning of line.  The \"^\" means beginning of line.
124  This variable is used to initialise `comint-prompt-regexp' in the  This variable is used to initialise `comint-prompt-regexp' in the
125  process buffer.  process buffer.
126    
127  This is a fine thing to set in your `.emacs' file."  This is a fine thing to set in your `.emacs' file."
# Line 137  process output is made by surrounding th Line 136  process output is made by surrounding th
136    
137  ;; (defcustom idlwave-shell-automatic-start...)  See idlwave.el  ;; (defcustom idlwave-shell-automatic-start...)  See idlwave.el
138    
 (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-initial-commands  
   :type 'string)  
   
139  (defcustom idlwave-shell-use-dedicated-frame nil  (defcustom idlwave-shell-use-dedicated-frame nil
140    "*Non-nil means, IDLWAVE should use a special frame to display shell buffer."    "*Non-nil means, IDLWAVE should use a special frame to display shell buffer."
141    :group 'idlwave-shell-general-setup    :group 'idlwave-shell-general-setup
# Line 158  The default makes the frame splittable, Line 150  The default makes the frame splittable,
150    :type '(repeat    :type '(repeat
151            (cons symbol sexp)))            (cons symbol sexp)))
152    
153    (defcustom idlwave-shell-raise-frame t
154      "*Non-nil means, `idlwave-shell' raises the frame showing the shell window."
155      :group 'idlwave-shell-general-setup
156      :type 'boolean)
157    
158  (defcustom idlwave-shell-arrows-do-history t  (defcustom idlwave-shell-arrows-do-history t
159    "*Non-nil means UP and DOWN arrows move through command history.    "*Non-nil means UP and DOWN arrows move through command history.
160  This variable can have 3 values:  This variable can have 3 values:
# Line 172  t          Arrows force the cursor back Line 169  t          Arrows force the cursor back
169            (const :tag "everywhere" t)            (const :tag "everywhere" t)
170            (const :tag "in command line only" cmdline)))            (const :tag "in command line only" cmdline)))
171    
172    ;; FIXME: add comint-input-ring-size?
173    
174  (defcustom idlwave-shell-use-toolbar t  (defcustom idlwave-shell-use-toolbar t
175    "*Non-nil means, use the debugging toolbar in all IDL related buffers.    "*Non-nil means, use the debugging toolbar in all IDL related buffers.
176  Starting the shell will then add the toolbar to all idlwave-mode buffers.  Starting the shell will then add the toolbar to all idlwave-mode buffers.
# Line 185  At any time you can toggle the display o Line 184  At any time you can toggle the display o
184  (defcustom idlwave-shell-temp-pro-prefix "/tmp/idltemp"  (defcustom idlwave-shell-temp-pro-prefix "/tmp/idltemp"
185    "*The prefix for temporary IDL files used when compiling regions.    "*The prefix for temporary IDL files used when compiling regions.
186  It should be an absolute pathname.  It should be an absolute pathname.
187  The full temporary file name is obtained by to using `make-temp-name'  The full temporary file name is obtained by using `make-temp-file'
188  so that the name will be unique among multiple Emacs processes."  so that the name will be unique among multiple Emacs processes."
189    :group 'idlwave-shell-general-setup    :group 'idlwave-shell-general-setup
190    :type 'string)    :type 'string)
# Line 228  to set this option to nil." Line 227  to set this option to nil."
227    :group 'idlwave-shell-general-setup    :group 'idlwave-shell-general-setup
228    :type 'boolean)    :type 'boolean)
229    
230  (defcustom idlwave-shell-file-name-chars "~/A-Za-z0-9+@:_.$#%={}\\-"  (defcustom idlwave-shell-file-name-chars "~/A-Za-z0-9+:_.$#%={}\\-"
231    "The characters allowed in file names, as a string.    "The characters allowed in file names, as a string.
232  Used for file name completion. Must not contain `'', `,' and `\"'  Used for file name completion. Must not contain `'', `,' and `\"'
233  because these are used as separators by IDL."  because these are used as separators by IDL."
# Line 240  because these are used as separators by Line 239  because these are used as separators by
239    :group 'idlwave-shell-general-setup    :group 'idlwave-shell-general-setup
240    :type 'hook)    :type 'hook)
241    
242  (defcustom idlwave-shell-print-expression-function nil  (defcustom idlwave-shell-graphics-window-size '(500 400)
243    "When non-nil, a function to handle display of evaluated expressions.    "Size of IDL graphics windows popped up by special IDLWAVE command.
244  This can be used to arrange for displaying the value of an expression  The command is `C-c C-d C-f' and accepts as a prefix the window nr.
245  in (e.g.) a special frame.  The function must accept one argument:  A command like `WINDOW,N,xsize=XX,ysize=YY' is sent to IDL."
246  the expression which was evaluated.  The output from IDL will be    :group 'idlwave-shell-general-setup
247  available in the variable `idlwave-shell-command-output'."    :type '(list
248    :group 'idlwave-shell-highlighting-and-faces            (integer :tag "x size")
249    :type 'symbol)            (integer :tag "y size")))
250    
251    ;; Commands Sent to Shell... etc.
252    (defgroup idlwave-shell-command-setup nil
253      "Setup for command parameters of the Shell interaction for IDLWAVE."
254      :prefix "idlwave-shell"
255      :group 'idlwave)
256    
257    (defcustom idlwave-shell-initial-commands "!more=0"
258      "Initial commands, separated by newlines, to send to IDL.
259    This string is sent to the IDL process by `idlwave-shell-mode' which is
260    invoked by `idlwave-shell'."
261      :group 'idlwave-shell-command-setup
262      :type 'string)
263    
264    (defcustom idlwave-shell-save-command-history t
265      "Non-nil means preserve command history between sessions.
266    The file `idlwave-shell-command-history-file' is used to save and restore
267    the history."
268      :group 'idlwave-shell-command-setup
269      :type 'boolean)
270    
271    (defcustom idlwave-shell-command-history-file "~/.idlwhist"
272      "The file in which the command history of the idlwave shell is saved.
273    In order to change the size of the history, see the variable
274    `comint-input-ring-size'.
275    The history is only saved if the variable `idlwave-shell-save-command-history'
276    is non-nil."
277      :group 'idlwave-shell-command-setup
278      :type 'file)
279    
280    (defcustom idlwave-shell-show-commands
281      '(run misc breakpoint)
282      "*A list of command types to show output from in the shell.
283    Possibilities are 'run, 'debug, 'breakpoint, and 'misc .  Unlisted
284    types are not displayed in the shell.  The single type 'everything
285    causes all the copious shell traffic to be displayed."
286      :group 'idlwave-shell-command-setup
287      :type '(choice
288              (const everything)
289              (set :tag "Checklist" :greedy t
290                   (const :tag "All .run and .compile commands"  run)
291                   (const :tag "All breakpoint commands"         breakpoint)
292                   (const :tag "All debug and stepping commands" debug)
293                   (const :tag "Return, close, etc. commands"    misc))))
294    
295    (defcustom idlwave-shell-examine-alist
296      '(("Print"            . "print,___")
297        ("Help"             . "help,___")
298        ("Structure Help"   . "help,___,/STRUCTURE")
299        ("Dimensions"       . "print,size(___,/DIMENSIONS)")
300        ("Type"             . "print,size(___,/TNAME)")
301        ("N_Elements"       . "print,n_elements(___)")
302        ("All Size Info"    . "help,(__IWsz__=size(___,/STRUCTURE)),/STRUCTURE & print,__IWsz__.DIMENSIONS")
303        ("Ptr Valid"        . "print,ptr_valid(___)")
304        ("Widget Valid"     . "print,widget_info(___,/VALID)")
305        ("Widget Geometry"  . "help,widget_info(___,/GEOMETRY)"))
306      "Alist of special examine commands for popup selection.
307    The keys are used in the selection popup created by
308    `idlwave-shell-examine-select', and the corresponding value is sent as
309    a command to the shell, with special sequence `___' replaced by the
310    expression being examined."
311      :group 'idlwave-shell-command-setup
312      :type '(repeat
313              (cons
314               (string :tag "Label  ")
315               (string :tag "Command"))))
316    
317    (defvar idlwave-shell-print-expression-function nil
318      "*OBSOLETE VARIABLE, is no longer used.")
319    
320    (defcustom idlwave-shell-separate-examine-output t
321      "*Non-nil mean, put output of examine commands in their own buffer."
322      :group 'idlwave-shell-command-setup
323      :type 'boolean)
324    
325    (defcustom idlwave-shell-comint-settings
326      '((comint-scroll-to-bottom-on-input . t)
327        (comint-scroll-to-bottom-on-output . t)
328        (comint-scroll-show-maximum-output . nil))
329    
330      "Alist of special settings for the comint variables in the IDLWAVE Shell.
331    Each entry is a cons cell with the name of a variable and a value.
332    The function `idlwave-shell-mode' will make local variables out of each entry.
333    Changes to this variable will only be active when the shell buffer is
334    newly created."
335      :group 'idlwave-shell-command-setup
336      :type '(repeat
337              (cons variable sexp)))
338    
339    (defcustom idlwave-shell-query-for-class t
340      "*Non-nil means query the shell for object class on object completions."
341      :group 'idlwave-shell-command-setup
342      :type 'boolean)
343    
344  (defcustom idlwave-shell-use-input-mode-magic nil  (defcustom idlwave-shell-use-input-mode-magic nil
345    "*Non-nil means, IDLWAVE should check for input mode spells in output.    "*Non-nil means, IDLWAVE should check for input mode spells in output.
# Line 255  The spells are strings printed by your I Line 347  The spells are strings printed by your I
347  by the regular expressions in `idlwave-shell-input-mode-spells'.  by the regular expressions in `idlwave-shell-input-mode-spells'.
348  When these expressions match, IDLWAVE switches to character input mode and  When these expressions match, IDLWAVE switches to character input mode and
349  back, respectively.  See `idlwave-shell-input-mode-spells' for details."  back, respectively.  See `idlwave-shell-input-mode-spells' for details."
350    :group 'idlwave-shell-general-setup    :group 'idlwave-shell-command-setup
351    :type 'boolean)    :type 'boolean)
352    
353  (defcustom idlwave-shell-input-mode-spells  (defcustom idlwave-shell-input-mode-spells
# Line 292  strings.  Here is some example code whic Line 384  strings.  Here is some example code whic
384    answer = GET_KBRD(1)    answer = GET_KBRD(1)
385    
386  Since the IDLWAVE shell defines the system variable `!IDLWAVE_VERSION',  Since the IDLWAVE shell defines the system variable `!IDLWAVE_VERSION',
387  you could actually check if you are running under Emacs before printing  you could actually check if you are running under Emacs before printing
388  the magic strings.  Here is a procedure which uses this.  the magic strings.  Here is a procedure which uses this.
389    
390  Usage:  Usage:
# Line 309  pro idlwave_char_input,on=on,off=off Line 401  pro idlwave_char_input,on=on,off=off
401        if keyword_set(on) then         print,'<chars>' $        if keyword_set(on) then         print,'<chars>' $
402          else if keyword_set(off) then print,'</chars>' $          else if keyword_set(off) then print,'</chars>' $
403          else                          print,'<onechar>'          else                          print,'<onechar>'
404    endif    endif
405  end"  end"
406    :group 'idlwave-shell-general-setup    :group 'idlwave-shell-command-setup
407    :type '(list    :type '(list
408            (regexp :tag "One-char  regexp")            (regexp :tag "One-char  regexp")
409            (regexp :tag "Char-mode regexp")            (regexp :tag "Char-mode regexp")
410            (regexp :tag "Line-mode regexp")))            (regexp :tag "Line-mode regexp")))
411    
 (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")))  
   
 ;;; Breakpoint Overlays etc  
412    
413    ;; Breakpoint Overlays etc
414  (defgroup idlwave-shell-highlighting-and-faces nil  (defgroup idlwave-shell-highlighting-and-faces nil
415    "Highlighting and Faces used by the IDLWAVE Shell mode."    "Highlighting and Faces used by the IDLWAVE Shell mode."
416    :prefix "idlwave-shell"    :prefix "idlwave-shell"
# Line 346  t         Use what IDLWAVE thinks is bes Line 429  t         Use what IDLWAVE thinks is bes
429  The overlay-arrow has the disadvantage to hide the first chars of a line.  The overlay-arrow has the disadvantage to hide the first chars of a line.
430  Since many people do not have the main block of IDL programs indented,  Since many people do not have the main block of IDL programs indented,
431  a face highlighting may be better.  a face highlighting may be better.
432  On Emacs 21, the overlay arrow is displayed in a special area and never  In Emacs 21, the overlay arrow is displayed in a special area and never
433  hides any code, so setting this to 'arrow on Emacs 21 sounds like a good idea."  hides any code, so setting this to 'arrow on Emacs 21 sounds like a good idea."
434    :group 'idlwave-shell-highlighting-and-faces    :group 'idlwave-shell-highlighting-and-faces
435    :type '(choice    :type '(choice
# Line 387  t          Glyph when possible, otherwis Line 470  t          Glyph when possible, otherwis
470            (const :tag "Glyph or face." t)))            (const :tag "Glyph or face." t)))
471    
472  (defvar idlwave-shell-use-breakpoint-glyph t  (defvar idlwave-shell-use-breakpoint-glyph t
473    "Obsolete variable.   See `idlwave-shell-mark-breakpoints.")    "Obsolete variable.  See `idlwave-shell-mark-breakpoints.")
474    
475  (defcustom idlwave-shell-breakpoint-face 'idlwave-shell-bp-face  (defcustom idlwave-shell-breakpoint-face 'idlwave-shell-bp-face
476    "*The face for breakpoint lines in the source code.    "*The face for breakpoint lines in the source code.
# Line 413  the expression printed by IDL." Line 496  the expression printed by IDL."
496    :group 'idlwave-shell-highlighting-and-faces    :group 'idlwave-shell-highlighting-and-faces
497    :type 'symbol)    :type 'symbol)
498    
499    (defcustom idlwave-shell-output-face 'secondary-selection
500      "*The face for `idlwave-shell-output-overlay'.
501    Allows you to choose the font, color and other properties for
502    the expression output by IDL."
503      :group 'idlwave-shell-highlighting-and-faces
504      :type 'symbol)
505    
506  ;;; End user customization variables  ;;; End user customization variables
507    
508  ;;; External variables  ;;; External variables
509  (defvar comint-last-input-start)  (defvar comint-last-input-start)
510  (defvar comint-last-input-end)  (defvar comint-last-input-end)
511    
512  ;; Other variables  (defun idlwave-shell-temp-file (type)
513      "Return a temp file, creating it if necessary.
514    
515  (defvar idlwave-shell-temp-file-base  TYPE is either 'pro or 'rinfo, and idlwave-shell-temp-pro-file or
516    (make-temp-name idlwave-shell-temp-pro-prefix)  idlwave-shell-temp-rinfo-save-file is set (respectively)."
517    "Base name of the temporary files.")    (cond
518       ((eq type 'rinfo)
519        (or idlwave-shell-temp-rinfo-save-file
520            (setq idlwave-shell-temp-rinfo-save-file
521                  (idlwave-shell-make-temp-file idlwave-shell-temp-pro-prefix))))
522       ((eq type 'pro)
523        (or idlwave-shell-temp-pro-file
524            (setq idlwave-shell-temp-pro-file
525                  (idlwave-shell-make-temp-file idlwave-shell-temp-pro-prefix))))
526       (t (error "Wrong argument (idlwave-shell-temp-file): %s"
527                 (symbol-name type)))))
528    
529    
530    (defun idlwave-shell-make-temp-file (prefix)
531      "Create a temporary file."
532      ; Hard coded make-temp-file for Emacs<21
533      (if (fboundp 'make-temp-file)
534          (make-temp-file prefix)
535        (let (file
536              (temp-file-dir (if (boundp 'temporary-file-directory)
537                                 temporary-file-directory
538                               "/tmp")))
539          (while (condition-case ()
540                     (progn
541                       (setq file
542                             (make-temp-name
543                              (expand-file-name prefix temp-file-dir)))
544                       (if (featurep 'xemacs)
545                           (write-region "" nil file nil 'silent nil)
546                         (write-region "" nil file nil 'silent nil 'excl))
547                       nil)
548                   (file-already-exists t))
549            ;; the file was somehow created by someone else between
550            ;; `make-temp-name' and `write-region', let's try again.
551            nil)
552          file)))
553    
554  (defvar idlwave-shell-temp-pro-file  ;; Other variables
555    (concat idlwave-shell-temp-file-base ".pro")  (defvar idlwave-shell-temp-pro-file
556      nil
557    "Absolute pathname for temporary IDL file for compiling regions")    "Absolute pathname for temporary IDL file for compiling regions")
558    
559  (defvar idlwave-shell-temp-rinfo-save-file  (defvar idlwave-shell-temp-rinfo-save-file
560    (concat idlwave-shell-temp-file-base ".sav")    nil
561    "Absolute pathname for temporary IDL file save file for routine_info.    "Absolute pathname for temporary IDL file save file for routine_info.
562  This is used to speed up the reloading of the routine info procedure  This is used to speed up the reloading of the routine info procedure
563  before use by the shell.")  before use by the shell.")
564    
565    (defvar idlwave-shell-dirstack-query "cd,current=___cur & print,___cur"
566  (defvar idlwave-shell-dirstack-query "printd"    "Command used by `idlwave-shell-resync-dirs' to query IDL for
   "Command used by `idlwave-shell-resync-dirs' to query IDL for  
567  the directory stack.")  the directory stack.")
568    
569  (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+'>'"  (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+'>'"
570    "The command which gets !PATH and !DIR infor from the shell.")    "The command which gets !PATH and !DIR infor from the shell.")
571    
572  (defvar idlwave-shell-mode-line-info nil  (defvar idlwave-shell-mode-line-info nil
573    "Additional info displayed in the mode line")      "Additional info displayed in the mode line")
574    
575  (defvar idlwave-shell-default-directory nil  (defvar idlwave-shell-default-directory nil
576    "The default directory in the idlwave-shell buffer, of outside use.")    "The default directory in the idlwave-shell buffer, of outside use.")
# Line 463  the directory stack.") Line 589  the directory stack.")
589  (defvar idlwave-shell-is-stopped nil)  (defvar idlwave-shell-is-stopped nil)
590  (defvar idlwave-shell-expression-overlay nil  (defvar idlwave-shell-expression-overlay nil
591    "The overlay for where IDL is currently stopped.")    "The overlay for where IDL is currently stopped.")
592    (defvar idlwave-shell-output-overlay nil
593      "The overlay for the last IDL output.")
594    
595  ;; If these were already overlays, delete them.  This probably means that we  ;; If these were already overlays, delete them.  This probably means that we
596  ;; are reloading this file.  ;; are reloading this file.
597  (if (overlayp idlwave-shell-stop-line-overlay)  (if (overlayp idlwave-shell-stop-line-overlay)
598      (delete-overlay idlwave-shell-stop-line-overlay))      (delete-overlay idlwave-shell-stop-line-overlay))
599  (if (overlayp idlwave-shell-expression-overlay)  (if (overlayp idlwave-shell-expression-overlay)
600      (delete-overlay idlwave-shell-expression-overlay))      (delete-overlay idlwave-shell-expression-overlay))
601    (if (overlayp idlwave-shell-output-overlay)
602        (delete-overlay idlwave-shell-output-overlay))
603    
604  ;; Set to nil initially  ;; Set to nil initially
605  (setq idlwave-shell-stop-line-overlay nil  (setq idlwave-shell-stop-line-overlay nil
606        idlwave-shell-expression-overlay nil)        idlwave-shell-expression-overlay nil
607          idlwave-shell-output-overlay nil)
608    
609  ;; Define the shell stop overlay.  When left nil, the arrow will be used.  ;; Define the shell stop overlay.  When left nil, the arrow will be used.
610  (cond  (cond
# Line 488  the directory stack.") Line 621  the directory stack.")
621              window-system)                ; Window systems always              window-system)                ; Window systems always
622      (progn      (progn
623        (setq idlwave-shell-stop-line-overlay (make-overlay 1 1))        (setq idlwave-shell-stop-line-overlay (make-overlay 1 1))
624        (overlay-put idlwave-shell-stop-line-overlay        (overlay-put idlwave-shell-stop-line-overlay
625                     'face idlwave-shell-stop-line-face))))                     'face idlwave-shell-stop-line-face))))
626    
627   (t   (t
# Line 496  the directory stack.") Line 629  the directory stack.")
629    (if window-system    (if window-system
630        (progn        (progn
631          (setq idlwave-shell-stop-line-overlay (make-overlay 1 1))          (setq idlwave-shell-stop-line-overlay (make-overlay 1 1))
632          (overlay-put idlwave-shell-stop-line-overlay          (overlay-put idlwave-shell-stop-line-overlay
633                       'face idlwave-shell-stop-line-face)))))                       'face idlwave-shell-stop-line-face)))))
634    
635  ;; Now the expression overlay  ;; Now the expression and output overlays
636  (setq idlwave-shell-expression-overlay (make-overlay 1 1))  (setq idlwave-shell-expression-overlay (make-overlay 1 1))
637  (overlay-put idlwave-shell-expression-overlay  (overlay-put idlwave-shell-expression-overlay
638               'face idlwave-shell-expression-face)               'face idlwave-shell-expression-face)
639    (setq idlwave-shell-output-overlay (make-overlay 1 1))
640    (overlay-put idlwave-shell-output-overlay
641                 'face idlwave-shell-output-face)
642    
643  (defvar idlwave-shell-bp-query "help,/breakpoints"  (defvar idlwave-shell-bp-query "help,/breakpoints"
644    "Command to obtain list of breakpoints")    "Command to obtain list of breakpoints")
645    
# Line 514  the directory stack.") Line 651  the directory stack.")
651  The current command is finished when the IDL prompt is displayed.  The current command is finished when the IDL prompt is displayed.
652  This is evaluated if it is a list or called with funcall.")  This is evaluated if it is a list or called with funcall.")
653    
654    (defvar idlwave-shell-sentinel-hook nil
655      "Hook run when the idl process exits.")
656    
657  (defvar idlwave-shell-hide-output nil  (defvar idlwave-shell-hide-output nil
658    "If non-nil the process output is not inserted into the output    "If non-nil the process output is not inserted into the output
659    buffer.")    buffer.")
# Line 541  with `*'s." Line 681  with `*'s."
681  (defvar idlwave-shell-ready nil  (defvar idlwave-shell-ready nil
682    "If non-nil can send next command to IDL process.")    "If non-nil can send next command to IDL process.")
683    
684    (defvar idlwave-shell-wait-for-output nil
685      "Whether to wait for output to accumulate.")
686    
687  ;;; The following are the types of messages we attempt to catch to  ;;; The following are the types of messages we attempt to catch to
688  ;;; resync our idea of where IDL execution currently is.  ;;; resync our idea of where IDL execution currently is.
689  ;;;  ;;;
690    
691  (defvar idlwave-shell-halt-frame nil  (defvar idlwave-shell-halt-frame nil
692    "The frame associated with halt/breakpoint messages.")    "The frame associated with halt/breakpoint messages.")
# Line 629  IDL has currently stepped.") Line 772  IDL has currently stepped.")
772     `\\[idlwave-routine-info]' displays information about an IDL routine near point,     `\\[idlwave-routine-info]' displays information about an IDL routine near point,
773     just like in `idlwave-mode'.  The module used is the one at point or     just like in `idlwave-mode'.  The module used is the one at point or
774     the one whose argument list is being edited.     the one whose argument list is being edited.
775     To update IDLWAVE's knowledge about compiled or edited modules, use     To update IDLWAVE's knowledge about compiled or edited modules, use
776     \\[idlwave-update-routine-info].     \\[idlwave-update-routine-info].
777     \\[idlwave-find-module] find the source of a module.     \\[idlwave-find-module] find the source of a module.
778     \\[idlwave-resolve] tells IDL to compile an unresolved module.     \\[idlwave-resolve] tells IDL to compile an unresolved module.
779     \\[idlwave-context-help] shows the online help on the item at     \\[idlwave-context-help] shows the online help on the item at
780     point, if online help has been installed.     point, if online help has been installed.
781      
782    
783  4. Debugging  4. Debugging
784     ---------     ---------
785     A complete set of commands for compiling and debugging IDL programs     A complete set of commands for compiling and debugging IDL programs
786     is available from the menu.  Also keybindings starting with a     is available from the menu.  Also keybindings starting with a
787     `C-c C-d' prefix are available for most commands in the *idl* buffer     `C-c C-d' prefix are available for most commands in the *idl* buffer
788     and also in source buffers.  The best place to learn about the     and also in source buffers.  The best place to learn about the
789     keybindings is again the menu.     keybindings is again the menu.
# Line 665  IDL has currently stepped.") Line 808  IDL has currently stepped.")
808     Info documentation for this package is available.  Use \\[idlwave-info]     Info documentation for this package is available.  Use \\[idlwave-info]
809     to display (complain to your sysadmin if that does not work).     to display (complain to your sysadmin if that does not work).
810     For Postscript and HTML versions of the documentation, check IDLWAVE's     For Postscript and HTML versions of the documentation, check IDLWAVE's
811     homepage at `http://www.strw.leidenuniv.nl/~dominik/Tools/idlwave'.     homepage at `http://idlwave.org'.
812     IDLWAVE has customize support - see the group `idlwave'.     IDLWAVE has customize support - see the group `idlwave'.
813    
814  7. Keybindings  7. Keybindings
# Line 679  IDL has currently stepped.") Line 822  IDL has currently stepped.")
822    (setq comint-process-echoes t)    (setq comint-process-echoes t)
823    ;; Can not use history expansion because "!" is used for system variables.    ;; Can not use history expansion because "!" is used for system variables.
824    (setq comint-input-autoexpand nil)    (setq comint-input-autoexpand nil)
825    (setq comint-input-ring-size 64)  ;  (setq comint-input-ring-size 64)
826    (make-local-variable 'comint-completion-addsuffix)    (make-local-variable 'comint-completion-addsuffix)
827    (set (make-local-variable 'completion-ignore-case) t)    (set (make-local-variable 'completion-ignore-case) t)
828    (setq comint-completion-addsuffix '("/" . ""))    (setq comint-completion-addsuffix '("/" . ""))
# Line 713  IDL has currently stepped.") Line 856  IDL has currently stepped.")
856    (idlwave-shell-display-line nil)    (idlwave-shell-display-line nil)
857    (setq idlwave-shell-calling-stack-index 0)    (setq idlwave-shell-calling-stack-index 0)
858    
859      (when idlwave-shell-query-for-class
860          (add-to-list (make-local-variable 'idlwave-determine-class-special)
861                       'idlwave-shell-get-object-class)
862          (setq idlwave-store-inquired-class t))
863    
864    ;; Make sure comint-last-input-end does not go to beginning of    ;; Make sure comint-last-input-end does not go to beginning of
865    ;; buffer (in case there were other processes already in this buffer).    ;; buffer (in case there were other processes already in this buffer).
866    (set-marker comint-last-input-end (point))    (set-marker comint-last-input-end (point))
867    (setq idlwave-idlwave_routine_info-compiled nil)    (setq idlwave-idlwave_routine_info-compiled nil)
868    (setq idlwave-shell-ready nil)    (setq idlwave-shell-ready nil)
869      (setq idlwave-shell-wait-for-output nil)
870    (setq idlwave-shell-bp-alist nil)    (setq idlwave-shell-bp-alist nil)
871    (idlwave-shell-update-bp-overlays) ; Throw away old overlays    (idlwave-shell-update-bp-overlays) ; Throw away old overlays
872    (setq idlwave-shell-sources-alist nil)    (setq idlwave-shell-sources-alist nil)
873    (setq idlwave-shell-default-directory default-directory)    (setq idlwave-shell-default-directory default-directory)
874    (setq idlwave-shell-hide-output nil)    (setq idlwave-shell-hide-output nil)
875    
876      ;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
877      (make-local-hook 'kill-buffer-hook)
878    (add-hook 'kill-buffer-hook 'idlwave-shell-kill-shell-buffer-confirm    (add-hook 'kill-buffer-hook 'idlwave-shell-kill-shell-buffer-confirm
879              nil 'local)              nil 'local)
880    (add-hook 'kill-buffer-hook 'idlwave-shell-delete-temp-files nil 'local)    (add-hook 'kill-buffer-hook 'idlwave-shell-delete-temp-files nil 'local)
# Line 730  IDL has currently stepped.") Line 882  IDL has currently stepped.")
882    (use-local-map idlwave-shell-mode-map)    (use-local-map idlwave-shell-mode-map)
883    (easy-menu-add idlwave-shell-mode-menu idlwave-shell-mode-map)    (easy-menu-add idlwave-shell-mode-menu idlwave-shell-mode-map)
884    
885    (set (make-local-variable 'comint-scroll-to-bottom-on-input) t)    ;; Set the optional comint variables
886    (set (make-local-variable 'comint-scroll-show-maximum-output) t)    (when idlwave-shell-comint-settings
887        (let ((list idlwave-shell-comint-settings) entry)
888          (while (setq entry (pop list))
889            (set (make-local-variable (car entry)) (cdr entry)))))
890    
891    ;; IDLWAVE syntax, and turn on abbreviations    ;; IDLWAVE syntax, and turn on abbreviations
892    (setq local-abbrev-table idlwave-mode-abbrev-table)    (setq local-abbrev-table idlwave-mode-abbrev-table)
893    (set-syntax-table idlwave-mode-syntax-table)    (set-syntax-table idlwave-mode-syntax-table)
894    (set (make-local-variable 'comment-start) ";")    (set (make-local-variable 'comment-start) ";")
895    (setq abbrev-mode t)    (setq abbrev-mode t)
896    
897      ;; NB: `make-local-hook' needed for older/alternative Emacs compatibility
898      (make-local-hook 'post-command-hook)
899    (add-hook 'post-command-hook 'idlwave-command-hook nil t)    (add-hook 'post-command-hook 'idlwave-command-hook nil t)
900    
901      ;; Read the command history?
902      (when (and idlwave-shell-save-command-history
903                 (stringp idlwave-shell-command-history-file))
904        (set (make-local-variable 'comint-input-ring-file-name)
905             idlwave-shell-command-history-file)
906        (if (file-regular-p idlwave-shell-command-history-file)
907            (comint-read-input-ring)))
908    
909    ;; Run the hooks.    ;; Run the hooks.
910    (run-hooks 'idlwave-shell-mode-hook)    (run-hooks 'idlwave-shell-mode-hook)
911    (idlwave-shell-send-command idlwave-shell-initial-commands nil 'hide)    (idlwave-shell-send-command idlwave-shell-initial-commands nil 'hide)
912    ;; Define a system variable which knows the version of IDLWAVE    ;; Define a system variable which knows the version of IDLWAVE
913    (idlwave-shell-send-command    (idlwave-shell-send-command
914     (format "defsysv,'!idlwave_version','%s',1" idlwave-mode-version)     (format "defsysv,'!idlwave_version','%s',1" idlwave-mode-version)
915     nil 'hide)     nil 'hide)
916    (if (and (not idlwave-path-alist)    (if (and (not idlwave-path-alist)
# Line 780  IDL has currently stepped.") Line 946  IDL has currently stepped.")
946            ;; The frame exists, so we use it.            ;; The frame exists, so we use it.
947            idlwave-shell-display-wframe            idlwave-shell-display-wframe
948          ;; The frame does not exist.  We use the current frame.          ;; The frame does not exist.  We use the current frame.
949          ;; However, if the current is the shell frame, we make a new frame.          ;; However, if the current is the shell frame, we make a new frame,
950            ;; or recycle the first existing visible frame
951          (setq idlwave-shell-display-wframe          (setq idlwave-shell-display-wframe
952                (if (eq (selected-frame) idlwave-shell-idl-wframe)                (if (eq (selected-frame) idlwave-shell-idl-wframe)
953                    (make-frame)                    (or
954                       (let ((flist (visible-frame-list))
955                             (frame (selected-frame)))
956                         (catch 'exit
957                           (while flist
958                             (if (not (eq (car flist)
959                                          idlwave-shell-idl-wframe))
960                                 (throw 'exit (car flist))
961                               (setq flist (cdr flist))))))
962                       (make-frame))
963                  (selected-frame))))))                  (selected-frame))))))
964    
965  (defun idlwave-shell-shell-frame ()  (defun idlwave-shell-shell-frame ()
# Line 798  IDL has currently stepped.") Line 974  IDL has currently stepped.")
974              ;; We do not have a source frame, so we use this one.              ;; We do not have a source frame, so we use this one.
975              (setq idlwave-shell-display-wframe (selected-frame)))              (setq idlwave-shell-display-wframe (selected-frame)))
976          ;; Return a new frame          ;; Return a new frame
977          (setq idlwave-shell-idl-wframe          (setq idlwave-shell-idl-wframe
978                (make-frame idlwave-shell-frame-parameters)))))                (make-frame idlwave-shell-frame-parameters)))))
979      
980  ;;;###autoload  ;;;###autoload
981  (defun idlwave-shell (&optional arg)  (defun idlwave-shell (&optional arg quick)
982    "Run an inferior IDL, with I/O through buffer `(idlwave-shell-buffer)'.    "Run an inferior IDL, with I/O through buffer `(idlwave-shell-buffer)'.
983  If buffer exists but shell process is not running, start new IDL.  If buffer exists but shell process is not running, start new IDL.
984  If buffer exists and shell process is running, just switch to the buffer.  If buffer exists and shell process is running, just switch to the buffer.
# Line 811  When called with a prefix ARG, or when ` Line 987  When called with a prefix ARG, or when `
987  is non-nil, the shell buffer and the source buffers will be in  is non-nil, the shell buffer and the source buffers will be in
988  separate frames.  separate frames.
989    
990  The command to run comes from variable `idlwave-shell-explicit-file-name'.  The command to run comes from variable `idlwave-shell-explicit-file-name',
991    with options taken from `idlwave-shell-command-line-options'.
992    
993  The buffer is put in `idlwave-shell-mode', providing commands for sending  The buffer is put in `idlwave-shell-mode', providing commands for sending
994  input and controlling the IDL job.  See help on `idlwave-shell-mode'.  input and controlling the IDL job.  See help on `idlwave-shell-mode'.
# Line 819  See also the variable `idlwave-shell-pro Line 996  See also the variable `idlwave-shell-pro
996    
997  \(Type \\[describe-mode] in the shell buffer for a list of commands.)"  \(Type \\[describe-mode] in the shell buffer for a list of commands.)"
998    (interactive "P")    (interactive "P")
999      (if (eq arg 'quick)
1000    ;; A non-nil arg means, we want a dedicated frame.  This will last        (progn
1001    ;; for the current editing session.          (let ((idlwave-shell-use-dedicated-frame nil))
1002    (if arg (setq idlwave-shell-use-dedicated-frame t))            (idlwave-shell nil)
1003    (if (equal arg '(16)) (setq idlwave-shell-use-dedicated-frame nil))            (delete-other-windows))
1004            (and idlwave-shell-use-dedicated-frame
1005    ;; Check if the process still exists.  If not, create it.               (setq idlwave-shell-idl-wframe (selected-frame)))
1006    (unless (comint-check-proc (idlwave-shell-buffer))          (add-hook 'idlwave-shell-sentinel-hook
1007      (let* ((prg (or idlwave-shell-explicit-file-name "idl"))                    'save-buffers-kill-emacs t))
1008             (buf (apply 'make-comint  
1009                         idlwave-shell-process-name prg nil      ;; A non-nil arg means, we want a dedicated frame.  This will last
1010                         idlwave-shell-command-line-options))      ;; for the current editing session.
1011             (process (get-buffer-process buf)))      (if arg (setq idlwave-shell-use-dedicated-frame t))
1012        (setq idlwave-idlwave_routine_info-compiled nil)      (if (equal arg '(16)) (setq idlwave-shell-use-dedicated-frame nil))
1013        (set-process-filter process 'idlwave-shell-filter)  
1014        (set-process-sentinel process 'idlwave-shell-sentinel)      ;; Check if the process still exists.  If not, create it.
1015        (set-buffer buf)      (unless (comint-check-proc (idlwave-shell-buffer))
1016        (idlwave-shell-mode)))        (let* ((prg (or idlwave-shell-explicit-file-name "idl"))
1017    (let ((window (idlwave-display-buffer (idlwave-shell-buffer) nil               (buf (apply 'make-comint
1018                                          (idlwave-shell-shell-frame)))                           idlwave-shell-process-name prg nil
1019          (current-window (selected-window)))                           (if (stringp idlwave-shell-command-line-options)
1020      (select-window window)                               (idlwave-split-string
1021      (goto-char (point-max))                                idlwave-shell-command-line-options)
1022      (select-window current-window)                                 idlwave-shell-command-line-options)))
1023      (raise-frame (window-frame window))               (process (get-buffer-process buf)))
1024      (if (eq (selected-frame) (window-frame window))          (setq idlwave-idlwave_routine_info-compiled nil)
1025          (select-window window))          (set-process-filter process 'idlwave-shell-filter)
1026      ))          (set-process-sentinel process 'idlwave-shell-sentinel)
1027            (set-buffer buf)
1028            (idlwave-shell-mode)))
1029        (let ((window (idlwave-display-buffer (idlwave-shell-buffer) nil
1030                                              (idlwave-shell-shell-frame)))
1031              (current-window (selected-window)))
1032          (select-window window)
1033          (goto-char (point-max))
1034          (select-window current-window)
1035          (if idlwave-shell-ready
1036              (raise-frame (window-frame window)))
1037          (if (eq (selected-frame) (window-frame window))
1038              (select-window window))
1039          )))
1040    
1041  (defun idlwave-shell-recenter-shell-window (&optional arg)  (defun idlwave-shell-recenter-shell-window (&optional arg)
1042    "Run `idlwave-shell', but make sure the current window stays selected."    "Run `idlwave-shell', but make sure the current window stays selected."
# Line 855  See also the variable `idlwave-shell-pro Line 1045  See also the variable `idlwave-shell-pro
1045      (idlwave-shell arg)      (idlwave-shell arg)
1046      (select-window window)))      (select-window window)))
1047    
1048    (defun idlwave-shell-hide-p (type)
1049      "Whether to hide this type of command.
1050    Return either nil or 'hide."
1051      (if (listp idlwave-shell-show-commands)
1052          (if (not (memq type idlwave-shell-show-commands)) 'hide)))
1053    
1054  (defun idlwave-shell-send-command (&optional cmd pcmd hide preempt)  (defun idlwave-shell-send-command (&optional cmd pcmd hide preempt)
1055    "Send a command to IDL process.    "Send a command to IDL process.
1056    
1057  \(CMD PCMD HIDE\) are placed at the end of `idlwave-shell-pending-commands'.  \(CMD PCMD HIDE\) are placed at the end of
1058  If IDL is ready the first command, CMD, in  ` idlwave-shell-pending-commands'.  If IDL is ready the first command,
1059  `idlwave-shell-pending-commands' is sent to the IDL process.  If optional  CMD, in `idlwave-shell-pending-commands' is sent to the IDL process.
1060  second argument PCMD is non-nil it will be placed on  If optional second argument PCMD is non-nil it will be placed on
1061  `idlwave-shell-post-command-hook' when CMD is executed.  If the optional  `idlwave-shell-post-command-hook' when CMD is executed.  If the
1062  third argument HIDE is non-nil, then hide output from CMD.  optional third argument HIDE is non-nil, then hide output from CMD.
1063  If optional fourth argument PREEMPT is non-nil CMD is put at front of  If optional fourth argument PREEMPT is non-nil CMD is put at front of
1064  `idlwave-shell-pending-commands'.  `idlwave-shell-pending-commands'.  If PREEMPT is 'wait, wait for all
1065    output to complete and the next prompt to arrive before returning
1066  IDL is considered ready if the prompt is present  \(useful if you need an answer now\). IDL is considered ready if the
1067  and if `idlwave-shell-ready' is non-nil."  prompt is present and if `idlwave-shell-ready' is non-nil."
1068    
1069    ;(setq hide nil)  ;  FIXME: turn this on for debugging only  ;  (setq hide nil)  ;  FIXME: turn this on for debugging only
1070    (let (buf proc)  ;  (if (null cmd)
1071    ;      (progn
1072    ;       (message "SENDING Pending commands: %s"
1073    ;                (prin1-to-string idlwave-shell-pending-commands)))
1074    ;    (message "SENDING %s|||%s" cmd pcmd))
1075      (if (and (symbolp idlwave-shell-show-commands)
1076               (eq idlwave-shell-show-commands 'everything))
1077          (setq hide nil))
1078      (let ((save-buffer (current-buffer))
1079            buf proc)
1080      ;; Get or make the buffer and its process      ;; Get or make the buffer and its process
1081      (if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))      (if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))
1082              (not (setq proc (get-buffer-process buf))))              (not (setq proc (get-buffer-process buf))))
# Line 885  and if `idlwave-shell-ready' is non-nil. Line 1090  and if `idlwave-shell-ready' is non-nil.
1090                    (not (setq proc (get-buffer-process buf))))                    (not (setq proc (get-buffer-process buf))))
1091                ;; Still nothing                ;; Still nothing
1092                (error "Problem with autostarting IDL shell"))))                (error "Problem with autostarting IDL shell"))))
1093        (when (or cmd idlwave-shell-pending-commands)
     (save-excursion  
1094        (set-buffer buf)        (set-buffer buf)
       (goto-char (process-mark proc))  
1095        ;; To make this easy, always push CMD onto pending commands        ;; To make this easy, always push CMD onto pending commands
1096        (if cmd        (if cmd
1097            (setq idlwave-shell-pending-commands            (setq idlwave-shell-pending-commands
1098                  (if preempt                  (if preempt
1099                      ;; Put at front.                      ;; Put at front.
1100                      (append (list (list cmd pcmd hide))                      (append (list (list cmd pcmd hide))
1101                              idlwave-shell-pending-commands)                              idlwave-shell-pending-commands)
1102                    ;; Put at end.                    ;; Put at end.
1103                    (append idlwave-shell-pending-commands                    (append idlwave-shell-pending-commands
1104                            (list (list cmd pcmd hide))))))                            (list (list cmd pcmd hide))))))
1105        ;; Check if IDL ready        ;; Check if IDL ready
1106        (if (and idlwave-shell-ready        (let ((save-point (point-marker)))
1107                 ;; Check for IDL prompt          (goto-char (process-mark proc))
1108                 (save-excursion          (if (and idlwave-shell-ready
1109                   (forward-line 0)                   ;; Check for IDL prompt
1110                   ;; (beginning-of-line) ; Changed for Emacs 21                   (prog2
1111                   (looking-at idlwave-shell-prompt-pattern)))                     (forward-line 0)
1112            ;; IDL ready for command                     ;; (beginning-of-line) ; Changed for Emacs 21
1113            (if idlwave-shell-pending-commands                     (looking-at idlwave-shell-prompt-pattern)
1114                ;; execute command                     (goto-char (process-mark proc))))
1115                (let* ((lcmd (car idlwave-shell-pending-commands))              ;; IDL ready for command, execute it
1116                       (cmd (car lcmd))              (let* ((lcmd (car idlwave-shell-pending-commands))
1117                       (pcmd (nth 1 lcmd))                     (cmd (car lcmd))
1118                       (hide (nth 2 lcmd)))                     (pcmd (nth 1 lcmd))
1119                  ;; If this is an executive command, reset the stack pointer                     (hide (nth 2 lcmd)))
1120                  (if (eq (string-to-char cmd) ?.)                ;; If this is an executive command, reset the stack pointer
1121                      (setq idlwave-shell-calling-stack-index 0))                (if (eq (string-to-char cmd) ?.)
1122                  ;; Set post-command                    (setq idlwave-shell-calling-stack-index 0))
1123                  (setq idlwave-shell-post-command-hook pcmd)                ;; Set post-command
1124                  ;; Output hiding                (setq idlwave-shell-post-command-hook pcmd)
1125  ;;; Debug code                          ;; Output hiding
1126  ;;;             (setq idlwave-shell-hide-output nil)                (setq idlwave-shell-hide-output hide)
1127                  (setq idlwave-shell-hide-output hide)                ;; Pop command
1128                  ;; Pop command                (setq idlwave-shell-pending-commands
1129                  (setq idlwave-shell-pending-commands                      (cdr idlwave-shell-pending-commands))
1130                        (cdr idlwave-shell-pending-commands))                ;; Send command for execution
1131                  ;; Send command for execution                (set-marker comint-last-input-start (point))
1132                  (set-marker comint-last-input-start (point))                (set-marker comint-last-input-end (point))
1133                  (set-marker comint-last-input-end (point))                (comint-simple-send proc cmd)
1134                  (comint-simple-send proc cmd)                (setq idlwave-shell-ready nil)
1135                  (setq idlwave-shell-ready nil)))))))                (when (equal preempt 'wait) ; Get all the output at once
1136                    (setq idlwave-shell-wait-for-output t)
1137                    (accept-process-output proc))))
1138            (goto-char save-point))
1139          (set-buffer save-buffer))))
1140    
1141  (defun idlwave-shell-send-char (c &optional no-error)  (defun idlwave-shell-send-char (c &optional no-error)
1142    "Send one character to the shell, without a newline."    "Send one character to the shell, without a newline."
# Line 939  and if `idlwave-shell-ready' is non-nil. Line 1146  and if `idlwave-shell-ready' is non-nil.
1146      (if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))      (if (or (not (setq buf (get-buffer (idlwave-shell-buffer))))
1147              (not (setq proc (get-buffer-process buf))))              (not (setq proc (get-buffer-process buf))))
1148          (funcall errf "Shell is not running"))          (funcall errf "Shell is not running"))
1149      (if (equal c ?\C-g)      (if (equal c ?\C-g)
1150          (funcall errf "Abort")          (funcall errf "Abort")
1151        (comint-send-string proc (char-to-string c)))))        (comint-send-string proc (char-to-string c)))))
1152    
# Line 980  when the IDL prompt gets displayed again Line 1187  when the IDL prompt gets displayed again
1187      (if idlwave-shell-ready      (if idlwave-shell-ready
1188          (funcall errf "No IDL program seems to be waiting for input"))          (funcall errf "No IDL program seems to be waiting for input"))
1189    
1190      ;; OK, start the loop      ;; OK, start the loop
1191      (message "Character mode on:  Sending single chars (`C-g' to exit)")      (message "Character mode on:  Sending single chars (`C-g' to exit)")
1192      (message      (message
1193       (catch 'exit       (catch 'exit
# Line 1010  when the IDL prompt gets displayed again Line 1217  when the IDL prompt gets displayed again
1217             (and (eq idlwave-shell-char-mode-active 'exit)             (and (eq idlwave-shell-char-mode-active 'exit)
1218                  (throw 'exit "Single char loop exited"))))))))                  (throw 'exit "Single char loop exited"))))))))
1219    
1220  (defun idlwave-shell-up-or-history (&optional arg)  (defun idlwave-shell-move-or-history (up &optional arg)
1221    "When in last line of process buffer, do `comint-previous-input'.    "When in last line of process buffer, do `comint-previous-input'.
1222  Otherwise just do `previous-line'."  Otherwise just move the line.  Move down unless UP is non-nil."
1223      (let* ((proc-pos (marker-position
1224                        (process-mark (get-buffer-process (current-buffer)))))
1225             (arg (or arg 1))
1226             (arg (if up arg (- arg))))
1227        (if (eq t idlwave-shell-arrows-do-history) (goto-char proc-pos))
1228        (if (and idlwave-shell-arrows-do-history
1229                 (>= (1+ (save-excursion (end-of-line) (point))) proc-pos))
1230            (progn
1231              (goto-char proc-pos)
1232              (and (not (eolp)) (kill-line nil))
1233              (comint-previous-input arg))
1234          (previous-line arg))))
1235    
1236    (defun idlwave-shell-up-or-history (&optional arg)
1237    "When in last line of process buffer, move to previous input.
1238     Otherwise just go up one line."
1239    (interactive "p")    (interactive "p")
1240    (if (eq t idlwave-shell-arrows-do-history) (goto-char (point-max)))    (idlwave-shell-move-or-history t arg))
   (if (and idlwave-shell-arrows-do-history  
            (>= (1+ (save-excursion (end-of-line) (point)))  
                (marker-position  
                 (process-mark (get-buffer-process (current-buffer))))))  
       (progn  
         (and (not (eolp)) (kill-line nil))  
         (comint-previous-input arg))  
     (previous-line arg)))  
1241    
1242  (defun idlwave-shell-down-or-history (&optional arg)  (defun idlwave-shell-down-or-history (&optional arg)
1243    "When in last line of process buffer, do `comint-next-input'.  "When in last line of process buffer, move to next input.
1244   Otherwise just do `next-line'."   Otherwise just go down one line."
1245    (interactive "p")    (interactive "p")
1246    (if (eq t idlwave-shell-arrows-do-history) (goto-char (point-max)))    (idlwave-shell-move-or-history nil arg))
   (if (and idlwave-shell-arrows-do-history  
            (>= (1+ (save-excursion (end-of-line) (point)))  
                (marker-position  
                 (process-mark (get-buffer-process (current-buffer))))))  
       (progn  
         (and (not (eolp)) (kill-line nil))  
         (comint-next-input arg))  
     (next-line arg)))  
   
 ;; There was a report that a newer version of comint.el changed the  
 ;; name of comint-filter to comint-output-filter.  Unfortunately, we  
 ;; have yet to upgrade.  
1247    
1248    ;; Newer versions of comint.el changed the name of comint-filter to
1249    ;; comint-output-filter.
1250  (defun idlwave-shell-comint-filter (process string) nil)  (defun idlwave-shell-comint-filter (process string) nil)
1251  (if (fboundp 'comint-output-filter)  (if (fboundp 'comint-output-filter)
1252      (fset 'idlwave-shell-comint-filter (symbol-function 'comint-output-filter))      (fset 'idlwave-shell-comint-filter (symbol-function 'comint-output-filter))
# Line 1053  Otherwise just do `previous-line'." Line 1258  Otherwise just do `previous-line'."
1258    
1259  (defvar idlwave-shell-hidden-output-buffer " *idlwave-shell-hidden-output*"  (defvar idlwave-shell-hidden-output-buffer " *idlwave-shell-hidden-output*"
1260    "Buffer containing hidden output from IDL commands.")    "Buffer containing hidden output from IDL commands.")
1261      
1262  (defun idlwave-shell-filter (proc string)  (defun idlwave-shell-filter (proc string)
1263    "Replace Carriage returns in output. Watch for prompt.    "Replace Carriage returns in output. Watch for prompt.
1264  When the IDL prompt is received executes `idlwave-shell-post-command-hook'  When the IDL prompt is received executes `idlwave-shell-post-command-hook'
# Line 1061  and then calls `idlwave-shell-send-comma Line 1266  and then calls `idlwave-shell-send-comma
1266    ;; We no longer do the cleanup here - this is done by the process sentinel    ;; We no longer do the cleanup here - this is done by the process sentinel
1267    (when (eq (process-status idlwave-shell-process-name) 'run)    (when (eq (process-status idlwave-shell-process-name) 'run)
1268      ;; OK, process is still running, so we can use it.      ;; OK, process is still running, so we can use it.
1269      (let ((data (match-data)))      (let ((data (match-data)) p)
1270        (unwind-protect        (unwind-protect
1271            (progn            (progn
1272              ;; May change the original match data.              ;; May change the original match data.
1273              (let (p)              (while (setq p (string-match "\C-M" string))
1274                (while (setq p (string-match "\C-M" string))                (aset string p ?\  ))
1275                  (aset string p ?  )))  
 ;;; Test/Debug code  
 ;;          (save-excursion (set-buffer (get-buffer-create "*test*"))  
 ;;                          (goto-char (point-max))  
 ;;                          (insert "%%%" string))  
1276              ;;              ;;
1277              ;; Keep output              ;; Keep output
1278    
# Line 1083  and then calls `idlwave-shell-send-comma Line 1284  and then calls `idlwave-shell-send-comma
1284  ;           (setq idlwave-shell-command-output  ;           (setq idlwave-shell-command-output
1285  ;                 (concat idlwave-shell-command-output string))  ;                 (concat idlwave-shell-command-output string))
1286              ;; Insert the string. Do this before getting the              ;; Insert the string. Do this before getting the
1287              ;; state.              ;; state.
1288                (while (setq p (string-match "\C-G" string))
1289                  (ding)
1290                  (aset string p ?\C-j ))
1291              (if idlwave-shell-hide-output              (if idlwave-shell-hide-output
1292                  (save-excursion                  (save-excursion
1293                    (set-buffer                    (set-buffer
1294                     (get-buffer-create idlwave-shell-hidden-output-buffer))                     (get-buffer-create idlwave-shell-hidden-output-buffer))
1295                    (goto-char (point-max))                    (goto-char (point-max))
1296                    (insert string))                    (insert string))
1297                (idlwave-shell-comint-filter proc string))                (idlwave-shell-comint-filter proc string))
1298              ;; Watch for prompt - need to accumulate the current line              ;; Watch for magic - need to accumulate the current line
1299              ;; since it may not be sent all at once.              ;; since it may not be sent all at once.
1300              (if (string-match "\n" string)              (if (string-match "\n" string)
1301                  (progn                  (progn
# Line 1099  and then calls `idlwave-shell-send-comma Line 1303  and then calls `idlwave-shell-send-comma
1303                        (idlwave-shell-input-mode-magic                        (idlwave-shell-input-mode-magic
1304                         (concat idlwave-shell-accumulation string)))                         (concat idlwave-shell-accumulation string)))
1305                    (setq idlwave-shell-accumulation                    (setq idlwave-shell-accumulation
1306                          (substring string                          (substring string
1307                                     (progn (string-match "\\(.*\n\\)*" string)                                     (progn (string-match "\\(.*\n\\)*" string)
1308                                            (match-end 0)))))                                            (match-end 0)))))
1309                (setq idlwave-shell-accumulation                (setq idlwave-shell-accumulation
1310                      (concat idlwave-shell-accumulation string)))                      (concat idlwave-shell-accumulation string)))
1311    
1312    
             ;; Check for prompt in current line  
             (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-min))  
                         (re-search-forward idlwave-shell-prompt-pattern nil t)  
                         (setq idlwave-shell-command-output  
                               (buffer-substring (point-min) (point)))  
                         (delete-region (point-min) (point)))  
                     (setq idlwave-shell-command-output  
                           (save-excursion  
                             (set-buffer  
                              (process-buffer proc))  
                             (buffer-substring  
                              (progn  
                                (goto-char (process-mark proc))  
                                (beginning-of-line nil)  
                                (point))  
                              comint-last-input-end))))  
1313  ;;; Test/Debug code  ;;; Test/Debug code
1314  ;;                (save-excursion (set-buffer  ;            (save-excursion (set-buffer
1315  ;;                                 (get-buffer-create "*idlwave-shell-output*"))  ;                             (get-buffer-create "*idlwave-shell-output*"))
1316  ;;                                (goto-char (point-max))  ;                            (goto-char (point-max))
1317  ;;                                (insert "%%%" string))  ;                            (insert "\nSTRING===>\n" string "\n<====\n"))
1318    
1319                ;; Check for prompt in current accumulating output
1320                (if (setq idlwave-shell-ready
1321                          (string-match idlwave-shell-prompt-pattern
1322                                        idlwave-shell-accumulation))
1323                    (progn
1324                      (if idlwave-shell-hide-output
1325                          (save-excursion
1326                            (set-buffer idlwave-shell-hidden-output-buffer)
1327                            (goto-char (point-max))
1328                            (re-search-backward idlwave-shell-prompt-pattern nil t)
1329                            (goto-char (match-end 0))
1330                            (setq idlwave-shell-command-output
1331                                  (buffer-substring (point-min) (point)))
1332    
1333    ;;; Test/Debug
1334    ;                        (save-excursion (set-buffer
1335    ;                                         (get-buffer-create "*idlwave-shell-output*"))
1336    ;                                        (goto-char (point-max))
1337    ;                                        (insert "\nOUPUT===>\n" idlwave-shell-command-output "\n<===\n"))
1338    
1339                            (delete-region (point-min) (point)))
1340                        (setq idlwave-shell-command-output
1341                              (with-current-buffer (process-buffer proc)
1342                                (buffer-substring
1343                                 (save-excursion
1344                                   (goto-char (process-mark proc))
1345                                   (beginning-of-line nil)
1346                                   (point))
1347                                 comint-last-input-end))))
1348    
1349                    ;; Scan for state and do post command - bracket them                    ;; Scan for state and do post command - bracket them
1350                    ;; with idlwave-shell-ready=nil since they                    ;; with idlwave-shell-ready=nil since they
1351                    ;; may call idlwave-shell-send-command.                    ;; may call idlwave-shell-send-command.
# Line 1149  and then calls `idlwave-shell-send-comma Line 1361  and then calls `idlwave-shell-send-comma
1361                      (setq idlwave-shell-accumulation nil                      (setq idlwave-shell-accumulation nil
1362                            idlwave-shell-command-output nil                            idlwave-shell-command-output nil
1363                            idlwave-shell-post-command-hook nil                            idlwave-shell-post-command-hook nil
1364                            idlwave-shell-hide-output nil))                            idlwave-shell-hide-output nil
1365                              idlwave-shell-wait-for-output nil))
1366                    ;; Done with post command. Do pending command if                    ;; Done with post command. Do pending command if
1367                    ;; any.                    ;; any.
1368                    (idlwave-shell-send-command))))                    (idlwave-shell-send-command))
1369                  ;; We didn't get the prompt yet... maybe accept more output
1370                  (when idlwave-shell-wait-for-output
1371    ;;; Test/Debug code
1372    ;               (save-excursion (set-buffer
1373    ;                                (get-buffer-create "*idlwave-shell-output*"))
1374    ;                               (goto-char (point-max))
1375    ;                               (insert "\n<=== WAITING ON OUTPUT ==>\n"))
1376                      (accept-process-output proc nil 100))))
1377          (store-match-data data)))))          (store-match-data data)))))
1378    
1379  (defun idlwave-shell-sentinel (process event)  (defun idlwave-shell-sentinel (process event)
# Line 1163  and then calls `idlwave-shell-send-comma Line 1384  and then calls `idlwave-shell-send-comma
1384        (save-excursion        (save-excursion
1385          (set-buffer (idlwave-shell-buffer))          (set-buffer (idlwave-shell-buffer))
1386          (goto-char (point-max))          (goto-char (point-max))
1387          (insert (format "\n\n  Process %s %s" process event))))          (insert (format "\n\n  Process %s %s" process event))
1388            (if (and idlwave-shell-save-command-history
1389                     (stringp idlwave-shell-command-history-file))
1390                (condition-case nil
1391                    (comint-write-input-ring)
1392                  (error nil)))))
1393    
1394      (when (and (> (length (frame-list)) 1)      (when (and (> (length (frame-list)) 1)
1395                 (frame-live-p idlwave-shell-idl-wframe))                 (frame-live-p idlwave-shell-idl-wframe))
1396        (delete-frame idlwave-shell-idl-wframe)        (delete-frame idlwave-shell-idl-wframe)
1397        (setq idlwave-shell-idl-wframe nil        (setq idlwave-shell-idl-wframe nil
1398              idlwave-shell-display-wframe nil))              idlwave-shell-display-wframe nil))
1399      (when (window-live-p win)      (when (and (window-live-p win)
1400                   (not (one-window-p 'nomini)))
1401        (delete-window win))        (delete-window win))
1402      (idlwave-shell-cleanup)))      (idlwave-shell-cleanup)
1403        ;; Run the hook, if possible in the shell buffer.
1404        (if (get-buffer buf)
1405            (save-excursion
1406              (set-buffer buf)
1407              (run-hooks 'idlwave-shell-sentinel-hook))
1408          (run-hooks 'idlwave-shell-sentinel-hook))))
1409    
1410  (defun idlwave-shell-scan-for-state ()  (defun idlwave-shell-scan-for-state ()
1411    "Scan for state info.    "Scan for state info.
# Line 1182  messages.  We ignore error messages othe Line 1416  messages.  We ignore error messages othe
1416  For breakpoint messages process any attached count or command  For breakpoint messages process any attached count or command
1417  parameters.  parameters.
1418  Update the windows if a message is found."  Update the windows if a message is found."
1419    (let (update)    (cond
1420      (cond     ;; Make sure we have output
1421       ;; Make sure we have output     ((not idlwave-shell-command-output))
      ((not idlwave-shell-command-output))  
1422    
1423       ;; Various types of HALT messages.     ;; First Priority: Syntax and other errors
1424       ((string-match idlwave-shell-halt-messages-re     ((or
1425                      idlwave-shell-command-output)       (string-match idlwave-shell-syntax-error idlwave-shell-command-output)
1426        ;; Grab the file and line state info.       (string-match idlwave-shell-other-error idlwave-shell-command-output))
1427        (setq idlwave-shell-calling-stack-index 0)      (save-excursion
1428        (setq idlwave-shell-halt-frame        (set-buffer
1429              (idlwave-shell-parse-line         (get-buffer-create idlwave-shell-error-buffer))
1430               (substring idlwave-shell-command-output (match-end 0)))        (erase-buffer)
1431              update t))        (insert idlwave-shell-command-output)
1432          (goto-char (point-min))
1433       ;; Handle breakpoints separately        (setq idlwave-shell-error-last (point)))
1434       ((string-match idlwave-shell-break-message      (idlwave-shell-goto-next-error))
                     idlwave-shell-command-output)  
       (setq idlwave-shell-calling-stack-index 0)  
       (setq idlwave-shell-halt-frame  
             (idlwave-shell-parse-line  
              (substring idlwave-shell-command-output (match-end 0)))  
             update t)  
       ;; We used to to counting hits on breakpoints  
       ;; this is no longer supported since IDL breakpoints  
       ;; have learned counting.  
       ;; Do breakpoint command processing  
       (let ((bp (assoc  
                  (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)))))  
   
     ;; Handle compilation errors in addition to the above  
     (if (and idlwave-shell-command-output  
              (or (string-match  
                   idlwave-shell-syntax-error idlwave-shell-command-output)  
                  (string-match  
                   idlwave-shell-other-error idlwave-shell-command-output)))  
         (progn  
           (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)))  
       
     ;; Do update  
     (when update  
       (idlwave-shell-display-line (idlwave-shell-pc-frame)))))  
1435    
1436       ;; Second Priority: Various types of HALT messages.
1437       ((string-match idlwave-shell-halt-messages-re
1438                      idlwave-shell-command-output)
1439        ;; Grab the file and line state info.
1440        (setq idlwave-shell-calling-stack-index 0)
1441        (setq idlwave-shell-halt-frame
1442              (idlwave-shell-parse-line
1443               (substring idlwave-shell-command-output (match-end 0))))
1444        (idlwave-shell-display-line (idlwave-shell-pc-frame)))
1445    
1446       ;; Last Priority: Breakpoints
1447       ((string-match idlwave-shell-break-message
1448                      idlwave-shell-command-output)
1449        (setq idlwave-shell-calling-stack-index 0)
1450        (setq idlwave-shell-halt-frame
1451              (idlwave-shell-parse-line
1452               (substring idlwave-shell-command-output (match-end 0))))
1453        ;; We used to count hits on breakpoints
1454        ;; this is no longer supported since IDL breakpoints
1455        ;; have learned counting.
1456        ;; Do breakpoint command processing
1457        (let ((bp (assoc
1458                   (list
1459                    (nth 0 idlwave-shell-halt-frame)
1460                    (nth 1 idlwave-shell-halt-frame))
1461                   idlwave-shell-bp-alist)))
1462          (if bp
1463              (let ((cmd (idlwave-shell-bp-get bp 'cmd)))
1464                (if cmd
1465                    ;; Execute command
1466                    (if (listp cmd) (eval cmd) (funcall cmd))))
1467            ;; A breakpoint that we did not know about - perhaps it was
1468            ;; set by the user or IDL isn't reporting breakpoints like
1469            ;; we expect.  Lets update our list.
1470            (idlwave-shell-bp-query)))
1471        (idlwave-shell-display-line (idlwave-shell-pc-frame)))))
1472    
1473  (defvar idlwave-shell-error-buffer " *idlwave-shell-errors*"  (defvar idlwave-shell-error-buffer " *idlwave-shell-errors*"
1474    "Buffer containing syntax errors from IDL compilations.")    "Buffer containing syntax errors from IDL compilations.")
1475    
   
1476  ;; FIXME: the following two variables do not currently allow line breaks  ;; FIXME: the following two variables do not currently allow line breaks
1477  ;; in module and file names.  I am not sure if it will be necessary to  ;; in module and file names.  I am not sure if it will be necessary to
1478  ;; change this.  Currently it seems to work the way it is.  ;; change this.  Currently it seems to work the way it is.
1479  (defvar idlwave-shell-syntax-error  (defvar idlwave-shell-syntax-error
1480    "^% Syntax error.\\s-*\n\\s-*At:\\s-*\\(.*\\),\\s-*Line\\s-*\\(.*\\)"      "^% Syntax error.\\s-*\n\\s-*At:\\s-*\\(.*\\),\\s-*Line\\s-*\\(.*\\)"
1481    "A regular expression to match an IDL syntax error.    "A regular expression to match an IDL syntax error.
1482  The first \(..\) pair should match the file name.  The second pair  The first \(..\) pair should match the file name.  The second pair
1483  should match the line number.")  should match the line number.")
# Line 1267  The first \(..\) pair should match the f Line 1489  The first \(..\) pair should match the f
1489  should match the line number.")  should match the line number.")
1490    
1491  (defvar idlwave-shell-file-line-message  (defvar idlwave-shell-file-line-message
1492    (concat    (concat
1493     "\\("                                 ; program name group (1)     "\\("                                 ; program name group (1)
1494     "\\<[a-zA-Z][a-zA-Z0-9_$:]*"          ; start with a letter, followed by [..]     "\\<[a-zA-Z][a-zA-Z0-9_$:]*"          ; start with a letter, followed by [..]
1495     "\\([ \t]*\n[ \t]*[a-zA-Z0-9_$:]+\\)*"; continuation lines program name (2)     "\\([ \t]*\n[ \t]*[a-zA-Z0-9_$:]+\\)*"; continuation lines program name (2)
# Line 1284  should match the line number.") Line 1506  should match the line number.")
1506     "\\)"                                 ; end line number group (5)     "\\)"                                 ; end line number group (5)
1507     )     )
1508    "*A regular expression to parse out the file name and line number.    "*A regular expression to parse out the file name and line number.
1509  The 1st group should match the subroutine name.    The 1st group should match the subroutine name.
1510  The 3rd group is the line number.  The 3rd group is the line number.
1511  The 5th group is the file name.  The 5th group is the file name.
1512  All parts may contain linebreaks surrounded by spaces.  This is important  All parts may contain linebreaks surrounded by spaces.  This is important
# Line 1296  We need to work hard here to remove the Line 1518  We need to work hard here to remove the
1518  IDL5.  These line breaks can be right in the middle of procedure  IDL5.  These line breaks can be right in the middle of procedure
1519  or file names.  or file names.
1520  It is very difficult to come up with a robust solution.  This one seems  It is very difficult to come up with a robust solution.  This one seems
1521  to be pretty good though.    to be pretty good though.
1522    
1523  Here is in what ways it improves over the previous solution:  Here is in what ways it improves over the previous solution:
1524    
# Line 1313  plus garbage match an existing regular f Line 1535  plus garbage match an existing regular f
1535  unlikely."  unlikely."
1536    
1537    (let (number procedure file)    (let (number procedure file)
1538      (when (string-match idlwave-shell-file-line-message string)      (when (and (not (string-match ":\\s-*\\$MAIN" string))
1539                    (string-match idlwave-shell-file-line-message string))
1540        (setq procedure (match-string 1 string)        (setq procedure (match-string 1 string)
1541              number (match-string 3 string)              number (match-string 3 string)
1542              file (match-string 5 string))              file (match-string 5 string))
1543            
1544        ;; Repair the strings        ;; Repair the strings
1545        (setq procedure (idlwave-shell-repair-string procedure))        (setq procedure (idlwave-shell-repair-string procedure))
1546        (setq number (idlwave-shell-repair-string number))        (setq number (idlwave-shell-repair-string number))
# Line 1343  The last line of STRING may be garbage - Line 1566  The last line of STRING may be garbage -
1566  file name."  file name."
1567    (let ((file1 "") (file2 "") (start 0))    (let ((file1 "") (file2 "") (start 0))
1568      ;; We scan no further than to the next "^%" line      ;; We scan no further than to the next "^%" line
1569      (if (string-match "^%" file)      (if (string-match "^%" file)
1570          (setq file (substring file 0 (match-beginning 0))))          (setq file (substring file 0 (match-beginning 0))))
1571      ;; Take out the line breaks      ;; Take out the line breaks
1572      (while (string-match "[ \t]*\n[ \t]*" file start)      (while (string-match "[ \t]*\n[ \t]*" file start)
# Line 1398  file name." Line 1621  file name."
1621  The size is given by `idlwave-shell-graphics-window-size'."  The size is given by `idlwave-shell-graphics-window-size'."
1622    (interactive "P")    (interactive "P")
1623    (let ((n (if n (prefix-numeric-value n) 0)))    (let ((n (if n (prefix-numeric-value n) 0)))
1624      (idlwave-shell-send-command      (idlwave-shell-send-command
1625       (apply 'format "window,%d,xs=%d,ys=%d"       (apply 'format "window,%d,xs=%d,ys=%d"
1626              n idlwave-shell-graphics-window-size))))              n idlwave-shell-graphics-window-size)
1627         nil (idlwave-shell-hide-p 'misc))))
1628    
1629  (defun idlwave-shell-resync-dirs ()  (defun idlwave-shell-resync-dirs ()
1630    "Resync the buffer's idea of the current directory stack.    "Resync the buffer's idea of the current directory.
1631  This command queries IDL with the command bound to  This command queries IDL with the command bound to
1632  `idlwave-shell-dirstack-query' (default \"printd\"), reads the  `idlwave-shell-dirstack-query', reads the output for the new
1633  output for the new directory stack."  directory."
1634    (interactive)    (interactive)
1635    (idlwave-shell-send-command idlwave-shell-dirstack-query    (idlwave-shell-send-command idlwave-shell-dirstack-query
1636                                'idlwave-shell-filter-directory                                'idlwave-shell-filter-directory
1637                                'hide))                                'hide 'wait))
1638    
1639  (defun idlwave-shell-retall (&optional arg)  (defun idlwave-shell-retall (&optional arg)
1640    "Return from the entire calling stack."    "Return from the entire calling stack."
1641    (interactive "P")    (interactive "P")
1642    (idlwave-shell-send-command "retall"))    (idlwave-shell-send-command "retall" nil (idlwave-shell-hide-p 'misc)))
1643    
1644  (defun idlwave-shell-closeall (&optional arg)  (defun idlwave-shell-closeall (&optional arg)
1645    "Close all open files."    "Close all open files."
1646    (interactive "P")    (interactive "P")
1647    (idlwave-shell-send-command "close,/all"))    (idlwave-shell-send-command "close,/all" nil (idlwave-shell-hide-p 'misc)))
1648    
1649  (defun idlwave-shell-quit (&optional arg)  (defun idlwave-shell-quit (&optional arg)
1650    "Exit the idl process after confirmation.    "Exit the idl process after confirmation.
# Line 1434  With prefix ARG, exit without confirmati Line 1658  With prefix ARG, exit without confirmati
1658            (error nil)))))            (error nil)))))
1659    
1660  (defun idlwave-shell-reset (&optional hidden)  (defun idlwave-shell-reset (&optional hidden)
1661    "Reset IDL.  Return to main level and destroy the leaftover variables.    "Reset IDL.  Return to main level and destroy the leftover variables.
1662  This issues the following commands:    This issues the following commands:
1663  RETALL  RETALL
1664  WIDGET_CONTROL,/RESET  WIDGET_CONTROL,/RESET
1665  CLOSE, /ALL  CLOSE, /ALL
# Line 1471  HEAP_GC, /VERBOSE" Line 1695  HEAP_GC, /VERBOSE"
1695    (let ((text idlwave-shell-command-output)    (let ((text idlwave-shell-command-output)
1696          (start 0)          (start 0)
1697          sep sep-re file type spec specs name cs key keys class entry)          sep sep-re file type spec specs name cs key keys class entry)
1698    ;    (message "GOT: %s" text) ;??????????????????????
1699      ;; Initialize variables      ;; Initialize variables
1700      (setq idlwave-compiled-routines nil      (setq idlwave-compiled-routines nil
1701            idlwave-unresolved-routines nil)            idlwave-unresolved-routines nil)
# Line 1483  HEAP_GC, /VERBOSE" Line 1708  HEAP_GC, /VERBOSE"
1708                text (substring text (match-end 0)))                text (substring text (match-end 0)))
1709        ;; Set dummy values and kill the text        ;; Set dummy values and kill the text
1710        (setq sep "@" sep-re "@ *" text "")        (setq sep "@" sep-re "@ *" text "")
1711        (message "Routine Info warning: No match for BEGIN line"))        (message "Routine Info warning: No match for BEGIN line in \n>>>>\n%s\n<<<<\n"
1712                   idlwave-shell-command-output))
1713      (if (string-match "^>>>END OF IDLWAVE ROUTINE INFO.*" text)      (if (string-match "^>>>END OF IDLWAVE ROUTINE INFO.*" text)
1714          (setq text (substring text 0 (match-beginning 0)))          (setq text (substring text 0 (match-beginning 0)))
1715        (message "Routine Info warning: No match for END line"))        (message "Routine Info warning: No match for END line in \n>>>>\n%s\n<<<<\n"
1716                   idlwave-shell-command-output))
1717      (if (string-match "\\S-" text)      (if (string-match "\\S-" text)
1718          ;; Obviously, the pro worked.  Make a note that we have it now.          ;; Obviously, the pro worked.  Make a note that we have it now.
1719          (setq idlwave-idlwave_routine_info-compiled t))          (setq idlwave-idlwave_routine_info-compiled t))
# Line 1503  HEAP_GC, /VERBOSE" Line 1730  HEAP_GC, /VERBOSE"
1730              key (nth 4 specs)              key (nth 4 specs)
1731              keys (if (and (stringp key)              keys (if (and (stringp key)
1732                            (not (string-match "\\` *\\'" key)))                            (not (string-match "\\` *\\'" key)))
1733                       (mapcar 'list                       (mapcar 'list
1734                               (delete "" (idlwave-split-string key " +")))))                               (delete "" (idlwave-split-string key " +")))))
1735        (setq name (idlwave-sintern-routine-or-method name class t)        (setq name (idlwave-sintern-routine-or-method name class t)
1736              class (idlwave-sintern-class class t)              class (idlwave-sintern-class class t)
1737              file (if (equal file "") nil file)              file (if (equal file "") nil file)
1738              keys (mapcar (lambda (x)              keys (mapcar (lambda (x)
1739                             (list (idlwave-sintern-keyword (car x) t))) keys))                             (list (idlwave-sintern-keyword (car x) t))) keys))
1740        ;; Make sure we use the same string object for the same file        ;; Make sure we use the same string object for the same file
1741        (setq file (idlwave-sintern-file file t))        (setq file (idlwave-sintern-file file t))
# Line 1520  HEAP_GC, /VERBOSE" Line 1747  HEAP_GC, /VERBOSE"
1747    
1748        ;; In the following ignore routines already defined in buffers,        ;; In the following ignore routines already defined in buffers,
1749        ;; assuming that if the buffer stuff differs, it is a "new"        ;; assuming that if the buffer stuff differs, it is a "new"
1750        ;; version.        ;; version.
1751        ;; We could do the same for the library to avoid duplicates -        ;; We could do the same for the library to avoid duplicates -
1752        ;; but I think frequently a user might have several versions of        ;; but I think frequently a user might have several versions of
1753        ;; the same function in different programs, and in this case the        ;; the same function in different programs, and in this case the
1754        ;; compiled one will be the best guess of all version.        ;; compiled one will be the best guess of all version.
1755        ;; Therefore, we leave duplicates of library routines in.        ;; Therefore, we leave duplicates of library routines in.
1756    
# Line 1531  HEAP_GC, /VERBOSE" Line 1758  HEAP_GC, /VERBOSE"
1758              ((and (string= type "PRO")              ((and (string= type "PRO")
1759                    ;; FIXME: is it OK to make the buffer routines dominate?                    ;; FIXME: is it OK to make the buffer routines dominate?
1760                    (or t (null file)                    (or t (null file)
1761                        (not (idlwave-rinfo-assq name 'pro class                        (not (idlwave-rinfo-assq name 'pro class
1762                                                 idlwave-buffer-routines)))                                                 idlwave-buffer-routines)))
1763                    ;; FIXME: is it OK to make the library routines dominate?                    ;; FIXME: is it OK to make the library routines dominate?
1764                    ;;(not (idlwave-rinfo-assq name 'pro class                    ;;(not (idlwave-rinfo-assq name 'pro class
1765                    ;;                       idlwave-library-routines))                    ;;                       idlwave-library-routines))
1766                    )                    )
1767               (setq entry (list name 'pro class (cons 'compiled file) cs keys))               (setq entry (list name 'pro class (cons 'compiled file) cs keys))
1768               (if file               (if file
1769                   (push entry idlwave-compiled-routines)                   (push entry idlwave-compiled-routines)
1770                 (push entry idlwave-unresolved-routines)))                 (push entry idlwave-unresolved-routines)))
1771                  
1772              ((and (string= type "FUN")              ((and (string= type "FUN")
1773                    ;; FIXME: is it OK to make the buffer routines dominate?                    ;; FIXME: is it OK to make the buffer routines dominate?
1774                    (or t (not file)                    (or t (not file)
1775                        (not (idlwave-rinfo-assq name 'fun class                        (not (idlwave-rinfo-assq name 'fun class
1776                                                 idlwave-buffer-routines)))                                                 idlwave-buffer-routines)))
1777                    ;; FIXME: is it OK to make the library routines dominate?                    ;; FIXME: is it OK to make the library routines dominate?
1778                    ;; (not (idlwave-rinfo-assq name 'fun class                    ;; (not (idlwave-rinfo-assq name 'fun class
1779                    ;;                       idlwave-library-routines))                    ;;                       idlwave-library-routines))
1780                    )                    )
1781               (setq entry (list name 'fun class (cons 'compiled file) cs keys))               (setq entry (list name 'fun class (cons 'compiled file) cs keys))
# Line 1564  HEAP_GC, /VERBOSE" Line 1791  HEAP_GC, /VERBOSE"
1791  Change the default directory for the process buffer to concur."  Change the default directory for the process buffer to concur."
1792    (save-excursion    (save-excursion
1793      (set-buffer (idlwave-shell-buffer))      (set-buffer (idlwave-shell-buffer))
1794      (if (string-match "Current Directory: *\\(\\S-*\\) *$"      (if (string-match ",___cur[\n\r]\\(\\S-*\\) *[\n\r]"
1795                        idlwave-shell-command-output)                        idlwave-shell-command-output)
1796          (let ((dir (substring idlwave-shell-command-output          (let ((dir (substring idlwave-shell-command-output
1797                                (match-beginning 1) (match-end 1))))                                (match-beginning 1) (match-end 1))))
1798            (message "Setting Emacs wd to %s" dir)  ;         (message "Setting Emacs working dir to %s" dir)
1799            (setq idlwave-shell-default-directory dir)            (setq idlwave-shell-default-directory dir)
1800            (setq default-directory (file-name-as-directory dir))))))            (setq default-directory (file-name-as-directory dir))))))
1801    
1802    (defvar idlwave-shell-get-object-class nil)
1803    (defun idlwave-shell-get-object-class (apos)
1804      "Query the shell for the class of the object before point."
1805      (let ((bos (save-excursion (idlwave-start-of-substatement 'pre) (point)))
1806            (bol (save-excursion (forward-line 0) (point)))
1807            expression)
1808        (save-excursion
1809          (goto-char apos)
1810          (setq expression (buffer-substring
1811                            (catch 'exit
1812                              (while t
1813                                (if (not (re-search-backward
1814                                          "[^][.A-Za-z0-9_() ]" bos t))
1815                                    (throw 'exit bos)) ;ran into bos
1816                                (if (not (idlwave-is-pointer-dereference bol))
1817                                    (throw 'exit (1+ (point))))))
1818                            apos)))
1819        (when (not (string= expression ""))
1820          (setq idlwave-shell-get-object-class nil)
1821          (idlwave-shell-send-command
1822           (concat "print,obj_class(" expression ")")
1823           'idlwave-shell-parse-object-class
1824           'hide 'wait)
1825          ;; If we don't know anything about the class, update shell routines
1826          (if (and idlwave-shell-get-object-class
1827                   (not (assoc-ignore-case idlwave-shell-get-object-class
1828                                           (idlwave-class-alist))))
1829              (idlwave-shell-maybe-update-routine-info))
1830          idlwave-shell-get-object-class)))
1831    
1832    (defun idlwave-shell-parse-object-class ()
1833      "Parse the output of the obj_class command."
1834      (let ((match "print,obj_class([^\n\r]+[\n\r ]+"))
1835        (if (and
1836             (not (string-match (concat match match "\\s-*^[\n\r]+"
1837                                        "% Syntax error")
1838                                idlwave-shell-command-output))
1839             (string-match (concat match "\\([A-Za-z_0-9]+\\)")
1840                           idlwave-shell-command-output))
1841            (setq idlwave-shell-get-object-class
1842                  (match-string 1 idlwave-shell-command-output)))))
1843    
1844    
1845  (defun idlwave-shell-complete (&optional arg)  (defun idlwave-shell-complete (&optional arg)
1846    "Do completion in the idlwave-shell buffer.    "Do completion in the idlwave-shell buffer.
1847  Calls `idlwave-shell-complete-filename' after some executive commands or  Calls `idlwave-shell-complete-filename' after some executive commands or
1848  in strings.  Otherwise, calls `idlwave-complete' to complete modules and  in strings.  Otherwise, calls `idlwave-complete' to complete modules and
1849  keywords."  keywords."
 ;;FIXME: batch files?  
1850    (interactive "P")    (interactive "P")
1851    (let (cmd)    (let (cmd)
1852      (cond      (cond
# Line 1588  keywords." Line 1857  keywords."
1857                      ".COM" ".COMP" ".COMPI" ".COMPIL" ".COMPILE"))                      ".COM" ".COMP" ".COMPI" ".COMPIL" ".COMPILE"))
1858            ;; This command expects file names            ;; This command expects file names
1859            (idlwave-shell-complete-filename)))            (idlwave-shell-complete-filename)))
1860    
1861         ((idlwave-shell-batch-command)
1862          (idlwave-shell-complete-filename))
1863    
1864       ((and (idlwave-shell-filename-string)       ((and (idlwave-shell-filename-string)
1865             (save-excursion             (save-excursion
1866               (beginning-of-line)               (beginning-of-line)
1867               (let ((case-fold-search t))               (let ((case-fold-search t))
1868                 (not (looking-at ".*obj_new"))))                 (not (looking-at ".*obj_new")))))
1869             ;; In a string, could be a file name to here        (idlwave-shell-complete-filename))
1870             (idlwave-shell-complete-filename)))  
1871       (t       (t
1872        ;; Default completion of modules and keywords        ;; Default completion of modules and keywords
1873        (idlwave-complete arg)))))        (idlwave-complete arg)))))
# Line 1602  keywords." Line 1875  keywords."
1875  (defun idlwave-shell-complete-filename (&optional arg)  (defun idlwave-shell-complete-filename (&optional arg)
1876    "Complete a file name at point if after a file name.    "Complete a file name at point if after a file name.
1877  We assume that we are after a file name when completing one of the  We assume that we are after a file name when completing one of the
1878  args of an executive .run, .rnew or .compile.  Also, in a string  args of an executive .run, .rnew or .compile."
1879  constant we complete file names.  Otherwise return nil, so that    ;; CWD might have changed, resync, to set default directory
1880  other completion functions can do thier work."    (idlwave-shell-resync-dirs)
1881    (let* ((comint-file-name-chars idlwave-shell-file-name-chars)    (let ((comint-file-name-chars idlwave-shell-file-name-chars))
1882           (completion-ignore-case (default-value 'completion-ignore-case)))      (comint-dynamic-complete-as-filename)))
     (comint-dynamic-complete-filename)))  
1883    
1884  (defun idlwave-shell-executive-command ()  (defun idlwave-shell-executive-command ()
1885    "Return the name of the current executive command, if any."    "Return the name of the current executive command, if any."
1886    (save-excursion    (save-excursion
1887      (idlwave-beginning-of-statement)      (idlwave-beginning-of-statement)
1888      (if (looking-at "[ \t]*\\([.][^ \t\n\r]*\\)")      (if (looking-at "[ \t]*\\([.][^ \t\n\r]+\\)")
1889          (match-string 1))))          (match-string 1))))
1890    
1891  (defun idlwave-shell-filename-string ()  (defun idlwave-shell-filename-string ()
# Line 1625  other completion functions can do thier Line 1897  other completion functions can do thier
1897        ;; Check of the next char is a string delimiter        ;; Check of the next char is a string delimiter
1898        (memq (preceding-char) '(?\' ?\")))))        (memq (preceding-char) '(?\' ?\")))))
1899    
1900    (defun idlwave-shell-batch-command ()
1901      "Returns t if we're in a batch command statement like @foo"
1902      (let ((limit (save-excursion (beginning-of-line) (point))))
1903        (save-excursion
1904          ;; Skip backwards over filename
1905          (skip-chars-backward idlwave-shell-file-name-chars limit)
1906          (skip-chars-backward " \t" limit)
1907          (and (eq (preceding-char) ?@) (not (idlwave-in-quote))))))
1908    
1909  ;;;  ;;;
1910  ;;; This section contains code for debugging IDL programs. --------------------  ;;; This section contains code for debugging IDL programs. --------------------
1911  ;;;  ;;;
1912    
1913  (defun idlwave-shell-redisplay (&optional hide)  (defun idlwave-shell-redisplay (&optional hide)
1914    "Tries to resync the display with where execution has stopped.    "Tries to resync the display with where execution has stopped.
1915  Issues a \"help,/trace\" command followed by a call to  Issues a \"help,/trace\" command followed by a call to
1916  `idlwave-shell-display-line'.  Also updates the breakpoint  `idlwave-shell-display-line'.  Also updates the breakpoint
1917  overlays."  overlays."
1918    (interactive)    (interactive)
# Line 1644  overlays." Line 1925  overlays."
1925    (idlwave-shell-bp-query))    (idlwave-shell-bp-query))
1926    
1927  (defun idlwave-shell-display-level-in-calling-stack (&optional hide)  (defun idlwave-shell-display-level-in-calling-stack (&optional hide)
1928    (idlwave-shell-send-command    (idlwave-shell-send-command
1929     "help,/trace"     "help,/trace"
1930     `(progn     `(progn
1931        ;; scanning for the state will reset the stack level - restore it        ;; scanning for the state will reset the stack level - restore it
# Line 1675  overlays." Line 1956  overlays."
1956        (setq idlwave-shell-calling-stack-index nmin        (setq idlwave-shell-calling-stack-index nmin
1957              message (format "%d is the current calling stack level - can't go further down"              message (format "%d is the current calling stack level - can't go further down"
1958                              (- nmin)))))                              (- nmin)))))
1959      (setq idlwave-shell-calling-stack-routine      (setq idlwave-shell-calling-stack-routine
1960            (nth 2 (nth idlwave-shell-calling-stack-index stack)))            (nth 2 (nth idlwave-shell-calling-stack-index stack)))
1961      (idlwave-shell-display-line      (idlwave-shell-display-line
1962       (nth idlwave-shell-calling-stack-index stack))       (nth idlwave-shell-calling-stack-index stack))
1963      (message (or message      (message (or message
1964                   (format "In routine %s (stack level %d)"                   (format "In routine %s (stack level %d)"
1965                           idlwave-shell-calling-stack-routine                           idlwave-shell-calling-stack-routine
1966                           (- idlwave-shell-calling-stack-index))))))                           (- idlwave-shell-calling-stack-index))))))
# Line 1710  used.  Does nothing if the resulting fra Line 1991  used.  Does nothing if the resulting fra
1991  (defun idlwave-shell-pc-frame ()  (defun idlwave-shell-pc-frame ()
1992    "Returns the frame for IDL execution."    "Returns the frame for IDL execution."
1993    (and idlwave-shell-halt-frame    (and idlwave-shell-halt-frame
1994         (list (nth 0 idlwave-shell-halt-frame)         (list (nth 0 idlwave-shell-halt-frame)
1995               (nth 1 idlwave-shell-halt-frame)               (nth 1 idlwave-shell-halt-frame)
1996               (nth 2 idlwave-shell-halt-frame))))               (nth 2 idlwave-shell-halt-frame))))
1997    
# Line 1725  FRAME is a list of file name, line numbe Line 2006  FRAME is a list of file name, line numbe
2006  If FRAME is nil then remove overlay."  If FRAME is nil then remove overlay."
2007    (if (not frame)    (if (not frame)
2008        ;; Remove stop-line overlay from old position        ;; Remove stop-line overlay from old position
2009        (progn        (progn
2010          (setq overlay-arrow-string nil)          (setq overlay-arrow-string nil)
2011          (setq idlwave-shell-mode-line-info nil)          (setq idlwave-shell-mode-line-info nil)
2012          (setq idlwave-shell-is-stopped nil)          (setq idlwave-shell-is-stopped nil)
# Line 1738  If FRAME is nil then remove overlay." Line 2019  If FRAME is nil then remove overlay."
2019  ;;;  ;;;
2020  ;;; buffer : the buffer to display a line in.  ;;; buffer : the buffer to display a line in.
2021  ;;; select-shell: current buffer is the shell.  ;;; select-shell: current buffer is the shell.
2022  ;;;  ;;;
2023        (setq idlwave-shell-mode-line-info        (setq idlwave-shell-mode-line-info
2024              (if (nth 2 frame)              (if (nth 2 frame)
2025                  (format "[%d:%s]"                  (format "[%d:%s]"
2026                          (- idlwave-shell-calling-stack-index)                          (- idlwave-shell-calling-stack-index)
2027                          (nth 2 frame))))                          (nth 2 frame))))
2028        (let* ((buffer (idlwave-find-file-noselect (car frame) 'shell))        (let* ((buffer (idlwave-find-file-noselect (car frame) 'shell))
# Line 1775  If FRAME is nil then remove overlay." Line 2056  If FRAME is nil then remove overlay."
2056                (or overlay-arrow-position  ; create the marker if necessary                (or overlay-arrow-position  ; create the marker if necessary
2057                    (setq overlay-arrow-position (make-marker)))                    (setq overlay-arrow-position (make-marker)))
2058                (set-marker overlay-arrow-position (point) buffer)))                (set-marker overlay-arrow-position (point) buffer)))
2059              
2060            ;; If the point is outside the restriction, widen the buffer.            ;; If the point is outside the restriction, widen the buffer.
2061            (if (or (< pos (point-min)) (> pos (point-max)))            (if (or (< pos (point-min)) (> pos (point-max)))
2062                (progn                (progn
# Line 1789  If FRAME is nil then remove overlay." Line 2070  If FRAME is nil then remove overlay."
2070          ;; Make sure pos is really displayed in the window.          ;; Make sure pos is really displayed in the window.
2071          (set-window-point window pos)          (set-window-point window pos)
2072    
2073          ;; If we came from the shell, go back there.  Otherwise select          ;; If we came from the shell, go back there.  Otherwise select
2074          ;; the window where the error is displayed.          ;; the window where the error is displayed.
2075          (if (and (equal (buffer-name) (idlwave-shell-buffer))          (if (and (equal (buffer-name) (idlwave-shell-buffer))
2076                   (not select-shell))                   (not select-shell))
2077              (select-window window))))))              (select-window window))))))
2078    
# Line 1801  If FRAME is nil then remove overlay." Line 2082  If FRAME is nil then remove overlay."
2082    (interactive "p")    (interactive "p")
2083    (or (not arg) (< arg 1)    (or (not arg) (< arg 1)
2084        (setq arg 1))        (setq arg 1))
2085    (idlwave-shell-send-command    (idlwave-shell-send-command
2086     (concat ".s " (if (integerp arg) (int-to-string arg) arg))))     (concat ".s " (if (integerp arg) (int-to-string arg) arg))
2087       nil (idlwave-shell-hide-p 'debug)))
2088    
2089  (defun idlwave-shell-stepover (arg)  (defun idlwave-shell-stepover (arg)
2090    "Stepover one source line.    "Stepover one source line.
2091  If given prefix argument ARG, step ARG source lines.  If given prefix argument ARG, step ARG source lines.
2092  Uses IDL's stepover executive command which does not enter called functions."  Uses IDL's stepover executive command which does not enter called functions."
2093    (interactive "p")    (interactive "p")
2094    (or (not arg) (< arg 1)    (or (not arg) (< arg 1)
2095        (setq arg 1))        (setq arg 1))
2096    (idlwave-shell-send-command    (idlwave-shell-send-command
2097     (concat ".so " (if (integerp arg) (int-to-string arg) arg))))     (concat ".so " (if (integerp arg) (int-to-string arg) arg))
2098       nil (idlwave-shell-hide-p 'debug)))
2099    
2100  (defun idlwave-shell-break-here (&optional count cmd)  (defun idlwave-shell-break-here (&optional count cmd condition)
2101    "Set breakpoint at current line.      "Set breakpoint at current line.
2102    
2103  If Count is nil then an ordinary breakpoint is set.  We treat a count  If Count is nil then an ordinary breakpoint is set.  We treat a count
2104  of 1 as a temporary breakpoint using the ONCE keyword.  Counts greater  of 1 as a temporary breakpoint using the ONCE keyword.  Counts greater
2105  than 1 use the IDL AFTER=count keyword to break only after reaching  than 1 use the IDL AFTER=count keyword to break only after reaching
2106  the statement count times.  the statement count times.
2107    
2108  Optional argument CMD is a list or function to evaluate upon reaching  Optional argument CMD is a list or function to evaluate upon reaching
2109  the breakpoint."  the breakpoint."
2110      
2111    (interactive "P")    (interactive "P")
2112    (if (listp count)    (when (listp count)
2113        (setq count nil))      (if (equal (car count) 4)
2114            (setq condition (read-string "Break Condition: ")))
2115        (setq count nil))
2116    (idlwave-shell-set-bp    (idlwave-shell-set-bp
2117     ;; Create breakpoint     ;; Create breakpoint
2118     (idlwave-shell-bp (idlwave-shell-current-frame)     (idlwave-shell-bp (idlwave-shell-current-frame)
2119                       (list count cmd)                       (list count cmd condition)
2120                       (idlwave-shell-current-module))))                       (idlwave-shell-current-module))))
2121    
2122  (defun idlwave-shell-set-bp-check (bp)  (defun idlwave-shell-set-bp-check (bp)
# Line 1847  the problem with not being able to set t Line 2132  the problem with not being able to set t
2132        (progn        (progn
2133          (if (progn          (if (progn
2134                (beep)                (beep)
2135                (y-or-n-p                (y-or-n-p
2136                 (concat "Okay to recompile file "                 (concat "Okay to recompile file "
2137                         (idlwave-shell-bp-get bp 'file) " ")))                         (idlwave-shell-bp-get bp 'file) " ")))
2138              ;; Recompile              ;; Recompile
# Line 1855  the problem with not being able to set t Line 2140  the problem with not being able to set t
2140                ;; Clean up before retrying                ;; Clean up before retrying
2141                (idlwave-shell-command-failure)                (idlwave-shell-command-failure)
2142                (idlwave-shell-send-command                (idlwave-shell-send-command
2143                 (concat ".run " (idlwave-shell-bp-get bp 'file)) nil nil)                 (concat ".run " (idlwave-shell-bp-get bp 'file)) nil
2144                   (idlwave-shell-hide-p 'run))
2145                ;; Try setting breakpoint again                ;; Try setting breakpoint again
2146                (idlwave-shell-set-bp bp))                (idlwave-shell-set-bp bp))
2147            (beep)            (beep)
# Line 1878  breakpoint can not be set." Line 2164  breakpoint can not be set."
2164  (defun idlwave-shell-cont ()  (defun idlwave-shell-cont ()
2165    "Continue executing."    "Continue executing."
2166    (interactive)    (interactive)
2167    (idlwave-shell-send-command ".c" '(idlwave-shell-redisplay 'hide)))    (idlwave-shell-send-command ".c" '(idlwave-shell-redisplay 'hide)
2168                                  (idlwave-shell-hide-p 'debug)))
2169    
2170  (defun idlwave-shell-go ()  (defun idlwave-shell-go ()
2171    "Run .GO.  This starts the main program of the last compiled file."    "Run .GO.  This starts the main program of the last compiled file."
2172    (interactive)    (interactive)
2173    (idlwave-shell-send-command ".go" '(idlwave-shell-redisplay 'hide)))    (idlwave-shell-send-command ".go" '(idlwave-shell-redisplay 'hide)
2174                                  (idlwave-shell-hide-p 'debug)))
2175    
2176  (defun idlwave-shell-return ()  (defun idlwave-shell-return ()
2177    "Run .RETURN (continue to next return, but stay in subprogram)."    "Run .RETURN (continue to next return, but stay in subprogram)."
2178    (interactive)    (interactive)
2179    (idlwave-shell-send-command ".return" '(idlwave-shell-redisplay 'hide)))    (idlwave-shell-send-command ".return" '(idlwave-shell-redisplay 'hide)
2180                                  (idlwave-shell-hide-p 'debug)))
2181    
2182  (defun idlwave-shell-skip ()  (defun idlwave-shell-skip ()
2183    "Run .SKIP (skip one line, then step)."    "Run .SKIP (skip one line, then step)."
2184    (interactive)    (interactive)
2185    (idlwave-shell-send-command ".skip" '(idlwave-shell-redisplay 'hide)))    (idlwave-shell-send-command ".skip" '(idlwave-shell-redisplay 'hide)
2186                                  (idlwave-shell-hide-p 'debug)))
2187    
2188  (defun idlwave-shell-clear-bp (bp)  (defun idlwave-shell-clear-bp (bp)
2189    "Clear breakpoint BP.    "Clear breakpoint BP.
# Line 1902  Clears in IDL and in `idlwave-shell-bp-a Line 2192  Clears in IDL and in `idlwave-shell-bp-a
2192      (if index      (if index
2193          (progn          (progn
2194            (idlwave-shell-send-command            (idlwave-shell-send-command
2195             (concat "breakpoint,/clear,"             (concat "breakpoint,/clear,"
2196                     (if (integerp index) (int-to-string index) index)))                     (if (integerp index) (int-to-string index) index))
2197               nil (idlwave-shell-hide-p 'breakpoint))
2198            (idlwave-shell-bp-query)))))            (idlwave-shell-bp-query)))))
2199    
2200  (defun idlwave-shell-current-frame ()  (defun idlwave-shell-current-frame ()
# Line 1949  at a breakpoint." Line 2240  at a breakpoint."
2240            (beep)            (beep)
2241            (message "Cannot identify breakpoint for this line"))))))            (message "Cannot identify breakpoint for this line"))))))
2242    
2243    (defun idlwave-shell-disable-all-bp (&optional enable)
2244      "Disable all breakpoints we know about.
2245    If ENABLE is non-nil, enable them instead."
2246      (let  ((bpl idlwave-shell-bp-alist))
2247        (while bpl
2248          (idlwave-shell-send-command
2249           (concat "breakpoint,"
2250                   (if enable "/enable," "/disable," )
2251                   (idlwave-shell-bp-get (car bpl)))
2252           nil (idlwave-shell-hide-p 'breakpoint))
2253          (setq bpl (cdr bpl)))))
2254    
2255  (defun idlwave-shell-to-here ()  (defun idlwave-shell-to-here ()
2256    "Set a breakpoint with count 1 then continue."    "Set a breakpoint with count 1 then continue."
2257    (interactive)    (interactive)
2258      (idlwave-shell-disable-all-bp)
2259    (idlwave-shell-break-here 1)    (idlwave-shell-break-here 1)
2260    (idlwave-shell-cont))    (idlwave-shell-cont)
2261      (idlwave-shell-disable-all-bp 'enable))
2262    
2263  (defun idlwave-shell-break-in (&optional module)  (defun idlwave-shell-break-in (&optional module)
2264    "Look for a module name near point and set a break point for it.    "Look for a module name near point and set a break point for it.
# Line 1977  for the first line of the corresponding Line 2282  for the first line of the corresponding
2282  (defun idlwave-shell-set-bp-in-module (module)  (defun idlwave-shell-set-bp-in-module (module)
2283    "Set breakpoint in module.  Assumes that `idlwave-shell-sources-alist'    "Set breakpoint in module.  Assumes that `idlwave-shell-sources-alist'
2284  contains an entry for that module."  contains an entry for that module."
2285    (let ((source-file (car-safe    (let ((source-file (car-safe
2286                        (cdr-safe                        (cdr-safe
2287                         (assoc (upcase module)                         (assoc (upcase module)
2288                                idlwave-shell-sources-alist))))                                idlwave-shell-sources-alist))))
# Line 1996  contains an entry for that module." Line 2301  contains an entry for that module."
2301          (save-excursion          (save-excursion
2302            (goto-char (point-min))            (goto-char (point-min))
2303            (let ((case-fold-search t))            (let ((case-fold-search t))
2304              (if (re-search-forward              (if (re-search-forward
2305                   (concat "^[ \t]*\\(pro\\|function\\)[ \t]+"                   (concat "^[ \t]*\\(pro\\|function\\)[ \t]+"
2306                           (downcase module)                           (downcase module)
2307                           "[ \t\n,]") nil t)                           "[ \t\n,]") nil t)
# Line 2038  Sets a breakpoint with count 1 at end of Line 2343  Sets a breakpoint with count 1 at end of
2343    "Attempt to run until this procedure exits.    "Attempt to run until this procedure exits.
2344  Runs to the last statement and then steps 1 statement.  Use the .out command."  Runs to the last statement and then steps 1 statement.  Use the .out command."
2345    (interactive)    (interactive)
2346    (idlwave-shell-send-command (concat ".o")))    (idlwave-shell-send-command ".o" nil (idlwave-shell-hide-p 'debug)))
2347    
2348  (defun idlwave-shell-help-expression (arg)  (defun idlwave-shell-help-expression (arg)
2349    "Print help on current expression.  See `idlwave-shell-print'."    "Print help on current expression.  See `idlwave-shell-print'."
2350    (interactive "P")    (interactive "P")
2351    (idlwave-shell-print arg 'help))    (idlwave-shell-print arg 'help))
2352    
2353    (defmacro idlwave-shell-mouse-examine (help &optional ev)
2354      "Create a function for generic examination of expressions."
2355      `(lambda (event)
2356         "Expansion function for expression examination."
2357         (interactive "e")
2358         (let ((transient-mark-mode t)
2359               (zmacs-regions t)
2360               (tracker (if (featurep 'xemacs) 'mouse-track
2361                          'mouse-drag-region)))
2362           (funcall tracker event)
2363           (idlwave-shell-print (if (idlwave-region-active-p) '(16) nil)
2364                                ,help ,ev))))
2365    
2366  (defun idlwave-shell-mouse-print (event)  (defun idlwave-shell-mouse-print (event)
2367    "Call `idlwave-shell-print' at the mouse position."    "Print value of variable at the mouse position, with `help'"
2368    (interactive "e")    (interactive "e")
2369    (mouse-set-point event)    (funcall (idlwave-shell-mouse-examine nil) event))
   (idlwave-shell-print nil nil 'mouse))  
2370    
2371  (defun idlwave-shell-mouse-help (event)  (defun idlwave-shell-mouse-help (event)
2372    "Call `idlwave-shell-print' at the mouse position."    "Print value of variable at the mouse position, with `print'."
2373    (interactive "e")    (interactive "e")
2374    (mouse-set-point event)    (funcall (idlwave-shell-mouse-examine 'help) event))
2375    (idlwave-shell-print nil 'help 'mouse))  
2376    (defun idlwave-shell-examine-select (event)
2377      "Pop-up a list to select from for examining the expression"
2378      (interactive "e")
2379      (funcall (idlwave-shell-mouse-examine nil event) event))
2380    
2381    (defmacro idlwave-shell-examine (help)
2382      "Create a function for key-driven expression examination."
2383      `(lambda ()
2384         (interactive)
2385         (idlwave-shell-print nil ,help)))
2386    
2387    (defun idlwave-shell-define-key-both (key hook)
2388      "Define a key in both the shell and buffer mode maps."
2389      (define-key idlwave-mode-map key hook)
2390      (define-key idlwave-shell-mode-map key hook))
2391    
2392    (defvar idlwave-shell-examine-label nil
2393      "Label to include with examine text if separate.")
2394    
2395    (defun idlwave-shell-print (arg &optional help ev)
2396      "Print current expression.
2397    
2398    With HELP non-nil, show help on expression.  If HELP is a string,
2399    the expression will be put in place of ___, e.g.:
2400    
2401       print,size(___,/DIMENSIONS)
2402    
2403    Otherwise, print is called on the expression.
2404    
 (defun idlwave-shell-print (arg &optional help mouse)  
   "Print current expression.  With HELP, show help on expression.  
2405  An expression is an identifier plus 1 pair of matched parentheses  An expression is an identifier plus 1 pair of matched parentheses
2406  directly following the identifier - an array or function  directly following the identifier - an array or function call.
2407  call.  Alternatively, an expression is the contents of any matched  Alternatively, an expression is the contents of any matched
2408  parentheses when the open parentheses is not directly preceded by an  parentheses when the open parenthesis is not directly preceded by an
2409  identifier. If point is at the beginning or within an expression  identifier. If point is at the beginning or within an expression
2410  return the inner-most containing expression, otherwise, return the  return the inner-most containing expression, otherwise, return the
2411  preceding expression.  preceding expression.
2412    
2413  With prefix arg ARG, or when called from the shell buffer, prompt  With prefix arg ARG prompt for an expression.
2414  for an expression."  
2415    With double prefix arg, use the current region.
2416    
2417    If EV is a valid event passed, pop-up a list from
2418    idlw-shell-examine-alist from which to select the help command text."
2419    (interactive "P")    (interactive "P")
2420    (save-excursion    (save-excursion
2421      (let (expr beg end cmd)      (let* ((process (get-buffer-process (current-buffer)))
2422        (if (and (not mouse)             (process-mark (if process (process-mark process)))
2423                 (or arg (eq major-mode 'idlwave-shell-mode)))             (stack-label
2424            (setq expr (read-string "Expression: "))              (if (and (integerp idlwave-shell-calling-stack-index)
2425          (idlwave-with-special-syntax1                       (> idlwave-shell-calling-stack-index 0))
2426                    (format "  [-%d:%s]"
2427                            idlwave-shell-calling-stack-index
2428                            idlwave-shell-calling-stack-routine)))
2429               expr beg end cmd examine-hook)
2430          (cond
2431           ((and (equal arg '(16))
2432                 (< (- (region-end) (region-beginning)) 2000))
2433            (setq beg (region-beginning)
2434                  end (region-end)))
2435           (arg
2436            (setq expr (read-string "Expression: ")))
2437           (t
2438            (idlwave-with-special-syntax
2439           ;; Move to beginning of current or previous expression           ;; Move to beginning of current or previous expression
2440           (if (looking-at "\\<\\|(")           (if (looking-at "\\<\\|(")
2441               ;; At beginning of expression, don't move backwards unless               ;; At beginning of expression, don't move backwards unless
# Line 2093  for an expression." Line 2453  for an expression."
2453           (while (looking-at "\\>[[(]\\|\\.")           (while (looking-at "\\>[[(]\\|\\.")
2454             ;; an array             ;; an array
2455             (forward-sexp))             (forward-sexp))
2456           (setq end (point))           (setq end (point)))))
2457           (setq expr (buffer-substring beg end))))  
2458          ;; Get expression, but first move the begin mark if a
2459          ;; process-mark is inside the region, to keep the overlay from
2460          ;; wandering in the Shell.
2461          (when (and beg end)
2462            (if (and process-mark (> process-mark beg) (< process-mark end))
2463                (setq beg (marker-position process-mark)))
2464            (setq expr (buffer-substring beg end)))
2465    
2466          ;; Show the overlay(s) and attach any necessary hooks and filters
2467        (when (and beg end idlwave-shell-expression-overlay)        (when (and beg end idlwave-shell-expression-overlay)
2468          (move-overlay idlwave-shell-expression-overlay beg end          (move-overlay idlwave-shell-expression-overlay beg end
2469                        (current-buffer))                        (current-buffer))
2470          (add-hook 'pre-command-hook 'idlwave-shell-delete-expression-overlay))          (add-hook 'pre-command-hook
2471        (if (and (integerp idlwave-shell-calling-stack-index)                    'idlwave-shell-delete-expression-overlay))
2472                 (> idlwave-shell-calling-stack-index 0))        (setq examine-hook
2473                (if idlwave-shell-separate-examine-output
2474                    'idlwave-shell-examine-display
2475                  'idlwave-shell-examine-highlight))
2476          (add-hook 'pre-command-hook
2477                    'idlwave-shell-delete-output-overlay)
2478    
2479          ;; Remove empty or comment-only lines
2480          (while (string-match "\n[ \t]*\\(;.*\\)?\r*\n" expr)
2481            (setq expr (replace-match "\n" t t expr)))
2482          ;; Concatenate continuation lines
2483          (while (string-match "[ \t]*\\$.*\\(;.*\\)?\\(\n[ \t]*\\|$\\)" expr)
2484            (setq expr (replace-match "" t t expr)))
2485          ;; Remove final newline
2486          (if (string-match "\n[ \t\r]*\\'" expr)
2487              (setq expr (replace-match "" t t expr)))
2488          ;; Pop-up the examine selection list, if appropriate
2489          (if (and ev idlwave-shell-examine-alist)
2490              (let* ((help-cons
2491                      (assoc
2492                       (idlwave-popup-select
2493                        ev (mapcar 'car idlwave-shell-examine-alist)
2494                        "Examine with")
2495                       idlwave-shell-examine-alist)))
2496                (setq help (cdr help-cons))
2497                (if idlwave-shell-separate-examine-output
2498                    (setq idlwave-shell-examine-label
2499                          (concat
2500                           (format "==>%s<==\n%s:" expr (car help-cons))
2501                           stack-label "\n"))))
2502            (setq idlwave-shell-examine-label
2503                  (concat
2504                   (format "==>%s<==\n%s:" expr
2505                           (cond ((null help) "print")
2506                                 ((stringp help) help)
2507                                 (t (symbol-name help))))
2508                   stack-label "\n")))
2509    
2510          ;; Send the command
2511          (if stack-label
2512            (setq cmd (idlwave-retrieve-expression-from-level            (setq cmd (idlwave-retrieve-expression-from-level
2513                       expr                       expr
2514                       idlwave-shell-calling-stack-index                       idlwave-shell-calling-stack-index
2515                       idlwave-shell-calling-stack-routine                       idlwave-shell-calling-stack-routine
2516                       help))                       help))
2517          (setq cmd (concat (if help "help," "print,") expr)))          (setq cmd (idlwave-shell-help-statement help expr)))
2518        (if idlwave-shell-print-expression-function        ;(idlwave-shell-recenter-shell-window)
2519            (idlwave-shell-send-command        (idlwave-shell-send-command
2520             cmd         cmd
2521             (list idlwave-shell-print-expression-function expr)         examine-hook
2522             'hide)         (if idlwave-shell-separate-examine-output 'hide)))))
2523          (idlwave-shell-recenter-shell-window)  
2524          (idlwave-shell-send-command cmd)))))  (defvar idlwave-shell-examine-window-alist nil
2525      "Variable to hold the win/height pairs for all *Examine* windows.")
2526    
2527    (defun idlwave-shell-examine-display ()
2528      "View the examine command output in a separate buffer."
2529      (let (win cur-beg cur-end)
2530        (save-excursion
2531          (set-buffer (get-buffer-create "*Examine*"))
2532          (use-local-map idlwave-shell-examine-map)
2533          (setq buffer-read-only nil)
2534          (goto-char (point-max))
2535          (save-restriction
2536            (narrow-to-region (point) (point))
2537            (if (string-match "^% Syntax error." idlwave-shell-command-output)
2538                (insert "% Syntax error.\n")
2539              (insert idlwave-shell-command-output)
2540              ;; Just take the last bit between the prompts (if more than one).
2541              (let* ((end (or
2542                           (re-search-backward idlwave-shell-prompt-pattern nil t)
2543                           (point-max)))
2544                     (beg (progn
2545                            (goto-char
2546                             (or (progn (if (re-search-backward
2547                                             idlwave-shell-prompt-pattern nil t)
2548                                            (match-end 0)))
2549                                 (point-min)))
2550                            (re-search-forward "\n")))
2551                     (str (buffer-substring beg end)))
2552                (delete-region (point-min) (point-max))
2553                (insert str)
2554                (if idlwave-shell-examine-label
2555                    (progn (goto-char (point-min))
2556                           (insert idlwave-shell-examine-label)
2557                           (setq idlwave-shell-examine-label nil)))))
2558            (setq cur-beg (point-min)
2559                  cur-end (point-max))
2560            (setq buffer-read-only t)
2561            (move-overlay idlwave-shell-output-overlay cur-beg cur-end
2562                          (current-buffer))
2563    
2564            ;; Look for the examine buffer in all windows.  If one is
2565            ;; found in a frame all by itself, use that, otherwise, switch
2566            ;; to or create an examine window in this frame, and resize if
2567            ;; it's a newly created window
2568            (let* ((winlist (get-buffer-window-list "*Examine*" nil 'visible)))
2569              (setq win (idlwave-display-buffer
2570                         "*Examine*"
2571                         nil
2572                         (let ((list winlist) thiswin)
2573                           (catch 'exit
2574                             (save-selected-window
2575                               (while (setq thiswin (pop list))
2576                                 (select-window thiswin)
2577                                 (if (one-window-p)
2578                                     (throw 'exit (window-frame thiswin)))))))))
2579              (set-window-start win (point-min)) ; Ensure the point is visible.
2580              (save-selected-window
2581                (select-window win)
2582                (let ((elt (assoc win idlwave-shell-examine-window-alist)))
2583                  (when (and (not (one-window-p))
2584                             (or (not (memq win winlist)) ;a newly created window
2585                                 (eq (window-height) (cdr elt))))
2586                    ;; Autosize it.
2587                    (enlarge-window (- (/ (frame-height) 2)
2588                                       (window-height)))
2589                    (shrink-window-if-larger-than-buffer)
2590                    ;; Clean the window list of dead windows
2591                    (setq idlwave-shell-examine-window-alist
2592                          (delq nil
2593                                (mapcar (lambda (x) (if (window-live-p (car x)) x))
2594                                        idlwave-shell-examine-window-alist)))
2595                    ;; And add the new value.
2596                    (if (setq elt (assoc win idlwave-shell-examine-window-alist))
2597                        (setcdr elt (window-height))
2598                      (add-to-list 'idlwave-shell-examine-window-alist
2599                                   (cons win (window-height)))))))))
2600          ;; Recenter for maximum output, after widened
2601          (save-selected-window
2602            (select-window win)
2603            (goto-char (point-max))
2604            (skip-chars-backward "\n")
2605            (recenter -1)))))
2606    
2607    (defvar idlwave-shell-examine-map (make-sparse-keymap))
2608    (define-key idlwave-shell-examine-map "q" 'idlwave-shell-examine-display-quit)
2609    (define-key idlwave-shell-examine-map "c" 'idlwave-shell-examine-display-clear)
2610    
2611    (defun idlwave-shell-examine-display-quit ()
2612      (interactive)
2613      (let ((win (selected-window)))
2614        (if (one-window-p)
2615            (delete-frame (window-frame win))
2616          (delete-window win))))
2617    
2618    (defun idlwave-shell-examine-display-clear ()
2619      (interactive)
2620      (save-excursion
2621        (let ((buf (get-buffer "*Examine*")))
2622          (when (bufferp buf)
2623            (set-buffer buf)
2624            (setq buffer-read-only nil)
2625            (erase-buffer)
2626            (setq buffer-read-only t)))))
2627    
2628  (defun idlwave-retrieve-expression-from-level (expr level routine help)  (defun idlwave-retrieve-expression-from-level (expr level routine help)
2629    "Return IDL command to print the expression EXPR from stack level LEVEL.    "Return IDL command to print the expression EXPR from stack level LEVEL.
# Line 2126  calling stack.  The copies are given som Line 2636  calling stack.  The copies are given som
2636  level.  level.
2637    
2638  Since this function depends upon the undocumented IDL routine routine_names,  Since this function depends upon the undocumented IDL routine routine_names,
2639  there is no guarantie that this will work with future versions of IDL."  there is no guarantee that this will work with future versions of IDL."
2640    (let ((prefix "___")         ;; No real variables should starts with this.    (let ((prefix "___")         ;; No real variables should starts with this.
2641          (fetch (- 0 level))          (fetch (- 0 level))
2642          (start 0)          (start 0)
2643          var tvar fetch-vars pre post)          var tvar fetch-vars pre post)
2644    
2645       ;; FIXME: In the following we try to find the variables in expression       ;; FIXME: In the following we try to find the variables in expression
2646       ;; This is quite empirical - I don't know in what situations this will      ;; This is quite empirical - I don't know in what situations this will
2647       ;; break.  We will look for identifiers and exclude cases where we      ;; break.  We will look for identifiers and exclude cases where we
2648       ;; know it is not a variable.  To distinguish array references from      ;; know it is not a variable.  To distinguish array references from
2649       ;; function calls, we require that arrays use [] instead of ()      ;; function calls, we require that arrays use [] instead of ()
2650    
2651       (while (string-match      (while (string-match
2652      "\\(\\`\\|[^a-zA-Z0-9$_]\\)\\([a-zA-Z][a-zA-Z0-9$_]*\\)\\([^a-zA-Z0-9$_]\\|\\'\\)" expr start)              "\\(\\`\\|[^a-zA-Z0-9$_]\\)\\([a-zA-Z][a-zA-Z0-9$_]*\\)\\([^a-zA-Z0-9$_]\\|\\'\\)" expr start)
2653         (setq var (match-string 2 expr)        (setq var (match-string 2 expr)
2654               tvar (concat prefix var)              tvar (concat prefix var)
2655               start (match-beginning 2)              start (match-beginning 2)
2656               pre (substring expr 0 (match-beginning 2))              pre (substring expr 0 (match-beginning 2))
2657               post (substring expr (match-end 2)))              post (substring expr (match-end 2)))
2658         (cond        (cond
2659          ;; Exclude identifiers which are not variables         ;; Exclude identifiers which are not variables
2660          ((string-match ",[ \t]*/\\'" pre))        ;; a `/' KEYWORD         ((string-match ",[ \t]*/\\'" pre))        ;; a `/' KEYWORD
2661          ((and (string-match "[,(][ \t]*\\'" pre)         ((and (string-match "[,(][ \t]*\\'" pre)
2662                (string-match "\\`[ \t]*=" post)))  ;; a `=' KEYWORD               (string-match "\\`[ \t]*=" post)))  ;; a `=' KEYWORD
2663          ((string-match "\\`(" post))              ;; a function         ((string-match "\\`(" post))              ;; a function
2664          ((string-match "->[ \t]*\\'" pre))        ;; a method         ((string-match "->[ \t]*\\'" pre))        ;; a method
2665          ((string-match "\\.\\'" pre))             ;; structure member         ((string-match "\\.\\'" pre))             ;; structure member
2666          (t ;; seems to be a variable - arrange to get it and replace         (t ;; seems to be a variable - arrange to get it and replace
2667             ;; its name in the expression with the temproary name.          ;; its name in the expression with the temproary name.
2668           (push (cons var tvar) fetch-vars)          (push (cons var tvar) fetch-vars)
2669           (setq expr (concat pre tvar post)))))          (setq expr (concat pre tvar post))))
2670          (if (= start 0) (setq start 1)))
2671      ;; Make a command line that first copies the relevant variables      ;; Make a command line that first copies the relevant variables
2672      ;; and then prints the expression.      ;; and then prints the expression.
2673      (concat      (concat
# Line 2165  there is no guarantie that this will wor Line 2676  there is no guarantie that this will wor
2676          (format "%s = routine_names('%s',fetch=%d)" (cdr x) (car x) fetch))          (format "%s = routine_names('%s',fetch=%d)" (cdr x) (car x) fetch))
2677        (nreverse fetch-vars)        (nreverse fetch-vars)
2678        " & ")        " & ")
2679       (if idlwave-shell-print-expression-function " & " "\n")       "\n"
2680       (if help "help, " "print, ")       (idlwave-shell-help-statement help expr)
      expr  
2681       (format " ; [-%d:%s]" level routine))))       (format " ; [-%d:%s]" level routine))))
2682    
2683    (defun idlwave-shell-help-statement (help expr)
2684      "Construct a help statement for printing expression EXPR.
2685    
2686    HELP can be non-nil for `help,', nil for 'print,' or any string into which
2687    to insert expression in place of the marker ___, e.g.: print,
2688    size(___,/DIMENSIONS)"
2689      (cond
2690       ((null help) (concat "print, " expr))
2691       ((stringp help)
2692        (if (string-match "\\(^\\|[^_]\\)\\(___\\)\\([^_]\\|$\\)" help)
2693            (concat (substring help 0 (match-beginning 2))
2694                    expr
2695                    (substring help (match-end 2)))))
2696       (t (concat "help, " expr))))
2697    
2698    
2699    (defun idlwave-shell-examine-highlight ()
2700      "Highlight the most recent IDL output."
2701      (let* ((buffer (get-buffer (idlwave-shell-buffer)))
2702             (process (get-buffer-process buffer))
2703             (process-mark (if process (process-mark process)))
2704             output-begin output-end)
2705        (save-excursion
2706          (set-buffer buffer)
2707          (goto-char process-mark)
2708          (beginning-of-line)
2709          (setq output-end (point))
2710          (re-search-backward idlwave-shell-prompt-pattern nil t)
2711          (beginning-of-line 2)
2712          (setq output-begin (point)))
2713    
2714        ;; First make sure the shell window is visible
2715        (idlwave-display-buffer (idlwave-shell-buffer)
2716                                nil (idlwave-shell-shell-frame))
2717        (if (and idlwave-shell-output-overlay process-mark)
2718            (move-overlay idlwave-shell-output-overlay
2719                          output-begin output-end buffer))))
2720    
2721    (defun idlwave-shell-delete-output-overlay ()
2722      (if (eq this-command 'idlwave-shell-mouse-nop)
2723          nil
2724        (condition-case nil
2725            (if idlwave-shell-output-overlay
2726                (delete-overlay idlwave-shell-output-overlay))
2727          (error nil))
2728        (remove-hook 'pre-command-hook 'idlwave-shell-delete-output-overlay)))
2729    
2730  (defun idlwave-shell-delete-expression-overlay ()  (defun idlwave-shell-delete-expression-overlay ()
2731    (condition-case nil    (if (eq this-command 'idlwave-shell-mouse-nop)
2732        (if idlwave-shell-expression-overlay        nil
2733            (delete-overlay idlwave-shell-expression-overlay))      (condition-case nil
2734      (error nil))          (if idlwave-shell-expression-overlay
2735    (remove-hook 'pre-command-hook 'idlwave-shell-delete-expression-overlay))              (delete-overlay idlwave-shell-expression-overlay))
2736          (error nil))
2737        (remove-hook 'pre-command-hook 'idlwave-shell-delete-expression-overlay)))
2738    
2739  (defvar idlwave-shell-bp-alist nil  (defvar idlwave-shell-bp-alist nil
2740    "Alist of breakpoints.    "Alist of breakpoints.
# Line 2195  contains two items: Line 2754  contains two items:
2754    
2755  count - number of times to execute breakpoint. When count reaches 0  count - number of times to execute breakpoint. When count reaches 0
2756  the breakpoint is cleared and removed from the alist.  the breakpoint is cleared and removed from the alist.
2757  command - command to execute when breakpoint is reached, either a  command - command to execute when breakpoint is reached, either a
2758  lisp function to be called with `funcall' with no arguments or a  lisp function to be called with `funcall' with no arguments or a
2759  list to be evaluated with `eval'.")  list to be evaluated with `eval'.")
2760    
# Line 2213  If there is a prefix argument, display I Line 2772  If there is a prefix argument, display I
2772    (let ((oldbuf (current-buffer)))    (let ((oldbuf (current-buffer)))
2773      (save-excursion      (save-excursion
2774        (set-buffer (idlwave-find-file-noselect        (set-buffer (idlwave-find-file-noselect
2775                     idlwave-shell-temp-pro-file 'tmp))                     (idlwave-shell-temp-file 'pro) 'tmp))
2776          (set (make-local-variable 'comment-start-skip) ";+[ \t]*")
2777          (set (make-local-variable 'comment-start) ";")
2778        (erase-buffer)        (erase-buffer)
2779        (insert-buffer-substring oldbuf beg end)        (insert-buffer-substring oldbuf beg end)
2780        (if (not (save-excursion        (if (not (save-excursion
# Line 2221  If there is a prefix argument, display I Line 2782  If there is a prefix argument, display I
2782                   (idlwave-look-at "\\<end\\>")))                   (idlwave-look-at "\\<end\\>")))
2783            (insert "\nend\n"))            (insert "\nend\n"))
2784        (save-buffer 0)))        (save-buffer 0)))
2785    (idlwave-shell-send-command (concat ".run " idlwave-shell-temp-pro-file))    (idlwave-shell-send-command (concat ".run " idlwave-shell-temp-pro-file)
2786                                  nil (idlwave-shell-hide-p 'run))
2787    (if n    (if n
2788        (idlwave-display-buffer (idlwave-shell-buffer)        (idlwave-display-buffer (idlwave-shell-buffer)
2789                                nil (idlwave-shell-shell-frame))))                                nil (idlwave-shell-shell-frame))))
2790    
2791  (defun idlwave-shell-evaluate-region (beg end &optional n)  (defun idlwave-shell-evaluate-region (beg end &optional n)
# Line 2234  Does not work for a region with multilin Line 2796  Does not work for a region with multilin
2796    (interactive "r\nP")    (interactive "r\nP")
2797    (idlwave-shell-send-command (buffer-substring beg end))    (idlwave-shell-send-command (buffer-substring beg end))
2798    (if n    (if n
2799        (idlwave-display-buffer (idlwave-shell-buffer)        (idlwave-display-buffer (idlwave-shell-buffer)
2800                                nil (idlwave-shell-shell-frame))))                                nil (idlwave-shell-shell-frame))))
2801    
2802  (defun idlwave-shell-delete-temp-files ()  (defun idlwave-shell-delete-temp-files ()
# Line 2253  Does not work for a region with multilin Line 2815  Does not work for a region with multilin
2815          (error nil))))          (error nil))))
2816    
2817  (defun idlwave-display-buffer (buf not-this-window-p &optional frame)  (defun idlwave-display-buffer (buf not-this-window-p &optional frame)
2818    (if (or (< emacs-major-version 20)    (if (featurep 'xemacs)
2819            (and (= emacs-major-version 20)        ;; The XEmacs version enforces the frame
2820                 (< emacs-minor-version 3)))        (display-buffer buf not-this-window-p frame)
2821        ;; Only two args.      ;; For Emacs, we need to force the frame ourselves.
2822        (display-buffer buf not-this-window-p)      (let ((this-frame (selected-frame)))
2823      ;; Three ares possible.        (if (frame-live-p frame)
2824      (display-buffer buf not-this-window-p frame)))            (select-frame frame))
2825          (if (eq this-frame (selected-frame))
2826              ;; same frame:  use display buffer, to make sure the current
2827              ;; window stays.
2828              (display-buffer buf)
2829            ;; different frame
2830            (if (one-window-p)
2831                ;; only window:  switch
2832                (progn
2833                  (switch-to-buffer buf)
2834                  (selected-window))   ; must return the window.
2835              ;; several windows - use display-buffer
2836              (display-buffer buf not-this-window-p))))))
2837    ;  (if (not (frame-live-p frame)) (setq frame nil))
2838    ;  (display-buffer buf not-this-window-p frame))
2839    
2840  (defvar idlwave-shell-bp-buffer " *idlwave-shell-bp*"  (defvar idlwave-shell-bp-buffer " *idlwave-shell-bp*"
2841    "Scratch buffer for parsing IDL breakpoint lists and other stuff.")    "Scratch buffer for parsing IDL breakpoint lists and other stuff.")
# Line 2287  Defaults to 'index." Line 2863  Defaults to 'index."
2863     ((eq item 'data) (cdr (cdr bp)))     ((eq item 'data) (cdr (cdr bp)))
2864     ((eq item 'count) (nth 0 (cdr (cdr bp))))     ((eq item 'count) (nth 0 (cdr (cdr bp))))
2865     ((eq item 'cmd) (nth 1 (cdr (cdr bp))))     ((eq item 'cmd) (nth 1 (cdr (cdr bp))))
2866       ((eq item 'condition) (nth 2 (cdr (cdr bp))))
2867     ;; IDL breakpoint info     ;; IDL breakpoint info
2868     ((eq item 'module) (nth 1 (car (cdr bp))))     ((eq item 'module) (nth 1 (car (cdr bp))))
2869     ;;    index - default     ;;    index - default
# Line 2302  from previous breakpoint list." Line 2879  from previous breakpoint list."
2879      (insert idlwave-shell-command-output)      (insert idlwave-shell-command-output)
2880      (goto-char (point-min))      (goto-char (point-min))
2881      (let ((old-bp-alist idlwave-shell-bp-alist)      (let ((old-bp-alist idlwave-shell-bp-alist)
2882            file line index module)            ;; Searching the breakpoints
2883              ;; In IDL 5.5, the breakpoint reporting format changed.
2884              (bp-re54 "^[ \t]*\\([0-9]+\\)[ \t]+\\(\\S-+\\)?[ \t]+\\([0-9]+\\)[ \t]+\\(\\S-+\\)")
2885              (bp-re55 "^\\s-*\\([0-9]+\\)\\s-+\\([0-9]+\\)\\s-+\\(Uncompiled\\|Func=\\|Pro=\\)\\([a-zA-Z][a-zA-Z0-9$_:]*\\)\\(,[^\n]*\n\\)?\\s-+\\(\\S-+\\)")
2886              file line index module
2887              bp-re indmap)
2888        (setq idlwave-shell-bp-alist (list nil))        (setq idlwave-shell-bp-alist (list nil))
2889        (when (re-search-forward "^\\s-*Index.*\n\\s-*-" nil t)        ;; Search for either header type, and set the correct regexp
2890          (when (or
2891                 (if (re-search-forward "^\\s-*Index.*\n\\s-*-" nil t)
2892                     (setq bp-re bp-re54    ; versions <= 5.4
2893                           indmap '(1 2 3 4)))
2894                 (if (re-search-forward
2895                      "^\\s-*Index\\s-*Line\\s-*Attributes\\s-*File" nil t)
2896                     (setq bp-re bp-re55    ; versions >= 5.5
2897                           indmap '(1 4 2 6))))
2898          ;; There seems to be a breakpoint listing here.          ;; There seems to be a breakpoint listing here.
2899          ;; Parse breakpoint lines.          ;; Parse breakpoint lines.
2900          ;; Breakpoints have the form:          ;; Breakpoints have the form
2901            ;;    for IDL<=v5.4:
2902          ;;  Index Module Line File          ;;  Index Module Line File
2903          ;;  All seperated by whitespace.          ;;  All separated by whitespace.
2904          ;;  Module may be missing if the file is not compiled.          ;;  Module may be missing if the file is not compiled.
2905          ;;          ;;    for IDL>=v5.5:
2906          (while (re-search-forward          ;;  Index Line Attributes File
2907                  "^[ \t]*\\([0-9]+\\)[ \t]+\\(\\S-+\\)?[ \t]+\\([0-9]+\\)[ \t]+\\(\\S-+\\)" nil t)          ;;    (attributes replaces module, "Uncompiled" included)
2908            (setq index (match-string 1)          (while (re-search-forward bp-re nil t)
2909                  module (match-string 2)            (setq index (match-string (nth 0 indmap))
2910                  line (string-to-int (match-string 3))                  module (match-string (nth 1 indmap))
2911                  file (idlwave-shell-file-name (match-string 4)))                  line (string-to-int (match-string (nth 2 indmap)))
2912                    file (idlwave-shell-file-name (match-string (nth 3 indmap))))
2913            ;; Add the breakpoint info to the list            ;; Add the breakpoint info to the list
2914            (nconc idlwave-shell-bp-alist            (nconc idlwave-shell-bp-alist
2915                   (list (cons (list file line)                   (list (cons (list file line)
# Line 2373  The breakpoint will be placed at the beg Line 2965  The breakpoint will be placed at the beg
2965  line specified by BP or at the next IDL statement if that line is not  line specified by BP or at the next IDL statement if that line is not
2966  a statement.  a statement.
2967  Determines IDL's internal representation for the breakpoint which may  Determines IDL's internal representation for the breakpoint which may
2968  have occured at a different line then used with the breakpoint  have occurred at a different line then used with the breakpoint
2969  command."  command."
2970      
2971    ;; Get and save the old breakpoints    ;; Get and save the old breakpoints
2972    (idlwave-shell-send-command    (idlwave-shell-send-command
2973     idlwave-shell-bp-query     idlwave-shell-bp-query
2974     '(progn     '(progn
2975       (idlwave-shell-filter-bp)        (idlwave-shell-filter-bp)
2976       (setq idlwave-shell-old-bp idlwave-shell-bp-alist))        (setq idlwave-shell-old-bp idlwave-shell-bp-alist))
2977     'hide)     'hide)
2978    ;; Get sources for IDL compiled procedures followed by setting    ;; Get sources for IDL compiled procedures followed by setting
2979    ;; breakpoint.    ;; breakpoint.
2980    (idlwave-shell-send-command    (idlwave-shell-send-command
2981     idlwave-shell-sources-query     idlwave-shell-sources-query
2982     `(progn     `(progn
2983       (idlwave-shell-sources-filter)        (idlwave-shell-sources-filter)
2984       (idlwave-shell-set-bp2 (quote ,bp)))        (idlwave-shell-set-bp2 (quote ,bp)))
2985     'hide))     'hide))
2986    
2987  (defun idlwave-shell-set-bp2 (bp)  (defun idlwave-shell-set-bp2 (bp)
2988    "Use results of breakpoint and sources query to set bp.    "Use results of breakpoint and sources query to set bp.
2989  Use the count argument with IDLs breakpoint command.  Use the count argument with IDLs breakpoint command.
2990  We treat a count of 1 as a temporary breakpoint.  We treat a count of 1 as a temporary breakpoint.
2991  Counts greater than 1 use the IDL AFTER=count keyword to break  Counts greater than 1 use the IDL AFTER=count keyword to break
2992  only after reaching the statement count times."  only after reaching the statement count times."
2993    (let*    (let*
# Line 2406  only after reaching the statement count Line 2998  only after reaching the statement count
2998                 ",/once")                 ",/once")
2999                ((> arg 1)                ((> arg 1)
3000                 (format ",after=%d" arg))))                 (format ",after=%d" arg))))
3001           (condition (idlwave-shell-bp-get bp 'condition))
3002           (key (concat key
3003                        (if condition (concat ",CONDITION=\"" condition "\""))))
3004         (line (idlwave-shell-bp-get bp 'line)))         (line (idlwave-shell-bp-get bp 'line)))
3005      (idlwave-shell-send-command      (idlwave-shell-send-command
3006       (concat "breakpoint,'"       (concat "breakpoint,'"
3007               (idlwave-shell-sources-bp bp) "',"               (idlwave-shell-sources-bp bp) "',"
3008               (if (integerp line) (setq line (int-to-string line)))               (if (integerp line) (setq line (int-to-string line)))
3009               key)               key)
# Line 2416  only after reaching the statement count Line 3011  only after reaching the statement count
3011       `(progn       `(progn
3012         (if (idlwave-shell-set-bp-check (quote ,bp))         (if (idlwave-shell-set-bp-check (quote ,bp))
3013             (idlwave-shell-set-bp3 (quote ,bp))))             (idlwave-shell-set-bp3 (quote ,bp))))
3014       ;; do not hide output       ;; hide output?
3015       nil       (idlwave-shell-hide-p 'breakpoint)
3016       'preempt)))       'preempt)))
3017    
3018  (defun idlwave-shell-set-bp3 (bp)  (defun idlwave-shell-set-bp3 (bp)
# Line 2493  This stuff is stringly dependant upon th Line 3088  This stuff is stringly dependant upon th
3088      (if (featurep 'xemacs)      (if (featurep 'xemacs)
3089          ;; This is XEmacs          ;; This is XEmacs
3090          (progn          (progn
3091            (cond            (cond
3092             ((eq (console-type) 'tty)             ((eq (console-type) 'tty)
3093              ;; tty's cannot display glyphs              ;; tty's cannot display glyphs
3094              (set-extent-property ov 'face idlwave-shell-breakpoint-face))              (set-extent-property ov 'face idlwave-shell-breakpoint-face))
# Line 2504  This stuff is stringly dependant upon th Line 3099  This stuff is stringly dependant upon th
3099             (idlwave-shell-mark-breakpoints             (idlwave-shell-mark-breakpoints
3100              ;; use the face              ;; use the face
3101              (set-extent-property ov 'face idlwave-shell-breakpoint-face))              (set-extent-property ov 'face idlwave-shell-breakpoint-face))
3102             (t             (t
3103              ;; no marking              ;; no marking
3104              nil))              nil))
3105            (set-extent-priority ov -1))  ; make stop line face prevail            (set-extent-priority ov -1))  ; make stop line face prevail
# Line 2523  This stuff is stringly dependant upon th Line 3118  This stuff is stringly dependant upon th
3118         (idlwave-shell-mark-breakpoints         (idlwave-shell-mark-breakpoints
3119          ;; use a face          ;; use a face
3120          (overlay-put ov 'face idlwave-shell-breakpoint-face))          (overlay-put ov 'face idlwave-shell-breakpoint-face))
3121         (t         (t
3122          ;; No marking          ;; No marking
3123          nil)))          nil)))
3124      ov))      ov))
# Line 2541  Also with prefix arg, ask for the comman Line 3136  Also with prefix arg, ask for the comman
3136    (interactive "P")    (interactive "P")
3137    (if (or (not idlwave-shell-command-line-to-execute)    (if (or (not idlwave-shell-command-line-to-execute)
3138            arg)            arg)
3139        (setq idlwave-shell-command-line-to-execute        (setq idlwave-shell-command-line-to-execute
3140              (read-string "IDL> " idlwave-shell-command-line-to-execute)))              (read-string "IDL> " idlwave-shell-command-line-to-execute)))
3141    (idlwave-shell-reset 'hidden)    (idlwave-shell-reset 'hidden)
3142    (idlwave-shell-send-command idlwave-shell-command-line-to-execute    (idlwave-shell-send-command idlwave-shell-command-line-to-execute
# Line 2551  Also with prefix arg, ask for the comman Line 3146  Also with prefix arg, ask for the comman
3146    "Save file and run it in IDL.    "Save file and run it in IDL.
3147  Runs `save-buffer' and sends a '.RUN' command for the associated file to IDL.  Runs `save-buffer' and sends a '.RUN' command for the associated file to IDL.
3148  When called from the shell buffer, re-run the file which was last handled by  When called from the shell buffer, re-run the file which was last handled by
3149  one of the save-and-.. commands."    one of the save-and-.. commands."
3150    (interactive)    (interactive)
3151    (idlwave-shell-save-and-action 'run))    (idlwave-shell-save-and-action 'run))
3152    
# Line 2567  one of the save-and-.. commands." Line 3162  one of the save-and-.. commands."
3162    "Save file and batch it in IDL.    "Save file and batch it in IDL.
3163  Runs `save-buffer' and sends a '@file' command for the associated file to IDL.  Runs `save-buffer' and sends a '@file' command for the associated file to IDL.
3164  When called from the shell buffer, re-batch the file which was last handled by  When called from the shell buffer, re-batch the file which was last handled by
3165  one of the save-and-.. commands."    one of the save-and-.. commands."
3166    (interactive)    (interactive)
3167    (idlwave-shell-save-and-action 'batch))    (idlwave-shell-save-and-action 'batch))
3168    
# Line 2603  handled by this command." Line 3198  handled by this command."
3198                         (t (error "Unknown action %s" action)))                         (t (error "Unknown action %s" action)))
3199                   idlwave-shell-last-save-and-action-file)                   idlwave-shell-last-save-and-action-file)
3200           'idlwave-shell-maybe-update-routine-info           'idlwave-shell-maybe-update-routine-info
3201           nil)           (idlwave-shell-hide-p 'run))
3202          (idlwave-shell-bp-query))          (idlwave-shell-bp-query))
3203      (let ((msg (format "No such file %s"      (let ((msg (format "No such file %s"
3204                         idlwave-shell-last-save-and-action-file)))                         idlwave-shell-last-save-and-action-file)))
3205        (setq idlwave-shell-last-save-and-action-file nil)        (setq idlwave-shell-last-save-and-action-file nil)
3206        (error msg))))        (error msg))))
3207    
3208  (defun idlwave-shell-maybe-update-routine-info ()  (defun idlwave-shell-maybe-update-routine-info (&optional wait)
3209    "Update the routine info if the shell is not stopped at an error."    "Update the routine info if the shell is not stopped at an error."
3210    (if (and (not idlwave-shell-is-stopped)    (if (and (not idlwave-shell-is-stopped)
3211             (or (eq t idlwave-auto-routine-info-updates)             (or (eq t idlwave-auto-routine-info-updates)
3212                 (memq 'compile-buffer idlwave-auto-routine-info-updates))                 (memq 'compile-buffer idlwave-auto-routine-info-updates))
3213             idlwave-query-shell-for-routine-info             idlwave-query-shell-for-routine-info
3214             idlwave-routines)             idlwave-routines)
3215      (idlwave-shell-update-routine-info t)))        (idlwave-shell-update-routine-info t nil 'wait)))
3216    
3217  (defvar idlwave-shell-sources-query "help,/source"  (defvar idlwave-shell-sources-query "help,/source,/full"
3218    "IDL command to obtain source files for compiled procedures.")    "IDL command to obtain source files for compiled procedures.")
3219    
3220  (defvar idlwave-shell-sources-alist nil  (defvar idlwave-shell-sources-alist nil
# Line 2638  Queries IDL using the string in `idlwave Line 3233  Queries IDL using the string in `idlwave
3233    
3234  (defun idlwave-shell-sources-filter ()  (defun idlwave-shell-sources-filter ()
3235    "Get source files from `idlwave-shell-sources-query' output.    "Get source files from `idlwave-shell-sources-query' output.
3236  Create `idlwave-shell-sources-alist' consisting of  Create `idlwave-shell-sources-alist' consisting of
3237  list elements of the form:  list elements of the form:
3238   (module name . (source-file-truename idlwave-internal-filename))."   (module name . (source-file-truename idlwave-internal-filename))."
3239    (save-excursion    (save-excursion
# Line 2689  list elements of the form: Line 3284  list elements of the form:
3284                   ))))                   ))))
3285        (cdr al))))        (cdr al))))
3286    
   
3287  (defun idlwave-shell-clear-all-bp ()  (defun idlwave-shell-clear-all-bp ()
3288    "Remove all breakpoints in IDL."    "Remove all breakpoints in IDL."
3289    (interactive)    (interactive)
# Line 2746  Otherwise, just expand the file name." Line 3340  Otherwise, just expand the file name."
3340    (let ((def-dir (if (eq major-mode 'idlwave-shell-mode)    (let ((def-dir (if (eq major-mode 'idlwave-shell-mode)
3341                       default-directory                       default-directory
3342                     idlwave-shell-default-directory)))                     idlwave-shell-default-directory)))
3343      (if idlwave-shell-use-truename      (if idlwave-shell-use-truename
3344          (file-truename name def-dir)          (file-truename name def-dir)
3345        (expand-file-name name def-dir))))        (expand-file-name name def-dir))))
3346    
   
3347  ;; Keybindings --------------------------------------------------------------  ;; Keybindings --------------------------------------------------------------
3348    
3349  (defvar idlwave-shell-mode-map (copy-keymap comint-mode-map)  (defvar idlwave-shell-mode-map (copy-keymap comint-mode-map)
# Line 2764  Otherwise, just expand the file name." Line 3357  Otherwise, just expand the file name."
3357  (define-key idlwave-shell-mode-map "\M-\t"    'idlwave-shell-complete)  (define-key idlwave-shell-mode-map "\M-\t"    'idlwave-shell-complete)
3358  (define-key idlwave-shell-mode-map "\C-c\C-s" 'idlwave-shell)  (define-key idlwave-shell-mode-map "\C-c\C-s" 'idlwave-shell)
3359  (define-key idlwave-shell-mode-map "\C-c?"    'idlwave-routine-info)  (define-key idlwave-shell-mode-map "\C-c?"    'idlwave-routine-info)
3360    (define-key idlwave-shell-mode-map "\C-g"     'idlwave-keyboard-quit)
3361  (define-key idlwave-shell-mode-map "\M-?"     'idlwave-context-help)  (define-key idlwave-shell-mode-map "\M-?"     'idlwave-context-help)
3362    (define-key idlwave-shell-mode-map [(control meta ?\?)] 'idlwave-online-help)
3363  (define-key idlwave-shell-mode-map "\C-c\C-i" 'idlwave-update-routine-info)  (define-key idlwave-shell-mode-map "\C-c\C-i" 'idlwave-update-routine-info)
3364  (define-key idlwave-shell-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)  (define-key idlwave-shell-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
3365  (define-key idlwave-shell-mode-map "\C-c\C-x" 'idlwave-shell-send-char)  (define-key idlwave-shell-mode-map "\C-c\C-x" 'idlwave-shell-send-char)
# Line 2777  Otherwise, just expand the file name." Line 3372  Otherwise, just expand the file name."
3372  (define-key idlwave-shell-mode-map [(down)] 'idlwave-shell-down-or-history)  (define-key idlwave-shell-mode-map [(down)] 'idlwave-shell-down-or-history)
3373  (define-key idlwave-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)  (define-key idlwave-mode-map "\C-c\C-y" 'idlwave-shell-char-mode-loop)
3374  (define-key idlwave-mode-map "\C-c\C-x" 'idlwave-shell-send-char)  (define-key idlwave-mode-map "\C-c\C-x" 'idlwave-shell-send-char)
3375  (define-key idlwave-mode-map  
3376    (if (featurep 'xemacs) [(shift button2)] [(shift mouse-2)])  ;; The mouse bindings for PRINT and HELP
3377    'idlwave-shell-mouse-print)  (idlwave-shell-define-key-both
3378  (define-key idlwave-mode-map   (if (featurep 'xemacs)
3379    (if (featurep 'xemacs) [(shift control button2)] [(shift control mouse-2)])       [(shift button2)]
3380    'idlwave-shell-mouse-help)     [(shift down-mouse-2)])
3381  (define-key idlwave-shell-mode-map   'idlwave-shell-mouse-print)
3382    (if (featurep 'xemacs) [(shift button2)] [(shift mouse-2)])  (idlwave-shell-define-key-both
3383    'idlwave-shell-mouse-print)   (if (featurep 'xemacs)
3384  (define-key idlwave-shell-mode-map       [(control meta button2)]
3385    (if (featurep 'xemacs) [(shift control button2)] [(shift control mouse-2)])     [(control meta down-mouse-2)])
3386    'idlwave-shell-mouse-help)    'idlwave-shell-mouse-help)
3387  (define-key idlwave-shell-mode-map  (idlwave-shell-define-key-both
3388    (if (featurep 'xemacs) [(shift button3)] [(shift mouse-3)])   (if (featurep 'xemacs)
3389         [(control shift button2)]
3390       [(control shift down-mouse-2)])
3391     'idlwave-shell-examine-select)
3392    ;; Add this one from the idlwave-mode-map
3393    (define-key idlwave-shell-mode-map
3394      (if (featurep 'xemacs)
3395          [(shift button3)]
3396        [(shift mouse-3)])
3397    'idlwave-mouse-context-help)    'idlwave-mouse-context-help)
3398    
3399    ;; For Emacs, we need to turn off the button release events.
3400    (defun idlwave-shell-mouse-nop (event)
3401      (interactive "e"))
3402    (unless (featurep 'xemacs)
3403      (idlwave-shell-define-key-both
3404       [(shift mouse-2)] 'idlwave-shell-mouse-nop)
3405      (idlwave-shell-define-key-both
3406       [(shift control mouse-2)] 'idlwave-shell-mouse-nop)
3407      (idlwave-shell-define-key-both
3408       [(control meta mouse-2)] 'idlwave-shell-mouse-nop))
3409    
3410    
3411  ;; The following set of bindings is used to bind the debugging keys.  ;; The following set of bindings is used to bind the debugging keys.
3412  ;; If `idlwave-shell-activate-prefix-keybindings' is non-nil, the first key  ;; If `idlwave-shell-activate-prefix-keybindings' is non-nil, the first key
3413  ;; in the list gets bound the C-c C-d prefix map.  ;; in the list gets bound the C-c C-d prefix map.
3414  ;; If `idlwave-shell-debug-modifiers' is non-nil, the second key  ;; If `idlwave-shell-debug-modifiers' is non-nil, the second key
3415  ;; in the list gets bound with the specified modifiers in both  ;; in the list gets bound with the specified modifiers in both
3416  ;; `idlwave-mode-map' and `idlwave-shell-mode-map'.  ;; `idlwave-mode-map' and `idlwave-shell-mode-map'.
3417    
3418  ;; Used keys:   abcdef hi klmnopqrs u wxyz  ;; Used keys:   abcdef hi klmnopqrs u wxyz
3419  ;; Unused keys:       g  j         t v    ;; Unused keys:       g  j         t v
3420  (let* ((specs  (let* ((specs
3421          '(([(control ?b)]   ?b   idlwave-shell-break-here)          '(([(control ?b)]   ?b   idlwave-shell-break-here)
3422            ([(control ?i)]   ?i   idlwave-shell-break-in)            ([(control ?i)]   ?i   idlwave-shell-break-in)
# Line 2896  Otherwise, just expand the file name." Line 3510  Otherwise, just expand the file name."
3510      "--"      "--"
3511      ["Print expression" idlwave-shell-print t]      ["Print expression" idlwave-shell-print t]
3512      ["Help on expression" idlwave-shell-help-expression t]      ["Help on expression" idlwave-shell-help-expression t]
3513      ["Evaluate Region" idlwave-shell-evaluate-region      ["Evaluate Region" idlwave-shell-evaluate-region
3514       (eq major-mode 'idlwave-mode)]       (eq major-mode 'idlwave-mode)]
3515      ["Run Region" idlwave-shell-run-region (eq major-mode 'idlwave-mode)]      ["Run Region" idlwave-shell-run-region (eq major-mode 'idlwave-mode)]
3516      "--"      "--"
# Line 2948  Otherwise, just expand the file name." Line 3562  Otherwise, just expand the file name."
3562      ("Print Expression"      ("Print Expression"
3563       ["Print expression" idlwave-shell-print t]       ["Print expression" idlwave-shell-print t]
3564       ["Help on expression" idlwave-shell-help-expression t]       ["Help on expression" idlwave-shell-help-expression t]
3565       ["Evaluate Region" idlwave-shell-evaluate-region       ["Evaluate Region" idlwave-shell-evaluate-region
3566        (eq major-mode 'idlwave-mode)]        (eq major-mode 'idlwave-mode)]
3567       "--"       "--"
3568       ["Redisplay" idlwave-shell-redisplay t]       ["Redisplay" idlwave-shell-redisplay t]
# Line 2974  Otherwise, just expand the file name." Line 3588  Otherwise, just expand the file name."
3588        (easy-menu-define        (easy-menu-define
3589         idlwave-shell-mode-menu idlwave-shell-mode-map "IDL shell menus"         idlwave-shell-mode-menu idlwave-shell-mode-map "IDL shell menus"
3590         idlwave-shell-menu-def)         idlwave-shell-menu-def)
3591        (easy-menu-define        (easy-menu-define
3592         idlwave-mode-debug-menu idlwave-mode-map "IDL debugging menus"         idlwave-mode-debug-menu idlwave-mode-map "IDL debugging menus"
3593         idlwave-shell-menu-def)         idlwave-shell-menu-def)
3594        (save-excursion        (save-excursion
# Line 2994  Otherwise, just expand the file name." Line 3608  Otherwise, just expand the file name."
3608  (let ((image-string "/* XPM */  (let ((image-string "/* XPM */
3609  static char * file[] = {  static char * file[] = {
3610  \"14 12 3 1\",  \"14 12 3 1\",
3611  \"      c #FFFFFFFFFFFF s backgroundColor\",  \"      c None s backgroundColor\",
3612  \".     c #4B4B4B4B4B4B\",  \".     c #4B4B4B4B4B4B\",
3613  \"R     c #FFFF00000000\",  \"R     c #FFFF00000000\",
3614  \"              \",  \"              \",
# Line 3009  static char * file[] = { Line 3623  static char * file[] = {
3623  \"    RRRR      \",  \"    RRRR      \",
3624  \"              \",  \"              \",
3625  \"              \"};"))  \"              \"};"))
3626          
3627    (setq idlwave-shell-bp-glyph    (setq idlwave-shell-bp-glyph
3628          (cond ((and (featurep 'xemacs)          (cond ((and (featurep 'xemacs)
3629                      (featurep 'xpm))                      (featurep 'xpm))
# Line 3017  static char * file[] = { Line 3631  static char * file[] = {
3631                ((and (not (featurep 'xemacs))                ((and (not (featurep 'xemacs))
3632                      (fboundp 'image-type-available-p)                      (fboundp 'image-type-available-p)
3633                      (image-type-available-p 'xpm))                      (image-type-available-p 'xpm))
3634                 (list 'image :type 'xpm :data image-string))                 (list 'image :type 'xpm :data image-string :ascent 'center))
3635                (t nil))))                (t nil))))
3636    
3637  (provide 'idlw-shell)  (provide 'idlw-shell)
# Line 3025  static char * file[] = { Line 3639  static char * file[] = {
3639    
3640  ;;; Load the toolbar when wanted by the user.  ;;; Load the toolbar when wanted by the user.
3641    
3642  (autoload 'idlwave-toolbar-toggle "idlw-toolbar"  (autoload 'idlwave-toolbar-toggle "idlw-toolbar"
3643    "Toggle the IDLWAVE toolbar")    "Toggle the IDLWAVE toolbar")
3644  (autoload 'idlwave-toolbar-add-everywhere "idlw-toolbar"  (autoload 'idlwave-toolbar-add-everywhere "idlw-toolbar"
3645    "Add IDLWAVE toolbar")    "Add IDLWAVE toolbar")
# Line 3036  static char * file[] = { Line 3650  static char * file[] = {
3650    
3651  (if idlwave-shell-use-toolbar  (if idlwave-shell-use-toolbar
3652      (add-hook 'idlwave-shell-mode-hook 'idlwave-toolbar-add-everywhere))      (add-hook 'idlwave-shell-mode-hook 'idlwave-toolbar-add-everywhere))
   
3653  ;;; idlw-shell.el ends here  ;;; idlw-shell.el ends here

Legend:
Removed from v.3.15  
changed lines
  Added in v.3.15.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26