]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/octave-inf.el
Merge from emacs--rel--22
[gnu-emacs] / lisp / progmodes / octave-inf.el
index 6f235c0f02ffc10a88440984d1870361e393c223..b46510b5ac9d1186fa59f2700e53863d948209ba 100644 (file)
@@ -1,10 +1,11 @@
 ;;; octave-inf.el --- running Octave as an inferior Emacs process
 
 ;;; octave-inf.el --- running Octave as an inferior Emacs process
 
-;; Copyright (C) 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;; Free Software Foundation, Inc.
 
 
-;; Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
+;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
 ;; Author: John Eaton <jwe@bevo.che.wisc.edu>
 ;; Author: John Eaton <jwe@bevo.che.wisc.edu>
-;; Maintainer: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
+;; Maintainer: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
 ;; Keywords: languages
 
 ;; This file is part of GNU Emacs.
 ;; Keywords: languages
 
 ;; This file is part of GNU Emacs.
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
 
 ;;; Code:
 
 
 ;;; Code:
 
   :group 'octave)
 
 (defcustom inferior-octave-program "octave"
   :group 'octave)
 
 (defcustom inferior-octave-program "octave"
-  "*Program invoked by `inferior-octave'."
+  "Program invoked by `inferior-octave'."
   :type 'string
   :group 'octave-inferior)
 
 (defcustom inferior-octave-prompt
   :type 'string
   :group 'octave-inferior)
 
 (defcustom inferior-octave-prompt
-  "\\(^octave\\(\\|.bin\\)\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ "
-  "*Regexp to match prompts for the inferior Octave process."
+  "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ "
+  "Regexp to match prompts for the inferior Octave process."
   :type 'regexp
   :group 'octave-inferior)
 
 (defcustom inferior-octave-startup-file nil
   :type 'regexp
   :group 'octave-inferior)
 
 (defcustom inferior-octave-startup-file nil
-  "*Name of the inferior Octave startup file.
+  "Name of the inferior Octave startup file.
 The contents of this file are sent to the inferior Octave process on
 startup."
   :type '(choice (const :tag "None" nil)
                 file)
   :group 'octave-inferior)
 
 The contents of this file are sent to the inferior Octave process on
 startup."
   :type '(choice (const :tag "None" nil)
                 file)
   :group 'octave-inferior)
 
-(defcustom inferior-octave-startup-args '("-i" "--no-line-editing")
-  "*List of command line arguments for the inferior Octave process.
+(defcustom inferior-octave-startup-args nil
+  "List of command line arguments for the inferior Octave process.
 For example, for suppressing the startup message and using `traditional'
 mode, set this to (\"-q\" \"--traditional\")."
   :type '(repeat string)
   :group 'octave-inferior)
 
 For example, for suppressing the startup message and using `traditional'
 mode, set this to (\"-q\" \"--traditional\")."
   :type '(repeat string)
   :group 'octave-inferior)
 
-(defvar inferior-octave-mode-map nil
-  "Keymap used in Inferior Octave mode.")
-(if inferior-octave-mode-map
-    ()
-  (let ((map (copy-keymap comint-mode-map)))
+(defvar inferior-octave-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map comint-mode-map)
     (define-key map "\t" 'comint-dynamic-complete)
     (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
     (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring)
     (define-key map [menu-bar inout list-history]
       '("List Input History" . inferior-octave-dynamic-list-input-ring))
     (define-key map "\C-c\C-h" 'octave-help)
     (define-key map "\t" 'comint-dynamic-complete)
     (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
     (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring)
     (define-key map [menu-bar inout list-history]
       '("List Input History" . inferior-octave-dynamic-list-input-ring))
     (define-key map "\C-c\C-h" 'octave-help)
-    (setq inferior-octave-mode-map map)))
+    map)
+  "Keymap used in Inferior Octave mode.")
 
 
-(defvar inferior-octave-mode-syntax-table nil
-  "Syntax table in use in inferior-octave-mode buffers.")
-(if inferior-octave-mode-syntax-table
-    ()
+(defvar inferior-octave-mode-syntax-table
   (let ((table (make-syntax-table)))
     (modify-syntax-entry ?\` "w" table)
     (modify-syntax-entry ?\# "<" table)
     (modify-syntax-entry ?\n ">" table)
   (let ((table (make-syntax-table)))
     (modify-syntax-entry ?\` "w" table)
     (modify-syntax-entry ?\# "<" table)
     (modify-syntax-entry ?\n ">" table)
-    (setq inferior-octave-mode-syntax-table table)))
+    table)
+  "Syntax table in use in inferior-octave-mode buffers.")
 
 (defcustom inferior-octave-mode-hook nil
   "*Hook to be run when Inferior Octave mode is started."
 
 (defcustom inferior-octave-mode-hook nil
   "*Hook to be run when Inferior Octave mode is started."
@@ -93,6 +93,17 @@ mode, set this to (\"-q\" \"--traditional\")."
   ;; Could certainly do more font locking in inferior Octave ...
   "Additional expressions to highlight in Inferior Octave mode.")
 
   ;; Could certainly do more font locking in inferior Octave ...
   "Additional expressions to highlight in Inferior Octave mode.")
 
+
+;;; Compatibility functions
+(if (not (fboundp 'comint-line-beginning-position))
+    ;; comint-line-beginning-position is defined in Emacs 21
+    (defun comint-line-beginning-position ()
+      "Returns the buffer position of the beginning of the line, after any prompt.
+The prompt is assumed to be any text at the beginning of the line matching
+the regular expression `comint-prompt-regexp', a buffer local variable."
+      (save-excursion (comint-bol nil) (point))))
+
+
 (defvar inferior-octave-output-list nil)
 (defvar inferior-octave-output-string nil)
 (defvar inferior-octave-receive-in-progress nil)
 (defvar inferior-octave-output-list nil)
 (defvar inferior-octave-output-string nil)
 (defvar inferior-octave-receive-in-progress nil)
@@ -102,8 +113,11 @@ mode, set this to (\"-q\" \"--traditional\")."
 (defvar inferior-octave-complete-impossible nil
   "Non-nil means that `inferior-octave-complete' is impossible.")
 
 (defvar inferior-octave-complete-impossible nil
   "Non-nil means that `inferior-octave-complete' is impossible.")
 
+(defvar inferior-octave-has-built-in-variables nil
+  "Non-nil means that Octave has built-in variables.")
+
 (defvar inferior-octave-dynamic-complete-functions
 (defvar inferior-octave-dynamic-complete-functions
-  '(inferior-octave-complete comint-dynamic-complete-filename)  
+  '(inferior-octave-complete comint-dynamic-complete-filename)
   "List of functions called to perform completion for inferior Octave.
 This variable is used to initialize `comint-dynamic-complete-functions'
 in the Inferior Octave buffer.")
   "List of functions called to perform completion for inferior Octave.
 This variable is used to initialize `comint-dynamic-complete-functions'
 in the Inferior Octave buffer.")
@@ -116,7 +130,7 @@ buffer.
 Entry to this mode successively runs the hooks `comint-mode-hook' and
 `inferior-octave-mode-hook'."
   (interactive)
 Entry to this mode successively runs the hooks `comint-mode-hook' and
 `inferior-octave-mode-hook'."
   (interactive)
-  (comint-mode)
+  (delay-mode-hooks (comint-mode))
   (setq comint-prompt-regexp inferior-octave-prompt
        major-mode 'inferior-octave-mode
        mode-name "Inferior Octave"
   (setq comint-prompt-regexp inferior-octave-prompt
        major-mode 'inferior-octave-mode
        mode-name "Inferior Octave"
@@ -125,12 +139,12 @@ Entry to this mode successively runs the hooks `comint-mode-hook' and
   (use-local-map inferior-octave-mode-map)
   (set-syntax-table inferior-octave-mode-syntax-table)
 
   (use-local-map inferior-octave-mode-map)
   (set-syntax-table inferior-octave-mode-syntax-table)
 
-  (make-local-variable 'comment-start)  
+  (make-local-variable 'comment-start)
   (setq comment-start octave-comment-start)
   (make-local-variable 'comment-end)
   (setq comment-end "")
   (make-local-variable 'comment-column)
   (setq comment-start octave-comment-start)
   (make-local-variable 'comment-end)
   (setq comment-end "")
   (make-local-variable 'comment-column)
-  (setq comment-column 32)    
+  (setq comment-column 32)
   (make-local-variable 'comment-start-skip)
   (setq comment-start-skip octave-comment-start-skip)
 
   (make-local-variable 'comment-start-skip)
   (setq comment-start-skip octave-comment-start-skip)
 
@@ -140,12 +154,12 @@ Entry to this mode successively runs the hooks `comint-mode-hook' and
   (setq comint-input-ring-file-name
        (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
        comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)
   (setq comint-input-ring-file-name
        (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
        comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)
-       comint-input-filter-functions '(inferior-octave-directory-tracker)
-       comint-dynamic-complete-functions
-       inferior-octave-dynamic-complete-functions)
+       comint-input-filter-functions '(inferior-octave-directory-tracker))
+  (set (make-local-variable 'comint-dynamic-complete-functions)
+       inferior-octave-dynamic-complete-functions)
   (comint-read-input-ring t)
 
   (comint-read-input-ring t)
 
-  (run-hooks 'inferior-octave-mode-hook))
+  (run-mode-hooks 'inferior-octave-mode-hook))
 
 ;;;###autoload
 (defun inferior-octave (&optional arg)
 
 ;;;###autoload
 (defun inferior-octave (&optional arg)
@@ -182,7 +196,8 @@ startup file, `~/.emacs-octave'."
               (substring inferior-octave-buffer 1 -1)
               inferior-octave-buffer
               inferior-octave-program
               (substring inferior-octave-buffer 1 -1)
               inferior-octave-buffer
               inferior-octave-program
-              inferior-octave-startup-args)))
+              (append (list "-i" "--no-line-editing")
+                      inferior-octave-startup-args))))
     (set-process-filter proc 'inferior-octave-output-digest)
     (setq comint-ptyp process-connection-type
          inferior-octave-process proc
     (set-process-filter proc 'inferior-octave-output-digest)
     (setq comint-ptyp process-connection-type
          inferior-octave-process proc
@@ -205,16 +220,34 @@ startup file, `~/.emacs-octave'."
          (concat (mapconcat
                   'identity inferior-octave-output-list "\n")
                  "\n"))))
          (concat (mapconcat
                   'identity inferior-octave-output-list "\n")
                  "\n"))))
+
+     ;; Find out whether Octave has built-in variables.
+     (inferior-octave-send-list-and-digest
+      (list "exist \"LOADPATH\"\n"))
+     (setq inferior-octave-has-built-in-variables
+         (string-match "101$" (car inferior-octave-output-list)))
+
+    ;; An empty secondary prompt, as e.g. obtained by '--braindead',
+    ;; means trouble.
+    (inferior-octave-send-list-and-digest (list "PS2\n"))
+    (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list))
+       (inferior-octave-send-list-and-digest
+        (list (if inferior-octave-has-built-in-variables
+                  "PS2 = \"> \"\n"
+                "PS2 (\"> \");\n"))))
+
     ;; O.k., now we are ready for the Inferior Octave startup commands.
     (let* (commands
           (program (file-name-nondirectory inferior-octave-program))
           (file (or inferior-octave-startup-file
                          (concat "~/.emacs-" program))))
       (setq commands
     ;; O.k., now we are ready for the Inferior Octave startup commands.
     (let* (commands
           (program (file-name-nondirectory inferior-octave-program))
           (file (or inferior-octave-startup-file
                          (concat "~/.emacs-" program))))
       (setq commands
-           (list "page_screen_output = 0;\n"
+           (list "more off;\n"
                  (if (not (string-equal
                  (if (not (string-equal
-                           inferior-octave-output-string ">> ")) 
-                     "PS1=\"\\\\s> \";\n")
+                           inferior-octave-output-string ">> "))
+                     (if inferior-octave-has-built-in-variables
+                         "PS1=\"\\\\s> \";\n"
+                       "PS1 (\"\\\\s> \");\n"))
                  (if (file-exists-p file)
                      (format "source (\"%s\");\n" file))))
       (inferior-octave-send-list-and-digest commands))
                  (if (file-exists-p file)
                      (format "source (\"%s\");\n" file))))
       (inferior-octave-send-list-and-digest commands))
@@ -233,7 +266,11 @@ startup file, `~/.emacs-octave'."
 
     ;; And finally, everything is back to normal.
     (set-process-filter proc 'inferior-octave-output-filter)
 
     ;; And finally, everything is back to normal.
     (set-process-filter proc 'inferior-octave-output-filter)
-    (run-hooks 'inferior-octave-startup-hook)))
+    (run-hooks 'inferior-octave-startup-hook)
+    (run-hooks 'inferior-octave-startup-hook)
+    ;; Just in case, to be sure a cd in the startup file
+    ;; won't have detrimental effects.
+    (inferior-octave-resync-dirs)))
 
 \f
 (defun inferior-octave-complete ()
 
 \f
 (defun inferior-octave-complete ()
@@ -242,13 +279,11 @@ This is implemented using the Octave command `completion_matches' which
 is NOT available with versions of Octave prior to 2.0."
   (interactive)
   (let* ((end (point))
 is NOT available with versions of Octave prior to 2.0."
   (interactive)
   (let* ((end (point))
-        (command (save-excursion
-                   (skip-syntax-backward "w_")
-                   (and (looking-at comint-prompt-regexp)
-                        (goto-char (match-end 0)))
-                   (buffer-substring-no-properties (point) end)))
-        (proc (get-buffer-process inferior-octave-buffer))
-        (filter (process-filter proc)))
+        (command
+         (save-excursion
+           (skip-syntax-backward "w_" (comint-line-beginning-position))
+           (buffer-substring-no-properties (point) end)))
+        (proc (get-buffer-process inferior-octave-buffer)))
     (cond (inferior-octave-complete-impossible
           (error (concat
                   "Your Octave does not have `completion_matches'.  "
     (cond (inferior-octave-complete-impossible
           (error (concat
                   "Your Octave does not have `completion_matches'.  "
@@ -274,7 +309,7 @@ is NOT available with versions of Octave prior to 2.0."
            command inferior-octave-output-list)))))
 
 (defun inferior-octave-dynamic-list-input-ring ()
            command inferior-octave-output-list)))))
 
 (defun inferior-octave-dynamic-list-input-ring ()
-  "List the buffer's input history in a help buffer"
+  "List the buffer's input history in a help buffer."
   ;; We cannot use `comint-dynamic-list-input-ring', because it replaces
   ;; "completion" by "history reference" ...
   (interactive)
   ;; We cannot use `comint-dynamic-list-input-ring', because it replaces
   ;; "completion" by "history reference" ...
   (interactive)
@@ -362,11 +397,12 @@ Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused."
 This command queries the inferior Octave process about its current
 directory and makes this the current buffer's default directory."
   (interactive)
 This command queries the inferior Octave process about its current
 directory and makes this the current buffer's default directory."
   (interactive)
-  (inferior-octave-send-list-and-digest '("pwd\n"))
+  (inferior-octave-send-list-and-digest '("disp (pwd ())\n"))
   (cd (car inferior-octave-output-list)))
 
 ;;; provide ourself
 
 (provide 'octave-inf)
 
   (cd (car inferior-octave-output-list)))
 
 ;;; provide ourself
 
 (provide 'octave-inf)
 
+;; arch-tag: bdce0395-24d1-4bb4-bfba-6fb1eeb1a660
 ;;; octave-inf.el ends here
 ;;; octave-inf.el ends here