Mercurial > octave
diff octave-mode.el @ 5:9c27e323492f
[project @ 1993-08-08 01:29:13 by jwe]
Initial revision
author | jwe |
---|---|
date | Sun, 08 Aug 1993 01:32:33 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/octave-mode.el Sun Aug 08 01:32:33 1993 +0000 @@ -0,0 +1,346 @@ +;; octave-mode.el - major mode for editing Octave source with GNU Emacs +;; +;; This major mode for GNU Emacs provides support for editing Octave +;; source files. It automatically indents for block structures, line +;; continuations (e.g., ...), and comments. The usual paren matching +;; support is included. Indenting for continued matrix expressions is +;; currently not supported. Perhaps it will be in the future. Auto-fill +;; mode seems to actually work! For convient use add something like the +;; following to your .emacs start-up file: +;; +;; (autoload 'octave-mode "octave-mode" "Enter Octave-mode." t) +;; (setq auto-mode-alist (cons '("\\.m$" . octave-mode) auto-mode-alist)) +;; (setq octave-mode-hook '(lambda () (setq fill-column 74))) +;; +;; Enjoy. +;; +;; Last modified Sun Mar 7 17:55:20 1993. +;; +;; This file was modified by John W. Eaton (jwe@che.utexas.edu) from +;; the file matlab-mode.el which is: +;; +;; Copyright (C) 1991 Matthew R. Wette. +;; Everyone is granted permission to copy, modify and redistribute this +;; file provided: +;; 1. All copies contain this copyright notice. +;; 2. All modified copies shall carry a prominant notice stating who +;; made the last modification and the date of such modification. +;; 3. No charge is made for this software or works derived from it. +;; This clause shall not be construed as constraining other software +;; distributed on the same medium as this software, nor is a +;; distribution fee considered a charge. +;; +;; Version 1.01, dated 25Jan91 +;; +;; 25Jan91 by Matt Wette, mwette@csi.jpl.nasa.gov +;; Got indentation of matrix expression to work, I think. Also, +;; added tabs to comment start regular-expression. +;; +;; 14Jan91 by Matt Wette, mwette@csi.jpl.nasa.gov +;; Added functions (ml-unbal-matexp ml-matexp-indent) for matrix +;; expressions. +;; +;; 07Jan91 by Matt Wette, mwette@csi.jpl.nasa.gov +;; Many changes. Seems to work reasonably well. Still would like +;; to add some support for filling in comments and handle continued +;; matrix expressions. Released as Version 1.0. +;; +;; 04Jan91 by Matt Wette, mwette@csi.jpl.nasa.gov +;; Created. Used eiffel.el as a guide. + + +;; Constants used in all Octave-mode buffers. +(defconst octave-indent-level 2 + "*The indentation in Octave-mode.") + +(defconst octave-comment-column 40 + "*The goal comment column in Octave-mode buffers.") + + +;; Syntax Table +(defvar octave-mode-syntax-table nil + "Syntax table used in Octave-mode buffers.") + +(if octave-mode-syntax-table + () + (setq octave-mode-syntax-table (make-syntax-table)) + (modify-syntax-entry ?\\ "." octave-mode-syntax-table) + (modify-syntax-entry ?/ "." octave-mode-syntax-table) + (modify-syntax-entry ?* "." octave-mode-syntax-table) + (modify-syntax-entry ?+ "." octave-mode-syntax-table) + (modify-syntax-entry ?- "." octave-mode-syntax-table) + (modify-syntax-entry ?= "." octave-mode-syntax-table) + (modify-syntax-entry ?< "." octave-mode-syntax-table) + (modify-syntax-entry ?> "." octave-mode-syntax-table) + (modify-syntax-entry ?& "." octave-mode-syntax-table) + (modify-syntax-entry ?| "." octave-mode-syntax-table) + (modify-syntax-entry ?\' "\"" octave-mode-syntax-table) + (modify-syntax-entry ?# "<" octave-mode-syntax-table) + (modify-syntax-entry ?% "<" octave-mode-syntax-table) + (modify-syntax-entry ?\n ">" octave-mode-syntax-table) + (set-syntax-table octave-mode-syntax-table)) + + +;; Abbrev Table +(defvar octave-mode-abbrev-table nil + "Abbrev table used in Octave-mode buffers.") + +(define-abbrev-table 'octave-mode-abbrev-table ()) + + +;; Mode Map +(defvar octave-mode-map () + "Keymap used in octave-mode.") + +(if octave-mode-map + () + (setq octave-mode-map (make-sparse-keymap)) + (define-key octave-mode-map "\r" 'octave-return) + (define-key octave-mode-map "\t" 'octave-indent-line) + (define-key octave-mode-map "\M-;" 'octave-comment) + (define-key octave-mode-map "\C-ct" 'octave-line-type) + (define-key octave-mode-map "\C-ci" 'octave-indent-type) + (define-key octave-mode-map "\M-\r" 'newline)) + + +;; Octave Mode +(defun octave-mode () + "Major mode for editing Octave source files. Version 1.0, 23 Feb 1993. +Will run octave-mode-hook if it is non-nil. Auto-fill-mode seems to work. +Filling does not work (yet). +Special Key Bindings: +\\{octave-mode-map} +Variables: + octave-indent-level Level to indent blocks. + octave-comment-column Goal column for on-line comments. + fill-column Column used in auto-fill (default=70). +Commands: + octave-mode Enter Octave major mode. + octave-return Handle return with indenting. + octave-indent-line Indent line for structure. + octave-comment Add comment to current line. + octave-comment-indent Compute indent for comment. + octave-line-type Tell current line type (for debugging). + octave-indent-type Tell last indent type (for debugging). +To add automatic support put something like the following in your .emacs file: + \(autoload 'octave-mode \"octave-mode\" \"Enter Octave-mode.\" t\) + \(setq auto-mode-alist \(cons '\(\"\\\\.m$\" . octave-mode\) \ +auto-mode-alist\)\) + \(setq octave-mode-hook '\(lambda \(\) \(setq fill-column 74\)\)\)" + (interactive) + (kill-all-local-variables) + (use-local-map octave-mode-map) + (setq major-mode 'octave-mode) + (setq mode-name "Octave") + (setq local-abbrev-table octave-mode-abbrev-table) + (set-syntax-table octave-mode-syntax-table) + (make-local-variable 'paragraph-start) + (setq paragraph-start (concat "^$\\|" page-delimiter)) + (make-local-variable 'paragraph-separate) + (setq paragraph-separate paragraph-start) + (make-local-variable 'paragraph-ignore-fill-prefix) + (setq paragraph-ignore-fill-prefix t) + (make-local-variable 'indent-line-function) + (setq indent-line-function 'octave-indent-line) + (make-local-variable 'comment-start-skip) + (setq comment-start-skip "[%#][ \t]*") + (make-local-variable 'comment-column) + (setq comment-column 'octave-comment-column) + (make-local-variable 'comment-indent-hook) + (setq comment-indent-hook 'octave-comment-indent) + (make-local-variable 'fill-column) + (setq fill-column default-fill-column) + (run-hooks 'octave-mode-hook)) + + +(defun octave-return () + "Handle carriage return in Octave-mode." + (interactive) + (if (oct-block-end-line) + (octave-indent-line)) + (newline) + (octave-indent-line)) + +(defun octave-comment () + "Add a comment to the following line, or format if one already exists." + (interactive) + (cond + ((oct-empty-line) + (octave-indent-line) + (insert "# ")) + ((oct-comment-line)) + (t + (end-of-line) + (re-search-backward "[^ \t^]" 0 t) + (forward-char) + (delete-horizontal-space) + (if (< (current-column) octave-comment-column) + (indent-to octave-comment-column) + (insert " ")) + (insert "# ")))) + +(defun octave-comment-indent () + "Indent a comment line in Octave-mode." + (oct-calc-indent)) + +(defun octave-indent-line () + "Indent a line in Octave-mode." + (interactive) + (save-excursion + (beginning-of-line) + (delete-horizontal-space) + (indent-to (oct-calc-indent))) + (skip-chars-forward " \t")) + +(defun octave-line-type () + "Display type of current line. Used in debugging." + (interactive) + (cond + ((oct-empty-line) + (message "octave-line-type: empty-line")) + ((oct-comment-line) + (message "octave-line-type: comment-line")) + ((oct-continuation-line) + (message "octave-line-type: continuation-line")) + ((oct-block-beg-end-line) + (message "octave-line-type: block-beg-end-line")) + ((oct-block-beg-line) + (message "octave-line-type: block-beg-line")) + ((oct-block-end-line) + (message "octave-line-type: block-end-line")) + (t + (message "octave-line-type: other")))) + +(defun octave-indent-type () + "Display type of current or previous nonempty line. Used in debugging." + (interactive) + (message (concat "octave-ident-type: " oct-last-indent-type))) + +(defun octave-fill-region (from to &optional justify-flag) + "Fill the region of comments. +Prefix arg (non-nil third arg, if called from program) +means justify as well." + (interactive "r\nP") + (messages "octave-fill-region not implemented yet.")) + +(defvar oct-last-indent-type "unknown" + "String to tell line type.") + +(defun oct-calc-indent () + "Return the appropriate indentation for this line as an int." + (let ((indent 0)) + (save-excursion + (forward-line -1) ; compute indent based on previous + (if (oct-empty-line) ; non-empty line + (re-search-backward "[^ \t\n]" 0 t)) + (cond + ((oct-empty-line) + (setq oct-last-indent-type "empty")) + ((oct-comment-line) + (setq oct-last-indent-type "comment")) + ((oct-continuation-line) + (setq oct-last-indent-type "continuation") + (setq indent (* 2 octave-indent-level))) + ((oct-block-beg-end-line) + (setq oct-last-indent-type "block begin-end")) + ((oct-block-beg-line) + (setq oct-last-indent-type "block begin") + (setq indent octave-indent-level)) + ((oct-unbal-matexp-line) + (setq oct-last-indent-type "unbalanced-matrix-expression") + (setq indent (oct-calc-matexp-indent))) + (t + (setq oct-last-indent-type "other"))) + (setq indent (+ indent (current-indentation))) + (if (= 0 (forward-line -1)) + (if (oct-continuation-line) + (setq indent (- indent (* 2 octave-indent-level)))))) + (if (oct-block-end-line) (setq indent (- indent octave-indent-level))) + (if (< indent 0) (setq indent 0)) + indent)) + + +(defun oct-empty-line () + "Returns t if current line is empty." + (save-excursion + (beginning-of-line) + (looking-at "^[ \t]*$"))) + +(defun oct-comment-line () + "Returns t if current line is an Octave comment line." + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (looking-at "[%#]"))) + +(defun oct-continuation-line () + "Returns t if current line ends in ... and optional comment." + (save-excursion + (beginning-of-line) + (re-search-forward "\\.\\.\\.+[ \t]*\\(%.*\\)?$" (oct-eoln-point) t))) + +(defun oct-eoln-point () + "Returns point for end-of-line in Octave-mode." + (save-excursion + (end-of-line) + (point))) + +(defun oct-block-beg-line () + "Returns t if line contains beginning of Octave block." + (save-excursion + (beginning-of-line) + (looking-at (concat "\\([^%#\n]*[ \t]\\)?" oct-block-beg-kw)))) + +(defconst oct-block-beg-kw "\\(for\\|while\\|if\\|else\\|elseif\\|function\\)" + "Regular expression for keywords which begin blocks in Octave-mode.") + +(defun oct-block-end-line () + "Returns t if line contains end of Octave block." + (save-excursion + (beginning-of-line) + (looking-at (concat "\\([^%#\n]*[ \t]\\)?" oct-block-end-kw)))) + +(defconst oct-block-end-kw "\\(end\\|endfor\\|endwhile\\|endif\\|endfunction\\|else\\|elseif\\)" + "Regular expression for keywords which end blocks.") + +(defun oct-block-beg-end-line () + "Returns t if line contains matching block begin-end in Octave-mode." + (save-excursion + (beginning-of-line) + (looking-at (concat + "\\([^%#\n]*[ \t]\\)?" oct-block-beg-kw + "." "\\([^%#\n]*[ \t]\\)?" oct-block-end-kw)))) + +(defun oct-unbal-matexp-line () + (if (= (oct-calc-matexp-indent) 0) + () + t)) + +(defun oct-calc-matexp-indent () + (let ((indent 0)) + (save-excursion + (beginning-of-line) + (while (< (point) (oct-eoln-point)) + (cond + ((looking-at "\\[") + (setq indent (+ indent octave-indent-level))) + ((looking-at "\\]") + (setq indent (- indent octave-indent-level)))) + (forward-char))) + (* 2 indent))) + +(defun oct-comment-on-line () + "Returns t if current line contains a comment." + (save-excursion + (beginning-of-line) + (looking-at "[^\n]*[%#]"))) + +(defun oct-in-comment () + "Returns t if point is in a comment." + (save-excursion + (and (/= (point) (point-max)) (forward-char)) + (search-backward "[%#]" (save-excursion (beginning-of-line) (point)) t))) + +(provide 'octave-mode) + +;; --- last line of octave-mode.el ---