aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1997-01-21 00:35:48 +0000
committerRichard M. Stallman1997-01-21 00:35:48 +0000
commit081bf30e0fc58decefa726ac0f5cff6c65063826 (patch)
treea197a4dbb5a2aa0d50b0bf91d5be2e65cc80d5fb
parent777874d02955447940543551a89b7c5430fe2623 (diff)
downloademacs-081bf30e0fc58decefa726ac0f5cff6c65063826.tar.gz
emacs-081bf30e0fc58decefa726ac0f5cff6c65063826.zip
Initial revision
-rw-r--r--lisp/progmodes/octave-hlp.el133
-rw-r--r--lisp/progmodes/octave-inf.el352
2 files changed, 485 insertions, 0 deletions
diff --git a/lisp/progmodes/octave-hlp.el b/lisp/progmodes/octave-hlp.el
new file mode 100644
index 00000000000..2295cb5fa05
--- /dev/null
+++ b/lisp/progmodes/octave-hlp.el
@@ -0,0 +1,133 @@
1;; octave-hlp.el --- getting help on Octave symbols using info
2
3;;; Copyright (C) 1997 Free Software Foundation, Inc.
4
5;; Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
6;; Author: John Eaton <jwe@bevo.che.wisc.edu>
7;; Maintainer: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
8;; Keywords: languages
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation; either version 2, or (at your option)
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
26
27;;; Commentary:
28
29;; Provides the command `octave-help' which allows index lookup of a
30;; symbol in the Octave-related info files, as specified by the list
31;; `octave-help-files'.
32
33;; Other features may be added in future versions.
34
35;;; Code:
36
37(require 'octave)
38(require 'info)
39
40(defvar octave-help-files '("octave")
41 "List of info files with documentation for Octave.
42Default is (\"octave\").")
43
44(defvar octave-help-lookup-alist nil
45 "Alist of Octave index entries for lookup.")
46
47(defvar octave-help-completion-alist nil
48 "Alist of Octave index entries for completion.
49The entries are of the form (VAR . VAR), where VAR runs through all
50different keys in `octave-help-lookup-alist'.")
51
52;;;###autoload
53(defun octave-help (key)
54 "Get help on Octave symbols from the Octave info files.
55Look up KEY in the function, operator and variable indices of the files
56specified by `octave-help-files'.
57If KEY is not a string, prompt for it with completion."
58 (interactive
59 (list
60 (completing-read (format "Describe Octave symbol: ")
61 (octave-help-get-completion-alist)
62 nil t)))
63 (if (get-buffer "*info*")
64 (set-buffer "*info*"))
65 (if (zerop (length key))
66 (Info-find-node (car octave-help-files) "Top")
67 (let ((alist (copy-alist (octave-help-get-lookup-alist)))
68 entry matches)
69 (while (setq entry (car alist))
70 (if (string-match key (car entry))
71 (add-to-list 'matches entry))
72 (setq alist (cdr alist)))
73 (if matches
74 (progn
75 (setq Info-index-alternatives matches)
76 (Info-index-next 0))))))
77
78(defun octave-help-get-lookup-alist ()
79 "Build the index lookup alist from all Octave info files.
80The files specified by `octave-help-files' are searched."
81 (if octave-help-lookup-alist
82 ()
83 (message "Building help lookup alist...")
84 (let ((files octave-help-files) file key node)
85 (save-window-excursion
86 (while files
87 (setq file (car files))
88 (Info-goto-node (concat "(" file ")"))
89 (condition-case nil
90 (progn
91 (Info-index "")
92 (while
93 (progn
94 (while (re-search-forward
95 "^\\* \\([^(:]+\\)[^:]*: *\\(.+\\)\\.$"
96 nil t)
97 (setq key (match-string 1)
98 node (concat "(" file ")" (match-string 2)))
99 (and (string-match "\\(.*\\>\\) *$" key)
100 (setq key (replace-match "\\1" t nil key)))
101 (add-to-list 'octave-help-lookup-alist
102 (list key
103 node
104 (concat (concat "(" file ")")
105 Info-current-node)
106 0)))
107 (and (setq node (Info-extract-pointer "next" t))
108 (string-match
109 (concat "\\(Function\\|Operator\\|Variable\\) "
110 "\\<Index\\>")
111 node)))
112 (Info-goto-node node)))
113 (error nil))
114 (setq files (cdr files)))))
115 (message "Building help lookup alist...done"))
116 octave-help-lookup-alist)
117
118(defun octave-help-get-completion-alist ()
119 "Build the index completion alist from all Octave info files.
120The files specified by `octave-help-files' are searched."
121 (if octave-help-completion-alist
122 ()
123 (message "Building help completion alist...")
124 (let ((alist (octave-help-get-lookup-alist)) entry)
125 (while alist
126 (setq entry (car alist))
127 (add-to-list 'octave-help-completion-alist
128 (cons (car entry) (car entry)))
129 (setq alist (cdr alist))))
130 (message "Building help completion alist...done"))
131 octave-help-completion-alist)
132
133;;; octave-hlp.el ends here \ No newline at end of file
diff --git a/lisp/progmodes/octave-inf.el b/lisp/progmodes/octave-inf.el
new file mode 100644
index 00000000000..acf0df30633
--- /dev/null
+++ b/lisp/progmodes/octave-inf.el
@@ -0,0 +1,352 @@
1;; octave-inf.el --- running Octave as an inferior Emacs process
2
3;;; Copyright (C) 1997 Free Software Foundation, Inc.
4
5;; Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
6;; Author: John Eaton <jwe@bevo.che.wisc.edu>
7;; Maintainer: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
8;; Keywords: languages
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation; either version 2, or (at your option)
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
26
27;;; Commentary:
28
29;;; Code:
30
31(require 'octave)
32(require 'comint)
33
34(defvar inferior-octave-program "octave"
35 "*Program invoked by `inferior-octave'.")
36
37(defvar inferior-octave-prompt "\\(^octave\\(:[0-9]+\\)?\\|^\\)>+ "
38 "*Regexp to match prompts for the inferior Octave process.")
39
40(defvar inferior-octave-startup-file nil
41 "*Name of the inferior Octave startup file.
42The contents of this file are sent to the inferior Octave process on
43startup.")
44
45(defvar inferior-octave-startup-args nil
46 "*List of command line arguments for the inferior Octave process.
47For example, for suppressing the startup message and using `traditional'
48mode, set this to (\"-q\" \"--traditional\").")
49
50(defvar inferior-octave-mode-map nil
51 "Keymap used in Inferior Octave mode.")
52(if inferior-octave-mode-map
53 ()
54 (let ((map (copy-keymap comint-mode-map)))
55 (define-key map "\t" 'comint-dynamic-complete)
56 (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
57 (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring)
58 (define-key map [menu-bar inout list-history]
59 '("List Input History" . inferior-octave-dynamic-list-input-ring))
60 (define-key map "\C-c\C-h" 'octave-help)
61 (setq inferior-octave-mode-map map)))
62
63(defvar inferior-octave-mode-syntax-table nil
64 "Syntax table in use in inferior-octave-mode buffers.")
65(if inferior-octave-mode-syntax-table
66 ()
67 (let ((table (make-syntax-table)))
68 (modify-syntax-entry ?\` "w" table)
69 (modify-syntax-entry ?\# "<" table)
70 (modify-syntax-entry ?\n ">" table)
71 (setq inferior-octave-mode-syntax-table table)))
72
73(defvar inferior-octave-mode-hook nil
74 "*Hook to be run when Inferior Octave mode is started.")
75
76(defvar inferior-octave-font-lock-keywords
77 (list
78 (cons inferior-octave-prompt 'font-lock-type-face))
79 ;; Could certainly do more font locking in inferior Octave ...
80 "Additional expressions to highlight in Inferior Octave mode.")
81
82(defvar inferior-octave-output-list nil)
83(defvar inferior-octave-output-string nil)
84(defvar inferior-octave-receive-in-progress nil)
85
86(defvar inferior-octave-startup-hook nil)
87
88(defvar inferior-octave-complete-impossible nil
89 "Non-nil means that `inferior-octave-complete' is impossible.")
90
91(defvar inferior-octave-dynamic-complete-functions
92 '(inferior-octave-complete comint-dynamic-complete-filename)
93 "List of functions called to perform completion for inferior Octave.
94This variable is used to initialize `comint-dynamic-complete-functions'
95in the Inferior Octave buffer.")
96
97(defun inferior-octave-mode ()
98 "Major mode for interacting with an inferior Octave process.
99Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs
100buffer.
101
102Entry to this mode successively runs the hooks `comint-mode-hook' and
103`inferior-octave-mode-hook'."
104 (interactive)
105 (comint-mode)
106 (setq comint-prompt-regexp inferior-octave-prompt
107 major-mode 'inferior-octave-mode
108 mode-name "Inferior Octave"
109 mode-line-process '(":%s")
110 local-abbrev-table octave-abbrev-table)
111 (use-local-map inferior-octave-mode-map)
112 (set-syntax-table inferior-octave-mode-syntax-table)
113
114 (make-local-variable 'comment-start)
115 (setq comment-start octave-comment-start)
116 (make-local-variable 'comment-end)
117 (setq comment-end "")
118 (make-local-variable 'comment-column)
119 (setq comment-column 32)
120 (make-local-variable 'comment-start-skip)
121 (setq comment-start-skip octave-comment-start-skip)
122
123 (make-local-variable 'font-lock-defaults)
124 (setq font-lock-defaults '(inferior-octave-font-lock-keywords nil nil))
125
126 (setq comint-input-ring-file-name
127 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
128 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)
129 comint-input-filter-functions '(inferior-octave-directory-tracker)
130 comint-dynamic-complete-functions
131 inferior-octave-dynamic-complete-functions)
132 (comint-read-input-ring t)
133
134 (run-hooks 'inferior-octave-mode-hook))
135
136;;;###autoload
137(defun inferior-octave (&optional arg)
138 "Run an inferior Octave process, I/O via `inferior-octave-buffer'.
139This buffer is put in Inferior Octave mode. See `inferior-octave-mode'.
140
141Unless ARG is non-nil, switches to this buffer.
142
143The elements of the list `inferior-octave-startup-args' are sent as
144command line arguments to the inferior Octave process on startup.
145
146Additional commands to be executed on startup can be provided either in
147the file specified by `inferior-octave-startup-file' or by the default
148startup file, `~/.emacs-octave'."
149 (interactive "P")
150 (let ((buffer inferior-octave-buffer))
151 (get-buffer-create buffer)
152 (if (comint-check-proc buffer)
153 ()
154 (save-excursion
155 (set-buffer buffer)
156 (comint-mode)
157 (inferior-octave-startup)
158 (inferior-octave-mode)))
159 (if (not arg)
160 (pop-to-buffer buffer))))
161
162;;;###autoload
163(defalias 'run-octave 'inferior-octave)
164
165(defun inferior-octave-startup ()
166 "Start an inferior Octave process."
167 (let ((proc (comint-exec-1
168 (substring inferior-octave-buffer 1 -1)
169 inferior-octave-buffer
170 inferior-octave-program
171 inferior-octave-startup-args)))
172 (set-process-filter proc 'inferior-octave-output-digest)
173 (setq comint-ptyp process-connection-type
174 inferior-octave-process proc
175 inferior-octave-output-list nil
176 inferior-octave-output-string nil
177 inferior-octave-receive-in-progress t)
178
179 ;; This may look complicated ... However, we need to make sure that
180 ;; we additional startup code only AFTER Octave is ready (otherwise,
181 ;; output may be mixed up). Hence, we need to digest the Octave
182 ;; output to see when it issues a prompt.
183 (while inferior-octave-receive-in-progress
184 (accept-process-output inferior-octave-process))
185 (goto-char (point-max))
186 (set-marker (process-mark proc) (point))
187 (insert-before-markers
188 (concat
189 (if (not (bobp)) " \n")
190 (if inferior-octave-output-list
191 (concat (mapconcat
192 'identity inferior-octave-output-list "\n")
193 "\n"))))
194 ;; O.k., now we are ready for the Inferior Octave startup commands.
195 (let* (commands
196 (program (file-name-nondirectory inferior-octave-program))
197 (file (or inferior-octave-startup-file
198 (concat "~/.emacs-" program))))
199 (setq commands
200 (list "page_screen_output = 0;\n"
201 (if (not (string-equal
202 inferior-octave-output-string ">> "))
203 "PS1=\"\\\\s> \";\n")
204 (if (file-exists-p file)
205 (format "source (\"%s\");\n" file))))
206 (inferior-octave-send-list-and-digest commands))
207 (insert-before-markers
208 (concat
209 (if inferior-octave-output-list
210 (concat (mapconcat
211 'identity inferior-octave-output-list "\n")
212 "\n"))
213 inferior-octave-output-string))
214 ;; Next, we check whether Octave supports `completion_matches' ...
215 (inferior-octave-send-list-and-digest
216 (list "exist \"completion_matches\"\n"))
217 (setq inferior-octave-complete-impossible
218 (not (string-match "5$" (car inferior-octave-output-list))))
219
220 ;; And finally, everything is back to normal.
221 (set-process-filter proc 'inferior-octave-output-filter)
222 (run-hooks 'inferior-octave-startup-hook)))
223
224
225(defun inferior-octave-complete ()
226 "Perform completion on the Octave symbol preceding point.
227This is implemented using the Octave command `completion_matches' which
228is NOT available with versions of Octave prior to 2.0."
229 (interactive)
230 (let* ((end (point))
231 (command (save-excursion
232 (skip-syntax-backward "w_")
233 (and (looking-at comint-prompt-regexp)
234 (goto-char (match-end 0)))
235 (buffer-substring-no-properties (point) end)))
236 (proc (get-buffer-process inferior-octave-buffer))
237 (filter (process-filter proc)))
238 (cond (inferior-octave-complete-impossible
239 (error (concat
240 "Your Octave does not have `completion_matches'. "
241 "Please upgrade to version 2.X.")))
242 ((string-equal command "")
243 (message "Cannot complete an empty string"))
244 (t
245 (inferior-octave-send-list-and-digest
246 (list (concat "completion_matches (\"" command "\");\n")))
247 ;; Sort the list
248 (setq inferior-octave-output-list
249 (sort inferior-octave-output-list 'string-lessp))
250 ;; Remove duplicates
251 (let* ((x inferior-octave-output-list)
252 (y (cdr x)))
253 (while y
254 (if (string-equal (car x) (car y))
255 (setcdr x (setq y (cdr y)))
256 (setq x y
257 y (cdr y)))))
258 ;; And let comint handle the rest
259 (comint-dynamic-simple-complete
260 command inferior-octave-output-list)))))
261
262(defun inferior-octave-dynamic-list-input-ring ()
263 "List the buffer's input history in a help buffer"
264 ;; We cannot use `comint-dynamic-list-input-ring', because it replaces
265 ;; "completion" by "history reference" ...
266 (interactive)
267 (if (or (not (ring-p comint-input-ring))
268 (ring-empty-p comint-input-ring))
269 (message "No history")
270 (let ((history nil)
271 (history-buffer " *Input History*")
272 (index (1- (ring-length comint-input-ring)))
273 (conf (current-window-configuration)))
274 ;; We have to build up a list ourselves from the ring vector.
275 (while (>= index 0)
276 (setq history (cons (ring-ref comint-input-ring index) history)
277 index (1- index)))
278 ;; Change "completion" to "history reference"
279 ;; to make the display accurate.
280 (with-output-to-temp-buffer history-buffer
281 (display-completion-list history)
282 (set-buffer history-buffer))
283 (message "Hit space to flush")
284 (let ((ch (read-event)))
285 (if (eq ch ?\ )
286 (set-window-configuration conf)
287 (setq unread-command-events (list ch)))))))
288
289(defun inferior-octave-strip-ctrl-g (string)
290 "Strip leading `^G' character.
291If STRING starts with a `^G', ring the bell and strip it."
292 (if (string-match "^\a" string)
293 (progn
294 (ding)
295 (setq string (substring string 1))))
296 string)
297
298(defun inferior-octave-output-filter (proc string)
299 "Standard output filter for the inferior Octave process.
300Ring Emacs bell if process output starts with an ASCII bell, and pass
301the rest to `comint-output-filter'."
302 (comint-output-filter proc (inferior-octave-strip-ctrl-g string)))
303
304(defun inferior-octave-output-digest (proc string)
305 "Special output filter for the inferior Octave process.
306Save all output between newlines into `inferior-octave-output-list', and
307the rest to `inferior-octave-output-string'."
308 (setq string (concat inferior-octave-output-string string))
309 (while (string-match "\n" string)
310 (setq inferior-octave-output-list
311 (append inferior-octave-output-list
312 (list (substring string 0 (match-beginning 0))))
313 string (substring string (match-end 0))))
314 (if (string-match inferior-octave-prompt string)
315 (setq inferior-octave-receive-in-progress nil))
316 (setq inferior-octave-output-string string))
317
318(defun inferior-octave-send-list-and-digest (list)
319 "Send LIST to the inferior Octave process and digest the output.
320The elements of LIST have to be strings and are sent one by one. All
321output is passed to the filter `inferior-octave-output-digest'."
322 (let* ((proc inferior-octave-process)
323 (filter (process-filter proc))
324 string)
325 (set-process-filter proc 'inferior-octave-output-digest)
326 (setq inferior-octave-output-list nil)
327 (unwind-protect
328 (while (setq string (car list))
329 (setq inferior-octave-output-string nil
330 inferior-octave-receive-in-progress t)
331 (comint-send-string proc string)
332 (while inferior-octave-receive-in-progress
333 (accept-process-output proc))
334 (setq list (cdr list)))
335 (set-process-filter proc filter))))
336
337(defun inferior-octave-directory-tracker (string)
338 "Tracks `cd' commands issued to the inferior Octave process.
339Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused."
340 (if (string-match "[ \t]*cd[ \t]*\\([^ \t\n;]*\\)[ \t\n;]"
341 string)
342 (cd (substring string (match-beginning 1) (match-end 1)))))
343
344(defun inferior-octave-resync-dirs ()
345 "Resync the buffer's idea of the current directory.
346This command queries the inferior Octave process about its current
347directory and makes this the current buffer's default directory."
348 (interactive)
349 (inferior-octave-send-list-and-digest '("pwd\n"))
350 (cd (car inferior-octave-output-list)))
351
352;;; octave-inf.el ends here \ No newline at end of file