diff options
| author | Leo Liu | 2013-04-25 22:51:08 +0800 |
|---|---|---|
| committer | Leo Liu | 2013-04-25 22:51:08 +0800 |
| commit | be64c05d81d6191397fa96e050b8b3ad8134b62b (patch) | |
| tree | 1b12d49580def0407fc08735fabf3bad0a4b5c71 /lisp | |
| parent | d79d37bd136542193dc61ac2e0163245058c4a13 (diff) | |
| download | emacs-be64c05d81d6191397fa96e050b8b3ad8134b62b.tar.gz emacs-be64c05d81d6191397fa96e050b8b3ad8134b62b.zip | |
Merge octave-mod.el and octave-inf.el into octave.el with some
cleanups.
* progmodes/octave.el: New file renamed from octave-mod.el.
* progmodes/octave-inf.el: Merged into octave.el.
* progmodes/octave-mod.el: Renamed to octave.el.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/progmodes/octave-inf.el | 387 | ||||
| -rw-r--r-- | lisp/progmodes/octave.el (renamed from lisp/progmodes/octave-mod.el) | 392 |
3 files changed, 371 insertions, 416 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e8933ee7c83..c3a97b7003e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2013-04-25 Leo Liu <sdl.web@gmail.com> | ||
| 2 | |||
| 3 | Merge octave-mod.el and octave-inf.el into octave.el with some | ||
| 4 | cleanups. | ||
| 5 | * progmodes/octave.el: New file renamed from octave-mod.el. | ||
| 6 | * progmodes/octave-inf.el: Merged into octave.el. | ||
| 7 | * progmodes/octave-mod.el: Renamed to octave.el. | ||
| 8 | |||
| 1 | 2013-04-25 Tassilo Horn <tsdh@gnu.org> | 9 | 2013-04-25 Tassilo Horn <tsdh@gnu.org> |
| 2 | 10 | ||
| 3 | * textmodes/reftex-vars.el | 11 | * textmodes/reftex-vars.el |
diff --git a/lisp/progmodes/octave-inf.el b/lisp/progmodes/octave-inf.el deleted file mode 100644 index 4a227db7164..00000000000 --- a/lisp/progmodes/octave-inf.el +++ /dev/null | |||
| @@ -1,387 +0,0 @@ | |||
| 1 | ;;; octave-inf.el --- running Octave as an inferior Emacs process | ||
| 2 | |||
| 3 | ;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> | ||
| 6 | ;; John Eaton <jwe@bevo.che.wisc.edu> | ||
| 7 | ;; Maintainer: FSF | ||
| 8 | ;; Keywords: languages | ||
| 9 | ;; Package: octave-mod | ||
| 10 | |||
| 11 | ;; This file is part of GNU Emacs. | ||
| 12 | |||
| 13 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 14 | ;; it under the terms of the GNU General Public License as published by | ||
| 15 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 16 | ;; (at your option) any later version. | ||
| 17 | |||
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | ;; GNU General Public License for more details. | ||
| 22 | |||
| 23 | ;; You should have received a copy of the GNU General Public License | ||
| 24 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 25 | |||
| 26 | ;;; Commentary: | ||
| 27 | |||
| 28 | ;;; Code: | ||
| 29 | |||
| 30 | (require 'octave-mod) | ||
| 31 | (require 'comint) | ||
| 32 | |||
| 33 | (defgroup octave-inferior nil | ||
| 34 | "Running Octave as an inferior Emacs process." | ||
| 35 | :group 'octave) | ||
| 36 | |||
| 37 | (defcustom inferior-octave-program "octave" | ||
| 38 | "Program invoked by `inferior-octave'." | ||
| 39 | :type 'string | ||
| 40 | :group 'octave-inferior) | ||
| 41 | |||
| 42 | (defcustom inferior-octave-prompt | ||
| 43 | "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ " | ||
| 44 | "Regexp to match prompts for the inferior Octave process." | ||
| 45 | :type 'regexp | ||
| 46 | :group 'octave-inferior) | ||
| 47 | |||
| 48 | (defcustom inferior-octave-startup-file nil | ||
| 49 | "Name of the inferior Octave startup file. | ||
| 50 | The contents of this file are sent to the inferior Octave process on | ||
| 51 | startup." | ||
| 52 | :type '(choice (const :tag "None" nil) | ||
| 53 | file) | ||
| 54 | :group 'octave-inferior) | ||
| 55 | |||
| 56 | (defcustom inferior-octave-startup-args nil | ||
| 57 | "List of command line arguments for the inferior Octave process. | ||
| 58 | For example, for suppressing the startup message and using `traditional' | ||
| 59 | mode, set this to (\"-q\" \"--traditional\")." | ||
| 60 | :type '(repeat string) | ||
| 61 | :group 'octave-inferior) | ||
| 62 | |||
| 63 | (defvar inferior-octave-mode-map | ||
| 64 | (let ((map (make-sparse-keymap))) | ||
| 65 | (set-keymap-parent map comint-mode-map) | ||
| 66 | (define-key map "\t" 'comint-dynamic-complete) | ||
| 67 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) | ||
| 68 | (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring) | ||
| 69 | (define-key map [menu-bar inout list-history] | ||
| 70 | '("List Input History" . inferior-octave-dynamic-list-input-ring)) | ||
| 71 | ;; FIXME: free C-h so it can do the describe-prefix-bindings. | ||
| 72 | (define-key map "\C-c\C-h" 'info-lookup-symbol) | ||
| 73 | map) | ||
| 74 | "Keymap used in Inferior Octave mode.") | ||
| 75 | |||
| 76 | (defvar inferior-octave-mode-syntax-table | ||
| 77 | (let ((table (make-syntax-table octave-mode-syntax-table))) | ||
| 78 | table) | ||
| 79 | "Syntax table in use in inferior-octave-mode buffers.") | ||
| 80 | |||
| 81 | (defcustom inferior-octave-mode-hook nil | ||
| 82 | "Hook to be run when Inferior Octave mode is started." | ||
| 83 | :type 'hook | ||
| 84 | :group 'octave-inferior) | ||
| 85 | |||
| 86 | (defvar inferior-octave-font-lock-keywords | ||
| 87 | (list | ||
| 88 | (cons inferior-octave-prompt 'font-lock-type-face)) | ||
| 89 | ;; Could certainly do more font locking in inferior Octave ... | ||
| 90 | "Additional expressions to highlight in Inferior Octave mode.") | ||
| 91 | |||
| 92 | |||
| 93 | ;;; Compatibility functions | ||
| 94 | (if (not (fboundp 'comint-line-beginning-position)) | ||
| 95 | ;; comint-line-beginning-position is defined in Emacs 21 | ||
| 96 | (defun comint-line-beginning-position () | ||
| 97 | "Returns the buffer position of the beginning of the line, after any prompt. | ||
| 98 | The prompt is assumed to be any text at the beginning of the line matching | ||
| 99 | the regular expression `comint-prompt-regexp', a buffer local variable." | ||
| 100 | (save-excursion (comint-bol nil) (point)))) | ||
| 101 | |||
| 102 | |||
| 103 | (defvar inferior-octave-output-list nil) | ||
| 104 | (defvar inferior-octave-output-string nil) | ||
| 105 | (defvar inferior-octave-receive-in-progress nil) | ||
| 106 | |||
| 107 | (defvar inferior-octave-startup-hook nil) | ||
| 108 | |||
| 109 | (defvar inferior-octave-complete-impossible nil | ||
| 110 | "Non-nil means that `inferior-octave-complete' is impossible.") | ||
| 111 | |||
| 112 | (defvar inferior-octave-has-built-in-variables nil | ||
| 113 | "Non-nil means that Octave has built-in variables.") | ||
| 114 | |||
| 115 | (defvar inferior-octave-dynamic-complete-functions | ||
| 116 | '(inferior-octave-completion-at-point comint-filename-completion) | ||
| 117 | "List of functions called to perform completion for inferior Octave. | ||
| 118 | This variable is used to initialize `comint-dynamic-complete-functions' | ||
| 119 | in the Inferior Octave buffer.") | ||
| 120 | |||
| 121 | (defvar info-lookup-mode) | ||
| 122 | |||
| 123 | (define-derived-mode inferior-octave-mode comint-mode "Inferior Octave" | ||
| 124 | "Major mode for interacting with an inferior Octave process. | ||
| 125 | Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs | ||
| 126 | buffer. | ||
| 127 | |||
| 128 | Entry to this mode successively runs the hooks `comint-mode-hook' and | ||
| 129 | `inferior-octave-mode-hook'." | ||
| 130 | (setq comint-prompt-regexp inferior-octave-prompt | ||
| 131 | mode-line-process '(":%s") | ||
| 132 | local-abbrev-table octave-abbrev-table) | ||
| 133 | |||
| 134 | (set (make-local-variable 'comment-start) octave-comment-start) | ||
| 135 | (set (make-local-variable 'comment-end) "") | ||
| 136 | (set (make-local-variable 'comment-column) 32) | ||
| 137 | (set (make-local-variable 'comment-start-skip) octave-comment-start-skip) | ||
| 138 | |||
| 139 | (set (make-local-variable 'font-lock-defaults) | ||
| 140 | '(inferior-octave-font-lock-keywords nil nil)) | ||
| 141 | |||
| 142 | (set (make-local-variable 'info-lookup-mode) 'octave-mode) | ||
| 143 | |||
| 144 | (setq comint-input-ring-file-name | ||
| 145 | (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist") | ||
| 146 | comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)) | ||
| 147 | (set (make-local-variable 'comint-dynamic-complete-functions) | ||
| 148 | inferior-octave-dynamic-complete-functions) | ||
| 149 | (add-hook 'comint-input-filter-functions | ||
| 150 | 'inferior-octave-directory-tracker nil t) | ||
| 151 | (comint-read-input-ring t)) | ||
| 152 | |||
| 153 | ;;;###autoload | ||
| 154 | (defun inferior-octave (&optional arg) | ||
| 155 | "Run an inferior Octave process, I/O via `inferior-octave-buffer'. | ||
| 156 | This buffer is put in Inferior Octave mode. See `inferior-octave-mode'. | ||
| 157 | |||
| 158 | Unless ARG is non-nil, switches to this buffer. | ||
| 159 | |||
| 160 | The elements of the list `inferior-octave-startup-args' are sent as | ||
| 161 | command line arguments to the inferior Octave process on startup. | ||
| 162 | |||
| 163 | Additional commands to be executed on startup can be provided either in | ||
| 164 | the file specified by `inferior-octave-startup-file' or by the default | ||
| 165 | startup file, `~/.emacs-octave'." | ||
| 166 | (interactive "P") | ||
| 167 | (let ((buffer inferior-octave-buffer)) | ||
| 168 | (get-buffer-create buffer) | ||
| 169 | (if (comint-check-proc buffer) | ||
| 170 | () | ||
| 171 | (with-current-buffer buffer | ||
| 172 | (comint-mode) | ||
| 173 | (inferior-octave-startup) | ||
| 174 | (inferior-octave-mode))) | ||
| 175 | (if (not arg) | ||
| 176 | (pop-to-buffer buffer)))) | ||
| 177 | |||
| 178 | ;;;###autoload | ||
| 179 | (defalias 'run-octave 'inferior-octave) | ||
| 180 | |||
| 181 | (defun inferior-octave-startup () | ||
| 182 | "Start an inferior Octave process." | ||
| 183 | (let ((proc (comint-exec-1 | ||
| 184 | (substring inferior-octave-buffer 1 -1) | ||
| 185 | inferior-octave-buffer | ||
| 186 | inferior-octave-program | ||
| 187 | (append (list "-i" "--no-line-editing") | ||
| 188 | inferior-octave-startup-args)))) | ||
| 189 | (set-process-filter proc 'inferior-octave-output-digest) | ||
| 190 | (setq comint-ptyp process-connection-type | ||
| 191 | inferior-octave-process proc | ||
| 192 | inferior-octave-output-list nil | ||
| 193 | inferior-octave-output-string nil | ||
| 194 | inferior-octave-receive-in-progress t) | ||
| 195 | |||
| 196 | ;; This may look complicated ... However, we need to make sure that | ||
| 197 | ;; we additional startup code only AFTER Octave is ready (otherwise, | ||
| 198 | ;; output may be mixed up). Hence, we need to digest the Octave | ||
| 199 | ;; output to see when it issues a prompt. | ||
| 200 | (while inferior-octave-receive-in-progress | ||
| 201 | (accept-process-output inferior-octave-process)) | ||
| 202 | (goto-char (point-max)) | ||
| 203 | (set-marker (process-mark proc) (point)) | ||
| 204 | (insert-before-markers | ||
| 205 | (concat | ||
| 206 | (if (not (bobp)) "\n") | ||
| 207 | (if inferior-octave-output-list | ||
| 208 | (concat (mapconcat | ||
| 209 | 'identity inferior-octave-output-list "\n") | ||
| 210 | "\n")))) | ||
| 211 | |||
| 212 | ;; Find out whether Octave has built-in variables. | ||
| 213 | (inferior-octave-send-list-and-digest | ||
| 214 | (list "exist \"LOADPATH\"\n")) | ||
| 215 | (setq inferior-octave-has-built-in-variables | ||
| 216 | (string-match "101$" (car inferior-octave-output-list))) | ||
| 217 | |||
| 218 | ;; An empty secondary prompt, as e.g. obtained by '--braindead', | ||
| 219 | ;; means trouble. | ||
| 220 | (inferior-octave-send-list-and-digest (list "PS2\n")) | ||
| 221 | (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list)) | ||
| 222 | (inferior-octave-send-list-and-digest | ||
| 223 | (list (if inferior-octave-has-built-in-variables | ||
| 224 | "PS2 = \"> \"\n" | ||
| 225 | "PS2 (\"> \");\n")))) | ||
| 226 | |||
| 227 | ;; O.k., now we are ready for the Inferior Octave startup commands. | ||
| 228 | (let* (commands | ||
| 229 | (program (file-name-nondirectory inferior-octave-program)) | ||
| 230 | (file (or inferior-octave-startup-file | ||
| 231 | (concat "~/.emacs-" program)))) | ||
| 232 | (setq commands | ||
| 233 | (list "more off;\n" | ||
| 234 | (if (not (string-equal | ||
| 235 | inferior-octave-output-string ">> ")) | ||
| 236 | (if inferior-octave-has-built-in-variables | ||
| 237 | "PS1=\"\\\\s> \";\n" | ||
| 238 | "PS1 (\"\\\\s> \");\n")) | ||
| 239 | (if (file-exists-p file) | ||
| 240 | (format "source (\"%s\");\n" file)))) | ||
| 241 | (inferior-octave-send-list-and-digest commands)) | ||
| 242 | (insert-before-markers | ||
| 243 | (concat | ||
| 244 | (if inferior-octave-output-list | ||
| 245 | (concat (mapconcat | ||
| 246 | 'identity inferior-octave-output-list "\n") | ||
| 247 | "\n")) | ||
| 248 | inferior-octave-output-string)) | ||
| 249 | ;; Next, we check whether Octave supports `completion_matches' ... | ||
| 250 | (inferior-octave-send-list-and-digest | ||
| 251 | (list "exist \"completion_matches\"\n")) | ||
| 252 | (setq inferior-octave-complete-impossible | ||
| 253 | (not (string-match "5$" (car inferior-octave-output-list)))) | ||
| 254 | |||
| 255 | ;; And finally, everything is back to normal. | ||
| 256 | (set-process-filter proc 'inferior-octave-output-filter) | ||
| 257 | (run-hooks 'inferior-octave-startup-hook) | ||
| 258 | (run-hooks 'inferior-octave-startup-hook) | ||
| 259 | ;; Just in case, to be sure a cd in the startup file | ||
| 260 | ;; won't have detrimental effects. | ||
| 261 | (inferior-octave-resync-dirs))) | ||
| 262 | |||
| 263 | |||
| 264 | (defun inferior-octave-completion-at-point () | ||
| 265 | "Return the data to complete the Octave symbol at point." | ||
| 266 | (let* ((end (point)) | ||
| 267 | (start | ||
| 268 | (save-excursion | ||
| 269 | (skip-syntax-backward "w_" (comint-line-beginning-position)) | ||
| 270 | (point)))) | ||
| 271 | (cond ((eq start end) nil) | ||
| 272 | (inferior-octave-complete-impossible | ||
| 273 | (message (concat | ||
| 274 | "Your Octave does not have `completion_matches'. " | ||
| 275 | "Please upgrade to version 2.X.")) | ||
| 276 | nil) | ||
| 277 | (t | ||
| 278 | (list | ||
| 279 | start end | ||
| 280 | (completion-table-dynamic | ||
| 281 | (lambda (command) | ||
| 282 | (inferior-octave-send-list-and-digest | ||
| 283 | (list (concat "completion_matches (\"" command "\");\n"))) | ||
| 284 | (sort (delete-dups inferior-octave-output-list) | ||
| 285 | 'string-lessp)))))))) | ||
| 286 | |||
| 287 | (define-obsolete-function-alias 'inferior-octave-complete | ||
| 288 | 'completion-at-point "24.1") | ||
| 289 | |||
| 290 | (defun inferior-octave-dynamic-list-input-ring () | ||
| 291 | "List the buffer's input history in a help buffer." | ||
| 292 | ;; We cannot use `comint-dynamic-list-input-ring', because it replaces | ||
| 293 | ;; "completion" by "history reference" ... | ||
| 294 | (interactive) | ||
| 295 | (if (or (not (ring-p comint-input-ring)) | ||
| 296 | (ring-empty-p comint-input-ring)) | ||
| 297 | (message "No history") | ||
| 298 | (let ((history nil) | ||
| 299 | (history-buffer " *Input History*") | ||
| 300 | (index (1- (ring-length comint-input-ring))) | ||
| 301 | (conf (current-window-configuration))) | ||
| 302 | ;; We have to build up a list ourselves from the ring vector. | ||
| 303 | (while (>= index 0) | ||
| 304 | (setq history (cons (ring-ref comint-input-ring index) history) | ||
| 305 | index (1- index))) | ||
| 306 | ;; Change "completion" to "history reference" | ||
| 307 | ;; to make the display accurate. | ||
| 308 | (with-output-to-temp-buffer history-buffer | ||
| 309 | (display-completion-list history) | ||
| 310 | (set-buffer history-buffer)) | ||
| 311 | (message "Hit space to flush") | ||
| 312 | (let ((ch (read-event))) | ||
| 313 | (if (eq ch ?\ ) | ||
| 314 | (set-window-configuration conf) | ||
| 315 | (setq unread-command-events (list ch))))))) | ||
| 316 | |||
| 317 | (defun inferior-octave-strip-ctrl-g (string) | ||
| 318 | "Strip leading `^G' character. | ||
| 319 | If STRING starts with a `^G', ring the bell and strip it." | ||
| 320 | (if (string-match "^\a" string) | ||
| 321 | (progn | ||
| 322 | (ding) | ||
| 323 | (setq string (substring string 1)))) | ||
| 324 | string) | ||
| 325 | |||
| 326 | (defun inferior-octave-output-filter (proc string) | ||
| 327 | "Standard output filter for the inferior Octave process. | ||
| 328 | Ring Emacs bell if process output starts with an ASCII bell, and pass | ||
| 329 | the rest to `comint-output-filter'." | ||
| 330 | (comint-output-filter proc (inferior-octave-strip-ctrl-g string))) | ||
| 331 | |||
| 332 | (defun inferior-octave-output-digest (_proc string) | ||
| 333 | "Special output filter for the inferior Octave process. | ||
| 334 | Save all output between newlines into `inferior-octave-output-list', and | ||
| 335 | the rest to `inferior-octave-output-string'." | ||
| 336 | (setq string (concat inferior-octave-output-string string)) | ||
| 337 | (while (string-match "\n" string) | ||
| 338 | (setq inferior-octave-output-list | ||
| 339 | (append inferior-octave-output-list | ||
| 340 | (list (substring string 0 (match-beginning 0)))) | ||
| 341 | string (substring string (match-end 0)))) | ||
| 342 | (if (string-match inferior-octave-prompt string) | ||
| 343 | (setq inferior-octave-receive-in-progress nil)) | ||
| 344 | (setq inferior-octave-output-string string)) | ||
| 345 | |||
| 346 | (defun inferior-octave-send-list-and-digest (list) | ||
| 347 | "Send LIST to the inferior Octave process and digest the output. | ||
| 348 | The elements of LIST have to be strings and are sent one by one. All | ||
| 349 | output is passed to the filter `inferior-octave-output-digest'." | ||
| 350 | (let* ((proc inferior-octave-process) | ||
| 351 | string) | ||
| 352 | (add-function :override (process-filter proc) | ||
| 353 | #'inferior-octave-output-digest) | ||
| 354 | (setq inferior-octave-output-list nil) | ||
| 355 | (unwind-protect | ||
| 356 | (while (setq string (car list)) | ||
| 357 | (setq inferior-octave-output-string nil | ||
| 358 | inferior-octave-receive-in-progress t) | ||
| 359 | (comint-send-string proc string) | ||
| 360 | (while inferior-octave-receive-in-progress | ||
| 361 | (accept-process-output proc)) | ||
| 362 | (setq list (cdr list))) | ||
| 363 | (remove-function (process-filter proc) | ||
| 364 | #'inferior-octave-output-digest)))) | ||
| 365 | |||
| 366 | (defun inferior-octave-directory-tracker (string) | ||
| 367 | "Tracks `cd' commands issued to the inferior Octave process. | ||
| 368 | Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused." | ||
| 369 | (cond | ||
| 370 | ((string-match "^[ \t]*cd[ \t;]*$" string) | ||
| 371 | (cd "~")) | ||
| 372 | ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string) | ||
| 373 | (cd (substring string (match-beginning 1) (match-end 1)))))) | ||
| 374 | |||
| 375 | (defun inferior-octave-resync-dirs () | ||
| 376 | "Resync the buffer's idea of the current directory. | ||
| 377 | This command queries the inferior Octave process about its current | ||
| 378 | directory and makes this the current buffer's default directory." | ||
| 379 | (interactive) | ||
| 380 | (inferior-octave-send-list-and-digest '("disp (pwd ())\n")) | ||
| 381 | (cd (car inferior-octave-output-list))) | ||
| 382 | |||
| 383 | ;;; provide ourself | ||
| 384 | |||
| 385 | (provide 'octave-inf) | ||
| 386 | |||
| 387 | ;;; octave-inf.el ends here | ||
diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave.el index d161754cad9..c652822bf47 100644 --- a/lisp/progmodes/octave-mod.el +++ b/lisp/progmodes/octave.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; octave-mod.el --- editing Octave source files under Emacs | 1 | ;;; octave.el --- editing octave source files under emacs |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -24,30 +24,21 @@ | |||
| 24 | 24 | ||
| 25 | ;;; Commentary: | 25 | ;;; Commentary: |
| 26 | 26 | ||
| 27 | ;; This package provides Emacs support for Octave. | 27 | ;; This package provides emacs support for octave. It defines a major |
| 28 | ;; It defines Octave mode, a major mode for editing | 28 | ;; mode for editing octave code and contains code for interacting with |
| 29 | ;; Octave code. | 29 | ;; an inferior octave process using comint. |
| 30 | 30 | ||
| 31 | ;; The file octave-inf.el contains code for interacting with an inferior | 31 | ;; See the documentation of `octave-mode' and `run-octave' for further |
| 32 | ;; Octave process using comint. | 32 | ;; information on usage and customization. |
| 33 | |||
| 34 | ;; See the documentation of `octave-mode' and | ||
| 35 | ;; `run-octave' for further information on usage and customization. | ||
| 36 | 33 | ||
| 37 | ;;; Code: | 34 | ;;; Code: |
| 38 | (require 'custom) | 35 | (require 'comint) |
| 39 | 36 | ||
| 40 | (defgroup octave nil | 37 | (defgroup octave nil |
| 41 | "Major mode for editing Octave source files." | 38 | "Editing Octave code." |
| 42 | :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) | 39 | :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) |
| 43 | :group 'languages) | 40 | :group 'languages) |
| 44 | 41 | ||
| 45 | (defvar inferior-octave-output-list nil) | ||
| 46 | (defvar inferior-octave-output-string nil) | ||
| 47 | (defvar inferior-octave-receive-in-progress nil) | ||
| 48 | |||
| 49 | (declare-function inferior-octave-send-list-and-digest "octave-inf" (list)) | ||
| 50 | |||
| 51 | (defconst octave-maintainer-address | 42 | (defconst octave-maintainer-address |
| 52 | "Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>, bug-gnu-emacs@gnu.org" | 43 | "Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>, bug-gnu-emacs@gnu.org" |
| 53 | "Current maintainer of the Emacs Octave package.") | 44 | "Current maintainer of the Emacs Octave package.") |
| @@ -84,7 +75,7 @@ | |||
| 84 | ("`upc" "unwind_protect_cleanup") | 75 | ("`upc" "unwind_protect_cleanup") |
| 85 | ("`w" "while ()"))) | 76 | ("`w" "while ()"))) |
| 86 | "Abbrev table for Octave's reserved words. | 77 | "Abbrev table for Octave's reserved words. |
| 87 | Used in `octave-mode' and inferior-octave-mode buffers. | 78 | Used in `octave-mode' and `inferior-octave-mode' buffers. |
| 88 | All Octave abbrevs start with a grave accent (`)." | 79 | All Octave abbrevs start with a grave accent (`)." |
| 89 | :regexp "\\(?:[^`]\\|^\\)\\(\\(?:\\<\\|`\\)\\w+\\)\\W*") | 80 | :regexp "\\(?:[^`]\\|^\\)\\(\\(?:\\<\\|`\\)\\w+\\)\\W*") |
| 90 | 81 | ||
| @@ -156,6 +147,7 @@ All Octave abbrevs start with a grave accent (`)." | |||
| 156 | The string `function' and its name are given by the first and third | 147 | The string `function' and its name are given by the first and third |
| 157 | parenthetical grouping.") | 148 | parenthetical grouping.") |
| 158 | 149 | ||
| 150 | |||
| 159 | (defvar octave-font-lock-keywords | 151 | (defvar octave-font-lock-keywords |
| 160 | (list | 152 | (list |
| 161 | ;; Fontify all builtin keywords. | 153 | ;; Fontify all builtin keywords. |
| @@ -201,12 +193,6 @@ parenthetical grouping.") | |||
| 201 | (put-text-property (match-beginning 1) (match-end 1) | 193 | (put-text-property (match-beginning 1) (match-end 1) |
| 202 | 'syntax-table (string-to-syntax "\"'"))))) | 194 | 'syntax-table (string-to-syntax "\"'"))))) |
| 203 | 195 | ||
| 204 | (defcustom inferior-octave-buffer "*Inferior Octave*" | ||
| 205 | "Name of buffer for running an inferior Octave process." | ||
| 206 | :type 'string | ||
| 207 | :group 'octave-inferior) | ||
| 208 | |||
| 209 | (defvar inferior-octave-process nil) | ||
| 210 | 196 | ||
| 211 | (defvar octave-mode-map | 197 | (defvar octave-mode-map |
| 212 | (let ((map (make-sparse-keymap))) | 198 | (let ((map (make-sparse-keymap))) |
| @@ -655,6 +641,357 @@ including a reproducible test case and send the message." | |||
| 655 | 641 | ||
| 656 | (easy-menu-add octave-mode-menu) | 642 | (easy-menu-add octave-mode-menu) |
| 657 | (octave-initialize-completions)) | 643 | (octave-initialize-completions)) |
| 644 | |||
| 645 | |||
| 646 | (defcustom inferior-octave-program "octave" | ||
| 647 | "Program invoked by `inferior-octave'." | ||
| 648 | :type 'string | ||
| 649 | :group 'octave) | ||
| 650 | |||
| 651 | (defcustom inferior-octave-buffer "*Inferior Octave*" | ||
| 652 | "Name of buffer for running an inferior Octave process." | ||
| 653 | :type 'string | ||
| 654 | :group 'octave) | ||
| 655 | |||
| 656 | (defcustom inferior-octave-prompt | ||
| 657 | "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ " | ||
| 658 | "Regexp to match prompts for the inferior Octave process." | ||
| 659 | :type 'regexp | ||
| 660 | :group 'octave) | ||
| 661 | |||
| 662 | (defcustom inferior-octave-startup-file nil | ||
| 663 | "Name of the inferior Octave startup file. | ||
| 664 | The contents of this file are sent to the inferior Octave process on | ||
| 665 | startup." | ||
| 666 | :type '(choice (const :tag "None" nil) | ||
| 667 | file) | ||
| 668 | :group 'octave) | ||
| 669 | |||
| 670 | (defcustom inferior-octave-startup-args nil | ||
| 671 | "List of command line arguments for the inferior Octave process. | ||
| 672 | For example, for suppressing the startup message and using `traditional' | ||
| 673 | mode, set this to (\"-q\" \"--traditional\")." | ||
| 674 | :type '(repeat string) | ||
| 675 | :group 'octave) | ||
| 676 | |||
| 677 | (defcustom inferior-octave-mode-hook nil | ||
| 678 | "Hook to be run when Inferior Octave mode is started." | ||
| 679 | :type 'hook | ||
| 680 | :group 'octave) | ||
| 681 | |||
| 682 | (defvar inferior-octave-process nil) | ||
| 683 | |||
| 684 | (defvar inferior-octave-mode-map | ||
| 685 | (let ((map (make-sparse-keymap))) | ||
| 686 | (set-keymap-parent map comint-mode-map) | ||
| 687 | (define-key map "\t" 'comint-dynamic-complete) | ||
| 688 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) | ||
| 689 | (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring) | ||
| 690 | (define-key map [menu-bar inout list-history] | ||
| 691 | '("List Input History" . inferior-octave-dynamic-list-input-ring)) | ||
| 692 | map) | ||
| 693 | "Keymap used in Inferior Octave mode.") | ||
| 694 | |||
| 695 | (defvar inferior-octave-mode-syntax-table | ||
| 696 | (let ((table (make-syntax-table octave-mode-syntax-table))) | ||
| 697 | table) | ||
| 698 | "Syntax table in use in inferior-octave-mode buffers.") | ||
| 699 | |||
| 700 | (defvar inferior-octave-font-lock-keywords | ||
| 701 | (list | ||
| 702 | (cons inferior-octave-prompt 'font-lock-type-face)) | ||
| 703 | ;; Could certainly do more font locking in inferior Octave ... | ||
| 704 | "Additional expressions to highlight in Inferior Octave mode.") | ||
| 705 | |||
| 706 | |||
| 707 | ;;; Compatibility functions | ||
| 708 | (if (not (fboundp 'comint-line-beginning-position)) | ||
| 709 | ;; comint-line-beginning-position is defined in Emacs 21 | ||
| 710 | (defun comint-line-beginning-position () | ||
| 711 | "Returns the buffer position of the beginning of the line, after any prompt. | ||
| 712 | The prompt is assumed to be any text at the beginning of the line matching | ||
| 713 | the regular expression `comint-prompt-regexp', a buffer local variable." | ||
| 714 | (save-excursion (comint-bol nil) (point)))) | ||
| 715 | |||
| 716 | |||
| 717 | (defvar inferior-octave-output-list nil) | ||
| 718 | (defvar inferior-octave-output-string nil) | ||
| 719 | (defvar inferior-octave-receive-in-progress nil) | ||
| 720 | |||
| 721 | (defvar inferior-octave-startup-hook nil) | ||
| 722 | |||
| 723 | (defvar inferior-octave-complete-impossible nil | ||
| 724 | "Non-nil means that `inferior-octave-complete' is impossible.") | ||
| 725 | |||
| 726 | (defvar inferior-octave-has-built-in-variables nil | ||
| 727 | "Non-nil means that Octave has built-in variables.") | ||
| 728 | |||
| 729 | (defvar inferior-octave-dynamic-complete-functions | ||
| 730 | '(inferior-octave-completion-at-point comint-filename-completion) | ||
| 731 | "List of functions called to perform completion for inferior Octave. | ||
| 732 | This variable is used to initialize `comint-dynamic-complete-functions' | ||
| 733 | in the Inferior Octave buffer.") | ||
| 734 | |||
| 735 | (defvar info-lookup-mode) | ||
| 736 | |||
| 737 | (define-derived-mode inferior-octave-mode comint-mode "Inferior Octave" | ||
| 738 | "Major mode for interacting with an inferior Octave process. | ||
| 739 | Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs | ||
| 740 | buffer. | ||
| 741 | |||
| 742 | Entry to this mode successively runs the hooks `comint-mode-hook' and | ||
| 743 | `inferior-octave-mode-hook'." | ||
| 744 | (setq comint-prompt-regexp inferior-octave-prompt | ||
| 745 | mode-line-process '(":%s") | ||
| 746 | local-abbrev-table octave-abbrev-table) | ||
| 747 | |||
| 748 | (set (make-local-variable 'comment-start) octave-comment-start) | ||
| 749 | (set (make-local-variable 'comment-end) "") | ||
| 750 | (set (make-local-variable 'comment-column) 32) | ||
| 751 | (set (make-local-variable 'comment-start-skip) octave-comment-start-skip) | ||
| 752 | |||
| 753 | (set (make-local-variable 'font-lock-defaults) | ||
| 754 | '(inferior-octave-font-lock-keywords nil nil)) | ||
| 755 | |||
| 756 | (set (make-local-variable 'info-lookup-mode) 'octave-mode) | ||
| 757 | |||
| 758 | (setq comint-input-ring-file-name | ||
| 759 | (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist") | ||
| 760 | comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)) | ||
| 761 | (set (make-local-variable 'comint-dynamic-complete-functions) | ||
| 762 | inferior-octave-dynamic-complete-functions) | ||
| 763 | (add-hook 'comint-input-filter-functions | ||
| 764 | 'inferior-octave-directory-tracker nil t) | ||
| 765 | (comint-read-input-ring t)) | ||
| 766 | |||
| 767 | ;;;###autoload | ||
| 768 | (defun inferior-octave (&optional arg) | ||
| 769 | "Run an inferior Octave process, I/O via `inferior-octave-buffer'. | ||
| 770 | This buffer is put in Inferior Octave mode. See `inferior-octave-mode'. | ||
| 771 | |||
| 772 | Unless ARG is non-nil, switches to this buffer. | ||
| 773 | |||
| 774 | The elements of the list `inferior-octave-startup-args' are sent as | ||
| 775 | command line arguments to the inferior Octave process on startup. | ||
| 776 | |||
| 777 | Additional commands to be executed on startup can be provided either in | ||
| 778 | the file specified by `inferior-octave-startup-file' or by the default | ||
| 779 | startup file, `~/.emacs-octave'." | ||
| 780 | (interactive "P") | ||
| 781 | (let ((buffer inferior-octave-buffer)) | ||
| 782 | (get-buffer-create buffer) | ||
| 783 | (if (comint-check-proc buffer) | ||
| 784 | () | ||
| 785 | (with-current-buffer buffer | ||
| 786 | (comint-mode) | ||
| 787 | (inferior-octave-startup) | ||
| 788 | (inferior-octave-mode))) | ||
| 789 | (if (not arg) | ||
| 790 | (pop-to-buffer buffer)))) | ||
| 791 | |||
| 792 | ;;;###autoload | ||
| 793 | (defalias 'run-octave 'inferior-octave) | ||
| 794 | |||
| 795 | (defun inferior-octave-startup () | ||
| 796 | "Start an inferior Octave process." | ||
| 797 | (let ((proc (comint-exec-1 | ||
| 798 | (substring inferior-octave-buffer 1 -1) | ||
| 799 | inferior-octave-buffer | ||
| 800 | inferior-octave-program | ||
| 801 | (append (list "-i" "--no-line-editing") | ||
| 802 | inferior-octave-startup-args)))) | ||
| 803 | (set-process-filter proc 'inferior-octave-output-digest) | ||
| 804 | (setq comint-ptyp process-connection-type | ||
| 805 | inferior-octave-process proc | ||
| 806 | inferior-octave-output-list nil | ||
| 807 | inferior-octave-output-string nil | ||
| 808 | inferior-octave-receive-in-progress t) | ||
| 809 | |||
| 810 | ;; This may look complicated ... However, we need to make sure that | ||
| 811 | ;; we additional startup code only AFTER Octave is ready (otherwise, | ||
| 812 | ;; output may be mixed up). Hence, we need to digest the Octave | ||
| 813 | ;; output to see when it issues a prompt. | ||
| 814 | (while inferior-octave-receive-in-progress | ||
| 815 | (accept-process-output inferior-octave-process)) | ||
| 816 | (goto-char (point-max)) | ||
| 817 | (set-marker (process-mark proc) (point)) | ||
| 818 | (insert-before-markers | ||
| 819 | (concat | ||
| 820 | (if (not (bobp)) "\n") | ||
| 821 | (if inferior-octave-output-list | ||
| 822 | (concat (mapconcat | ||
| 823 | 'identity inferior-octave-output-list "\n") | ||
| 824 | "\n")))) | ||
| 825 | |||
| 826 | ;; Find out whether Octave has built-in variables. | ||
| 827 | (inferior-octave-send-list-and-digest | ||
| 828 | (list "exist \"LOADPATH\"\n")) | ||
| 829 | (setq inferior-octave-has-built-in-variables | ||
| 830 | (string-match "101$" (car inferior-octave-output-list))) | ||
| 831 | |||
| 832 | ;; An empty secondary prompt, as e.g. obtained by '--braindead', | ||
| 833 | ;; means trouble. | ||
| 834 | (inferior-octave-send-list-and-digest (list "PS2\n")) | ||
| 835 | (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list)) | ||
| 836 | (inferior-octave-send-list-and-digest | ||
| 837 | (list (if inferior-octave-has-built-in-variables | ||
| 838 | "PS2 = \"> \"\n" | ||
| 839 | "PS2 (\"> \");\n")))) | ||
| 840 | |||
| 841 | ;; O.k., now we are ready for the Inferior Octave startup commands. | ||
| 842 | (let* (commands | ||
| 843 | (program (file-name-nondirectory inferior-octave-program)) | ||
| 844 | (file (or inferior-octave-startup-file | ||
| 845 | (concat "~/.emacs-" program)))) | ||
| 846 | (setq commands | ||
| 847 | (list "more off;\n" | ||
| 848 | (if (not (string-equal | ||
| 849 | inferior-octave-output-string ">> ")) | ||
| 850 | (if inferior-octave-has-built-in-variables | ||
| 851 | "PS1=\"\\\\s> \";\n" | ||
| 852 | "PS1 (\"\\\\s> \");\n")) | ||
| 853 | (if (file-exists-p file) | ||
| 854 | (format "source (\"%s\");\n" file)))) | ||
| 855 | (inferior-octave-send-list-and-digest commands)) | ||
| 856 | (insert-before-markers | ||
| 857 | (concat | ||
| 858 | (if inferior-octave-output-list | ||
| 859 | (concat (mapconcat | ||
| 860 | 'identity inferior-octave-output-list "\n") | ||
| 861 | "\n")) | ||
| 862 | inferior-octave-output-string)) | ||
| 863 | ;; Next, we check whether Octave supports `completion_matches' ... | ||
| 864 | (inferior-octave-send-list-and-digest | ||
| 865 | (list "exist \"completion_matches\"\n")) | ||
| 866 | (setq inferior-octave-complete-impossible | ||
| 867 | (not (string-match "5$" (car inferior-octave-output-list)))) | ||
| 868 | |||
| 869 | ;; And finally, everything is back to normal. | ||
| 870 | (set-process-filter proc 'inferior-octave-output-filter) | ||
| 871 | (run-hooks 'inferior-octave-startup-hook) | ||
| 872 | (run-hooks 'inferior-octave-startup-hook) | ||
| 873 | ;; Just in case, to be sure a cd in the startup file | ||
| 874 | ;; won't have detrimental effects. | ||
| 875 | (inferior-octave-resync-dirs))) | ||
| 876 | |||
| 877 | (defun inferior-octave-completion-at-point () | ||
| 878 | "Return the data to complete the Octave symbol at point." | ||
| 879 | (let* ((end (point)) | ||
| 880 | (start | ||
| 881 | (save-excursion | ||
| 882 | (skip-syntax-backward "w_" (comint-line-beginning-position)) | ||
| 883 | (point)))) | ||
| 884 | (cond ((eq start end) nil) | ||
| 885 | (inferior-octave-complete-impossible | ||
| 886 | (message (concat | ||
| 887 | "Your Octave does not have `completion_matches'. " | ||
| 888 | "Please upgrade to version 2.X.")) | ||
| 889 | nil) | ||
| 890 | (t | ||
| 891 | (list | ||
| 892 | start end | ||
| 893 | (completion-table-dynamic | ||
| 894 | (lambda (command) | ||
| 895 | (inferior-octave-send-list-and-digest | ||
| 896 | (list (concat "completion_matches (\"" command "\");\n"))) | ||
| 897 | (sort (delete-dups inferior-octave-output-list) | ||
| 898 | 'string-lessp)))))))) | ||
| 899 | |||
| 900 | (define-obsolete-function-alias 'inferior-octave-complete | ||
| 901 | 'completion-at-point "24.1") | ||
| 902 | |||
| 903 | (defun inferior-octave-dynamic-list-input-ring () | ||
| 904 | "List the buffer's input history in a help buffer." | ||
| 905 | ;; We cannot use `comint-dynamic-list-input-ring', because it replaces | ||
| 906 | ;; "completion" by "history reference" ... | ||
| 907 | (interactive) | ||
| 908 | (if (or (not (ring-p comint-input-ring)) | ||
| 909 | (ring-empty-p comint-input-ring)) | ||
| 910 | (message "No history") | ||
| 911 | (let ((history nil) | ||
| 912 | (history-buffer " *Input History*") | ||
| 913 | (index (1- (ring-length comint-input-ring))) | ||
| 914 | (conf (current-window-configuration))) | ||
| 915 | ;; We have to build up a list ourselves from the ring vector. | ||
| 916 | (while (>= index 0) | ||
| 917 | (setq history (cons (ring-ref comint-input-ring index) history) | ||
| 918 | index (1- index))) | ||
| 919 | ;; Change "completion" to "history reference" | ||
| 920 | ;; to make the display accurate. | ||
| 921 | (with-output-to-temp-buffer history-buffer | ||
| 922 | (display-completion-list history) | ||
| 923 | (set-buffer history-buffer)) | ||
| 924 | (message "Hit space to flush") | ||
| 925 | (let ((ch (read-event))) | ||
| 926 | (if (eq ch ?\ ) | ||
| 927 | (set-window-configuration conf) | ||
| 928 | (setq unread-command-events (list ch))))))) | ||
| 929 | |||
| 930 | (defun inferior-octave-strip-ctrl-g (string) | ||
| 931 | "Strip leading `^G' character. | ||
| 932 | If STRING starts with a `^G', ring the bell and strip it." | ||
| 933 | (if (string-match "^\a" string) | ||
| 934 | (progn | ||
| 935 | (ding) | ||
| 936 | (setq string (substring string 1)))) | ||
| 937 | string) | ||
| 938 | |||
| 939 | (defun inferior-octave-output-filter (proc string) | ||
| 940 | "Standard output filter for the inferior Octave process. | ||
| 941 | Ring Emacs bell if process output starts with an ASCII bell, and pass | ||
| 942 | the rest to `comint-output-filter'." | ||
| 943 | (comint-output-filter proc (inferior-octave-strip-ctrl-g string))) | ||
| 944 | |||
| 945 | (defun inferior-octave-output-digest (_proc string) | ||
| 946 | "Special output filter for the inferior Octave process. | ||
| 947 | Save all output between newlines into `inferior-octave-output-list', and | ||
| 948 | the rest to `inferior-octave-output-string'." | ||
| 949 | (setq string (concat inferior-octave-output-string string)) | ||
| 950 | (while (string-match "\n" string) | ||
| 951 | (setq inferior-octave-output-list | ||
| 952 | (append inferior-octave-output-list | ||
| 953 | (list (substring string 0 (match-beginning 0)))) | ||
| 954 | string (substring string (match-end 0)))) | ||
| 955 | (if (string-match inferior-octave-prompt string) | ||
| 956 | (setq inferior-octave-receive-in-progress nil)) | ||
| 957 | (setq inferior-octave-output-string string)) | ||
| 958 | |||
| 959 | (defun inferior-octave-send-list-and-digest (list) | ||
| 960 | "Send LIST to the inferior Octave process and digest the output. | ||
| 961 | The elements of LIST have to be strings and are sent one by one. All | ||
| 962 | output is passed to the filter `inferior-octave-output-digest'." | ||
| 963 | (let* ((proc inferior-octave-process) | ||
| 964 | (filter (process-filter proc)) | ||
| 965 | string) | ||
| 966 | (set-process-filter proc 'inferior-octave-output-digest) | ||
| 967 | (setq inferior-octave-output-list nil) | ||
| 968 | (unwind-protect | ||
| 969 | (while (setq string (car list)) | ||
| 970 | (setq inferior-octave-output-string nil | ||
| 971 | inferior-octave-receive-in-progress t) | ||
| 972 | (comint-send-string proc string) | ||
| 973 | (while inferior-octave-receive-in-progress | ||
| 974 | (accept-process-output proc)) | ||
| 975 | (setq list (cdr list))) | ||
| 976 | (set-process-filter proc filter)))) | ||
| 977 | |||
| 978 | (defun inferior-octave-directory-tracker (string) | ||
| 979 | "Tracks `cd' commands issued to the inferior Octave process. | ||
| 980 | Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused." | ||
| 981 | (cond | ||
| 982 | ((string-match "^[ \t]*cd[ \t;]*$" string) | ||
| 983 | (cd "~")) | ||
| 984 | ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string) | ||
| 985 | (cd (substring string (match-beginning 1) (match-end 1)))))) | ||
| 986 | |||
| 987 | (defun inferior-octave-resync-dirs () | ||
| 988 | "Resync the buffer's idea of the current directory. | ||
| 989 | This command queries the inferior Octave process about its current | ||
| 990 | directory and makes this the current buffer's default directory." | ||
| 991 | (interactive) | ||
| 992 | (inferior-octave-send-list-and-digest '("disp (pwd ())\n")) | ||
| 993 | (cd (car inferior-octave-output-list))) | ||
| 994 | |||
| 658 | 995 | ||
| 659 | ;;; Miscellaneous useful functions | 996 | ;;; Miscellaneous useful functions |
| 660 | 997 | ||
| @@ -1143,8 +1480,5 @@ code line." | |||
| 1143 | 'octave-send-line-auto-forward | 1480 | 'octave-send-line-auto-forward |
| 1144 | 'octave-send-show-buffer)))) | 1481 | 'octave-send-show-buffer)))) |
| 1145 | 1482 | ||
| 1146 | ;; provide ourself | 1483 | (provide 'octave) |
| 1147 | 1484 | ;;; octave.el ends here | |
| 1148 | (provide 'octave-mod) | ||
| 1149 | |||
| 1150 | ;;; octave-mod.el ends here | ||