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 ---