Mercurial > emacs
annotate lisp/progmodes/octave-inf.el @ 61263:56619c3aaf99
(fancy-splash-text): Shorten default text of
"Emacs Tutorial" line. Also, if the current language env
indicates an available tutorial file other than TUTORIAL,
extract its title and append it to the line in parentheses.
(fancy-splash-insert): If arg is a thunk, funcall it.
author | Thien-Thi Nguyen <ttn@gnuvola.org> |
---|---|
date | Mon, 04 Apr 2005 07:41:58 +0000 |
parents | 03afc05bc725 |
children | f2892faa87d4 |
rev | line source |
---|---|
17517 | 1 ;;; octave-inf.el --- running Octave as an inferior Emacs process |
16903 | 2 |
17517 | 3 ;; Copyright (C) 1997 Free Software Foundation, Inc. |
16903 | 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 | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
30902
diff
changeset
|
27 ;;; Commentary: |
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
30902
diff
changeset
|
28 |
16903 | 29 ;;; Code: |
30 | |
16904
2bc5f76917e0
Require octave-mod, not octave.
Richard M. Stallman <rms@gnu.org>
parents:
16903
diff
changeset
|
31 (require 'octave-mod) |
16903 | 32 (require 'comint) |
33 | |
20781 | 34 (defgroup octave-inferior nil |
35 "Running Octave as an inferior Emacs process." | |
36 :group 'octave) | |
16903 | 37 |
20781 | 38 (defcustom inferior-octave-program "octave" |
39 "*Program invoked by `inferior-octave'." | |
40 :type 'string | |
41 :group 'octave-inferior) | |
42 | |
43 (defcustom inferior-octave-prompt | |
52952
03afc05bc725
(inferior-octave-prompt): Recognize version number in prompt.
Lute Kamstra <lute@gnu.org>
parents:
52401
diff
changeset
|
44 "\\(^octave\\(\\|.bin\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ " |
20781 | 45 "*Regexp to match prompts for the inferior Octave process." |
46 :type 'regexp | |
47 :group 'octave-inferior) | |
16903 | 48 |
20781 | 49 (defcustom inferior-octave-startup-file nil |
16903 | 50 "*Name of the inferior Octave startup file. |
51 The contents of this file are sent to the inferior Octave process on | |
20781 | 52 startup." |
53 :type '(choice (const :tag "None" nil) | |
54 file) | |
55 :group 'octave-inferior) | |
16903 | 56 |
25719
f440228994ba
(inferior-octave-startup): Ensure -i and --no-line-editing are passed
Stephen Eglen <stephen@gnu.org>
parents:
25568
diff
changeset
|
57 (defcustom inferior-octave-startup-args nil |
16903 | 58 "*List of command line arguments for the inferior Octave process. |
59 For example, for suppressing the startup message and using `traditional' | |
20781 | 60 mode, set this to (\"-q\" \"--traditional\")." |
61 :type '(repeat string) | |
62 :group 'octave-inferior) | |
16903 | 63 |
64 (defvar inferior-octave-mode-map nil | |
65 "Keymap used in Inferior Octave mode.") | |
66 (if inferior-octave-mode-map | |
67 () | |
68 (let ((map (copy-keymap comint-mode-map))) | |
69 (define-key map "\t" 'comint-dynamic-complete) | |
70 (define-key map "\M-?" 'comint-dynamic-list-filename-completions) | |
71 (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring) | |
72 (define-key map [menu-bar inout list-history] | |
73 '("List Input History" . inferior-octave-dynamic-list-input-ring)) | |
74 (define-key map "\C-c\C-h" 'octave-help) | |
75 (setq inferior-octave-mode-map map))) | |
76 | |
77 (defvar inferior-octave-mode-syntax-table nil | |
78 "Syntax table in use in inferior-octave-mode buffers.") | |
79 (if inferior-octave-mode-syntax-table | |
80 () | |
81 (let ((table (make-syntax-table))) | |
82 (modify-syntax-entry ?\` "w" table) | |
83 (modify-syntax-entry ?\# "<" table) | |
84 (modify-syntax-entry ?\n ">" table) | |
85 (setq inferior-octave-mode-syntax-table table))) | |
86 | |
20781 | 87 (defcustom inferior-octave-mode-hook nil |
88 "*Hook to be run when Inferior Octave mode is started." | |
89 :type 'hook | |
90 :group 'octave-inferior) | |
16903 | 91 |
92 (defvar inferior-octave-font-lock-keywords | |
93 (list | |
94 (cons inferior-octave-prompt 'font-lock-type-face)) | |
95 ;; Could certainly do more font locking in inferior Octave ... | |
96 "Additional expressions to highlight in Inferior Octave mode.") | |
97 | |
30902
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
98 |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
99 ;;; Compatibility functions |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
100 (if (not (fboundp 'comint-line-beginning-position)) |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
101 ;; comint-line-beginning-position is defined in Emacs 21 |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
102 (defun comint-line-beginning-position () |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
103 "Returns the buffer position of the beginning of the line, after any prompt. |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
104 The prompt is assumed to be any text at the beginning of the line matching |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
105 the regular expression `comint-prompt-regexp', a buffer local variable." |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
106 (save-excursion (comint-bol nil) (point)))) |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
107 |
ffe3b5100238
Add compatibility definition of comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
30646
diff
changeset
|
108 |
16903 | 109 (defvar inferior-octave-output-list nil) |
110 (defvar inferior-octave-output-string nil) | |
111 (defvar inferior-octave-receive-in-progress nil) | |
112 | |
113 (defvar inferior-octave-startup-hook nil) | |
114 | |
115 (defvar inferior-octave-complete-impossible nil | |
116 "Non-nil means that `inferior-octave-complete' is impossible.") | |
117 | |
118 (defvar inferior-octave-dynamic-complete-functions | |
49598
0d8b17d428b5
Trailing whitepace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
38436
diff
changeset
|
119 '(inferior-octave-complete comint-dynamic-complete-filename) |
16903 | 120 "List of functions called to perform completion for inferior Octave. |
121 This variable is used to initialize `comint-dynamic-complete-functions' | |
122 in the Inferior Octave buffer.") | |
123 | |
124 (defun inferior-octave-mode () | |
125 "Major mode for interacting with an inferior Octave process. | |
126 Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs | |
127 buffer. | |
128 | |
129 Entry to this mode successively runs the hooks `comint-mode-hook' and | |
130 `inferior-octave-mode-hook'." | |
131 (interactive) | |
132 (comint-mode) | |
133 (setq comint-prompt-regexp inferior-octave-prompt | |
134 major-mode 'inferior-octave-mode | |
135 mode-name "Inferior Octave" | |
136 mode-line-process '(":%s") | |
137 local-abbrev-table octave-abbrev-table) | |
138 (use-local-map inferior-octave-mode-map) | |
139 (set-syntax-table inferior-octave-mode-syntax-table) | |
140 | |
49598
0d8b17d428b5
Trailing whitepace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
38436
diff
changeset
|
141 (make-local-variable 'comment-start) |
16903 | 142 (setq comment-start octave-comment-start) |
143 (make-local-variable 'comment-end) | |
144 (setq comment-end "") | |
145 (make-local-variable 'comment-column) | |
49598
0d8b17d428b5
Trailing whitepace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
38436
diff
changeset
|
146 (setq comment-column 32) |
16903 | 147 (make-local-variable 'comment-start-skip) |
148 (setq comment-start-skip octave-comment-start-skip) | |
149 | |
150 (make-local-variable 'font-lock-defaults) | |
151 (setq font-lock-defaults '(inferior-octave-font-lock-keywords nil nil)) | |
152 | |
153 (setq comint-input-ring-file-name | |
154 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist") | |
155 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024) | |
156 comint-input-filter-functions '(inferior-octave-directory-tracker) | |
157 comint-dynamic-complete-functions | |
158 inferior-octave-dynamic-complete-functions) | |
159 (comint-read-input-ring t) | |
160 | |
161 (run-hooks 'inferior-octave-mode-hook)) | |
162 | |
163 ;;;###autoload | |
164 (defun inferior-octave (&optional arg) | |
165 "Run an inferior Octave process, I/O via `inferior-octave-buffer'. | |
166 This buffer is put in Inferior Octave mode. See `inferior-octave-mode'. | |
167 | |
168 Unless ARG is non-nil, switches to this buffer. | |
169 | |
170 The elements of the list `inferior-octave-startup-args' are sent as | |
171 command line arguments to the inferior Octave process on startup. | |
172 | |
173 Additional commands to be executed on startup can be provided either in | |
174 the file specified by `inferior-octave-startup-file' or by the default | |
175 startup file, `~/.emacs-octave'." | |
176 (interactive "P") | |
177 (let ((buffer inferior-octave-buffer)) | |
178 (get-buffer-create buffer) | |
179 (if (comint-check-proc buffer) | |
180 () | |
181 (save-excursion | |
182 (set-buffer buffer) | |
183 (comint-mode) | |
184 (inferior-octave-startup) | |
185 (inferior-octave-mode))) | |
186 (if (not arg) | |
187 (pop-to-buffer buffer)))) | |
188 | |
189 ;;;###autoload | |
190 (defalias 'run-octave 'inferior-octave) | |
191 | |
192 (defun inferior-octave-startup () | |
193 "Start an inferior Octave process." | |
194 (let ((proc (comint-exec-1 | |
195 (substring inferior-octave-buffer 1 -1) | |
196 inferior-octave-buffer | |
197 inferior-octave-program | |
25719
f440228994ba
(inferior-octave-startup): Ensure -i and --no-line-editing are passed
Stephen Eglen <stephen@gnu.org>
parents:
25568
diff
changeset
|
198 (append (list "-i" "--no-line-editing") |
f440228994ba
(inferior-octave-startup): Ensure -i and --no-line-editing are passed
Stephen Eglen <stephen@gnu.org>
parents:
25568
diff
changeset
|
199 inferior-octave-startup-args)))) |
16903 | 200 (set-process-filter proc 'inferior-octave-output-digest) |
201 (setq comint-ptyp process-connection-type | |
202 inferior-octave-process proc | |
203 inferior-octave-output-list nil | |
204 inferior-octave-output-string nil | |
205 inferior-octave-receive-in-progress t) | |
206 | |
207 ;; This may look complicated ... However, we need to make sure that | |
208 ;; we additional startup code only AFTER Octave is ready (otherwise, | |
209 ;; output may be mixed up). Hence, we need to digest the Octave | |
210 ;; output to see when it issues a prompt. | |
211 (while inferior-octave-receive-in-progress | |
212 (accept-process-output inferior-octave-process)) | |
213 (goto-char (point-max)) | |
214 (set-marker (process-mark proc) (point)) | |
215 (insert-before-markers | |
216 (concat | |
217 (if (not (bobp)) "\n") | |
218 (if inferior-octave-output-list | |
219 (concat (mapconcat | |
220 'identity inferior-octave-output-list "\n") | |
221 "\n")))) | |
222 ;; O.k., now we are ready for the Inferior Octave startup commands. | |
223 (let* (commands | |
224 (program (file-name-nondirectory inferior-octave-program)) | |
225 (file (or inferior-octave-startup-file | |
226 (concat "~/.emacs-" program)))) | |
227 (setq commands | |
228 (list "page_screen_output = 0;\n" | |
229 (if (not (string-equal | |
49598
0d8b17d428b5
Trailing whitepace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
38436
diff
changeset
|
230 inferior-octave-output-string ">> ")) |
16903 | 231 "PS1=\"\\\\s> \";\n") |
232 (if (file-exists-p file) | |
233 (format "source (\"%s\");\n" file)))) | |
234 (inferior-octave-send-list-and-digest commands)) | |
235 (insert-before-markers | |
236 (concat | |
237 (if inferior-octave-output-list | |
238 (concat (mapconcat | |
239 'identity inferior-octave-output-list "\n") | |
240 "\n")) | |
241 inferior-octave-output-string)) | |
242 ;; Next, we check whether Octave supports `completion_matches' ... | |
243 (inferior-octave-send-list-and-digest | |
244 (list "exist \"completion_matches\"\n")) | |
245 (setq inferior-octave-complete-impossible | |
246 (not (string-match "5$" (car inferior-octave-output-list)))) | |
247 | |
248 ;; And finally, everything is back to normal. | |
249 (set-process-filter proc 'inferior-octave-output-filter) | |
250 (run-hooks 'inferior-octave-startup-hook))) | |
251 | |
252 | |
253 (defun inferior-octave-complete () | |
254 "Perform completion on the Octave symbol preceding point. | |
255 This is implemented using the Octave command `completion_matches' which | |
256 is NOT available with versions of Octave prior to 2.0." | |
257 (interactive) | |
258 (let* ((end (point)) | |
30646
bb2ebaf63949
(inferior-octave-complete): Use comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
25719
diff
changeset
|
259 (command |
bb2ebaf63949
(inferior-octave-complete): Use comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
25719
diff
changeset
|
260 (save-excursion |
bb2ebaf63949
(inferior-octave-complete): Use comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
25719
diff
changeset
|
261 (skip-syntax-backward "w_" (comint-line-beginning-position)) |
bb2ebaf63949
(inferior-octave-complete): Use comint-line-beginning-position.
Miles Bader <miles@gnu.org>
parents:
25719
diff
changeset
|
262 (buffer-substring-no-properties (point) end))) |
16903 | 263 (proc (get-buffer-process inferior-octave-buffer)) |
264 (filter (process-filter proc))) | |
265 (cond (inferior-octave-complete-impossible | |
266 (error (concat | |
267 "Your Octave does not have `completion_matches'. " | |
268 "Please upgrade to version 2.X."))) | |
269 ((string-equal command "") | |
270 (message "Cannot complete an empty string")) | |
271 (t | |
272 (inferior-octave-send-list-and-digest | |
273 (list (concat "completion_matches (\"" command "\");\n"))) | |
274 ;; Sort the list | |
275 (setq inferior-octave-output-list | |
276 (sort inferior-octave-output-list 'string-lessp)) | |
277 ;; Remove duplicates | |
278 (let* ((x inferior-octave-output-list) | |
279 (y (cdr x))) | |
280 (while y | |
281 (if (string-equal (car x) (car y)) | |
282 (setcdr x (setq y (cdr y))) | |
283 (setq x y | |
284 y (cdr y))))) | |
285 ;; And let comint handle the rest | |
286 (comint-dynamic-simple-complete | |
287 command inferior-octave-output-list))))) | |
288 | |
289 (defun inferior-octave-dynamic-list-input-ring () | |
290 "List the buffer's input history in a help buffer" | |
291 ;; We cannot use `comint-dynamic-list-input-ring', because it replaces | |
292 ;; "completion" by "history reference" ... | |
293 (interactive) | |
294 (if (or (not (ring-p comint-input-ring)) | |
295 (ring-empty-p comint-input-ring)) | |
296 (message "No history") | |
297 (let ((history nil) | |
298 (history-buffer " *Input History*") | |
299 (index (1- (ring-length comint-input-ring))) | |
300 (conf (current-window-configuration))) | |
301 ;; We have to build up a list ourselves from the ring vector. | |
302 (while (>= index 0) | |
303 (setq history (cons (ring-ref comint-input-ring index) history) | |
304 index (1- index))) | |
305 ;; Change "completion" to "history reference" | |
306 ;; to make the display accurate. | |
307 (with-output-to-temp-buffer history-buffer | |
308 (display-completion-list history) | |
309 (set-buffer history-buffer)) | |
310 (message "Hit space to flush") | |
311 (let ((ch (read-event))) | |
312 (if (eq ch ?\ ) | |
313 (set-window-configuration conf) | |
314 (setq unread-command-events (list ch))))))) | |
315 | |
316 (defun inferior-octave-strip-ctrl-g (string) | |
317 "Strip leading `^G' character. | |
318 If STRING starts with a `^G', ring the bell and strip it." | |
319 (if (string-match "^\a" string) | |
320 (progn | |
321 (ding) | |
322 (setq string (substring string 1)))) | |
323 string) | |
324 | |
325 (defun inferior-octave-output-filter (proc string) | |
326 "Standard output filter for the inferior Octave process. | |
327 Ring Emacs bell if process output starts with an ASCII bell, and pass | |
328 the rest to `comint-output-filter'." | |
329 (comint-output-filter proc (inferior-octave-strip-ctrl-g string))) | |
330 | |
331 (defun inferior-octave-output-digest (proc string) | |
332 "Special output filter for the inferior Octave process. | |
333 Save all output between newlines into `inferior-octave-output-list', and | |
334 the rest to `inferior-octave-output-string'." | |
335 (setq string (concat inferior-octave-output-string string)) | |
336 (while (string-match "\n" string) | |
337 (setq inferior-octave-output-list | |
338 (append inferior-octave-output-list | |
339 (list (substring string 0 (match-beginning 0)))) | |
340 string (substring string (match-end 0)))) | |
341 (if (string-match inferior-octave-prompt string) | |
342 (setq inferior-octave-receive-in-progress nil)) | |
343 (setq inferior-octave-output-string string)) | |
344 | |
345 (defun inferior-octave-send-list-and-digest (list) | |
346 "Send LIST to the inferior Octave process and digest the output. | |
347 The elements of LIST have to be strings and are sent one by one. All | |
348 output is passed to the filter `inferior-octave-output-digest'." | |
349 (let* ((proc inferior-octave-process) | |
350 (filter (process-filter proc)) | |
351 string) | |
352 (set-process-filter proc 'inferior-octave-output-digest) | |
353 (setq inferior-octave-output-list nil) | |
354 (unwind-protect | |
355 (while (setq string (car list)) | |
356 (setq inferior-octave-output-string nil | |
357 inferior-octave-receive-in-progress t) | |
358 (comint-send-string proc string) | |
359 (while inferior-octave-receive-in-progress | |
360 (accept-process-output proc)) | |
361 (setq list (cdr list))) | |
362 (set-process-filter proc filter)))) | |
363 | |
364 (defun inferior-octave-directory-tracker (string) | |
365 "Tracks `cd' commands issued to the inferior Octave process. | |
366 Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused." | |
24930
ea5923fcc5b2
inferior-octave-directory-tracker: Change regexp so that it doesn't
Stephen Eglen <stephen@gnu.org>
parents:
23343
diff
changeset
|
367 (cond |
ea5923fcc5b2
inferior-octave-directory-tracker: Change regexp so that it doesn't
Stephen Eglen <stephen@gnu.org>
parents:
23343
diff
changeset
|
368 ((string-match "^[ \t]*cd[ \t;]*$" string) |
ea5923fcc5b2
inferior-octave-directory-tracker: Change regexp so that it doesn't
Stephen Eglen <stephen@gnu.org>
parents:
23343
diff
changeset
|
369 (cd "~")) |
ea5923fcc5b2
inferior-octave-directory-tracker: Change regexp so that it doesn't
Stephen Eglen <stephen@gnu.org>
parents:
23343
diff
changeset
|
370 ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string) |
ea5923fcc5b2
inferior-octave-directory-tracker: Change regexp so that it doesn't
Stephen Eglen <stephen@gnu.org>
parents:
23343
diff
changeset
|
371 (cd (substring string (match-beginning 1) (match-end 1)))))) |
16903 | 372 |
373 (defun inferior-octave-resync-dirs () | |
374 "Resync the buffer's idea of the current directory. | |
375 This command queries the inferior Octave process about its current | |
376 directory and makes this the current buffer's default directory." | |
377 (interactive) | |
378 (inferior-octave-send-list-and-digest '("pwd\n")) | |
379 (cd (car inferior-octave-output-list))) | |
380 | |
17150 | 381 ;;; provide ourself |
382 | |
383 (provide 'octave-inf) | |
384 | |
52401 | 385 ;;; arch-tag: bdce0395-24d1-4bb4-bfba-6fb1eeb1a660 |
16906 | 386 ;;; octave-inf.el ends here |