Article View: gnu.emacs.help
Article #189256Re: matlab-mode anyone ?
From: thomas m. palka
Date: Thu, 21 Mar 1991 18:58
Date: Thu, 21 Mar 1991 18:58
355 lines
13458 bytes
13458 bytes
In article <AJT.91Mar21125536@bilbo.bhpmrl.oz.au> ajt@bilbo.bhpmrl.oz.au (Andrew Telford) writes:
>In our organisation we use one of the MATLAB variety of programs. I
>would be interested to know if anyone has written a mode for editing the
>.m files (m-files). Their syntax is quite simple - maybe another
>language mode needs to be hacked to get it to work. The most useful
>feature would be handling indents.
I'm annexing the one that we use at MIT. Hope it helps.
tom
tompalka@mit.edu
;; matlab-mode.el - major mode for Pro-Matlab dot-m files
;;
;; This major mode for GNU emacs provides support for editing Pro-Matlab
;; dot-m 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 'matlab-mode "matlab-mode" "Enter Matlab-mode." t)
;; (setq auto-mode-alist (cons '("\\.m$" . matlab-mode) auto-mode-alist))
;; (setq matlab-mode-hook '(lambda () (setq fill-column 74)))
;; Enjoy.
;;
;; 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 Matlab-mode buffers.
(defconst matlab-indent-level 2
"*The indentation in Matlab-mode.")
(defconst matlab-comment-column 40
"*The goal comment column in Matlab-mode buffers.")
;; Syntax Table
(defvar matlab-mode-syntax-table nil
"Syntax table used in Matlab-mode buffers.")
(if matlab-mode-syntax-table
()
(setq matlab-mode-syntax-table (make-syntax-table))
(modify-syntax-entry ?\\ "." matlab-mode-syntax-table)
(modify-syntax-entry ?/ "." matlab-mode-syntax-table)
(modify-syntax-entry ?* "." matlab-mode-syntax-table)
(modify-syntax-entry ?+ "." matlab-mode-syntax-table)
(modify-syntax-entry ?- "." matlab-mode-syntax-table)
(modify-syntax-entry ?= "." matlab-mode-syntax-table)
(modify-syntax-entry ?< "." matlab-mode-syntax-table)
(modify-syntax-entry ?> "." matlab-mode-syntax-table)
(modify-syntax-entry ?& "." matlab-mode-syntax-table)
(modify-syntax-entry ?| "." matlab-mode-syntax-table)
(modify-syntax-entry ?\' "\"" matlab-mode-syntax-table)
(modify-syntax-entry ?% "<" matlab-mode-syntax-table)
(modify-syntax-entry ?\n ">" matlab-mode-syntax-table)
(set-syntax-table matlab-mode-syntax-table))
;; Abbrev Table
(defvar matlab-mode-abbrev-table nil
"Abbrev table used in Matlab-mode buffers.")
(define-abbrev-table 'matlab-mode-abbrev-table ())
;; Mode Map
(defvar matlab-mode-map ()
"Keymap used in matlab-mode.")
(if matlab-mode-map
()
(setq matlab-mode-map (make-sparse-keymap))
(define-key matlab-mode-map "\r" 'matlab-return)
(define-key matlab-mode-map "\t" 'matlab-indent-line)
(define-key matlab-mode-map "\M-;" 'matlab-comment)
(define-key matlab-mode-map "\C-ct" 'matlab-line-type)
(define-key matlab-mode-map "\C-ci" 'matlab-indent-type)
(define-key matlab-mode-map "\M-\r" 'newline))
;; Matlab Mode
(defun matlab-mode ()
"Major mode for editing Pro-Matlab dot-m files. Version 1.01 dated 25Jan91.
Will run matlab-mode-hook if it is non-nil. Auto-fill-mode seems to work.
Filling does not work (yet).
Special Key Bindings:
\\{matlab-mode-map}
Variables:
matlab-indent-level Level to indent blocks.
matlab-comment-column Goal column for on-line comments.
fill-column Column used in auto-fill (default=70).
Commands:
matlab-mode Enter Matlab major mode.
matlab-return Handle return with indenting.
matlab-indent-line Indent line for structure.
matlab-comment Add comment to current line.
matlab-comment-indent Compute indent for comment.
matlab-line-type Tell current line type (for debugging).
matlab-indent-type Tell last indent type (for debugging).
To add automatic support put something like the following in your .emacs file:
\(autoload 'matlab-mode \"matlab-mode\" \"Enter Matlab-mode.\" t\)
\(setq auto-mode-alist \(cons '\(\"\\\\.m$\" . matlab-mode\) \
auto-mode-alist\)\)
\(setq matlab-mode-hook '\(lambda \(\) \(setq fill-column 74\)\)\)"
(interactive)
(kill-all-local-variables)
(use-local-map matlab-mode-map)
(setq major-mode 'matlab-mode)
(setq mode-name "Matlab")
(setq local-abbrev-table matlab-mode-abbrev-table)
(set-syntax-table matlab-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 'matlab-indent-line)
(make-local-variable 'comment-start-skip)
(setq comment-start-skip "%[ \t]*")
(make-local-variable 'comment-column)
(setq comment-column 'matlab-comment-column)
(make-local-variable 'comment-indent-hook)
(setq comment-indent-hook 'matlab-comment-indent)
(make-local-variable 'fill-column)
(setq fill-column default-fill-column)
(run-hooks 'matlab-mode-hook))
(defun matlab-return ()
"Handle carriage return in Matlab-mode."
(interactive)
;;(matlab-indent-line)
(newline)
(matlab-indent-line))
(defun matlab-comment ()
"Add a comment to the following line, or format if one already exists."
(interactive)
(cond
((ml-empty-line)
(matlab-indent-line)
(insert "% "))
((ml-comment-line))
(t
(end-of-line)
(re-search-backward "[^ \t^]" 0 t)
(forward-char)
(delete-horizontal-space)
(if (< (current-column) matlab-comment-column)
(indent-to matlab-comment-column)
(insert " "))
(insert "% "))))
(defun matlab-comment-indent ()
"Indent a comment line in Matlab-mode."
(ml-calc-indent))
(defun matlab-indent-line ()
"Indent a line in Matlab-mode."
(interactive)
(save-excursion
(beginning-of-line)
(delete-horizontal-space)
(indent-to (ml-calc-indent)))
(skip-chars-forward " \t"))
(defun matlab-line-type ()
"Display type of current line. Used in debugging."
(interactive)
(cond
((ml-empty-line)
(message "matlab-line-type: empty-line"))
((ml-comment-line)
(message "matlab-line-type: comment-line"))
((ml-continuation-line)
(message "matlab-line-type: continuation-line"))
((ml-block-beg-end-line)
(message "matlab-line-type: block-beg-end-line"))
((ml-block-beg-line)
(message "matlab-line-type: block-beg-line"))
((ml-block-end-line)
(message "matlab-line-type: block-end-line"))
(t
(message "matlab-line-type: other"))))
(defun matlab-indent-type ()
"Display type of current or previous nonempty line. Used in debugging."
(interactive)
(message (concat "matlab-ident-type: " ml-last-indent-type)))
(defun matlab-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 "matlab-fill-region not implemented yet."))
(defvar ml-last-indent-type "unknown"
"String to tell line type.")
(defun ml-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 (ml-empty-line) ; non-empty line
(re-search-backward "[^ \t\n]" 0 t))
(cond
((ml-empty-line)
(setq ml-last-indent-type "empty"))
((ml-comment-line)
(setq ml-last-indent-type "comment"))
((ml-continuation-line)
(setq ml-last-indent-type "continuation")
(setq indent (* 2 matlab-indent-level)))
((ml-block-beg-end-line)
(setq ml-last-indent-type "block begin-end"))
((ml-block-beg-line)
(setq ml-last-indent-type "block begin")
(setq indent matlab-indent-level))
((ml-unbal-matexp-line)
(setq ml-last-indent-type "unbalanced-matrix-expression")
(setq indent (ml-calc-matexp-indent)))
(t
(setq ml-last-indent-type "other")))
(setq indent (+ indent (current-indentation)))
(if (= 0 (forward-line -1))
(if (ml-continuation-line)
(setq indent (- indent (* 2 matlab-indent-level))))))
(if (ml-block-end-line) (setq indent (- indent matlab-indent-level)))
(if (< indent 0) (setq indent 0))
indent))
(defun ml-empty-line ()
"Returns t if current line is empty."
(save-excursion
(beginning-of-line)
(looking-at "^[ \t]*$")))
(defun ml-comment-line ()
"Returns t if current line is a Matlab comment line."
(save-excursion
(beginning-of-line)
(skip-chars-forward " \t")
(looking-at "%")))
(defun ml-continuation-line ()
"Returns t if current line ends in ... and optional comment."
(save-excursion
(beginning-of-line)
(re-search-forward "\\.\\.\\.+[ \t]*\\(%.*\\)?$" (ml-eoln-point) t)))
(defun ml-eoln-point ()
"Returns point for end-of-line in Matlab-mode."
(save-excursion
(end-of-line)
(point)))
(defun ml-block-beg-line ()
"Returns t if line contains beginning of Matlab block."
(save-excursion
(beginning-of-line)
(looking-at (concat "\\([^%\n]*[ \t]\\)?" ml-block-beg-kw))))
(defconst ml-block-beg-kw "\\(for\\|while\\|if\\|else\\|elseif\\)"
"Regular expression for keywords which begin blocks in Matlab-mode.")
(defun ml-block-end-line ()
"Returns t if line contains end of Matlab block."
(save-excursion
(beginning-of-line)
(looking-at (concat "\\([^%\n]*[ \t]\\)?" ml-block-end-kw))))
(defconst ml-block-end-kw "\\(end\\|else\\|elseif\\)"
"Regular expression for keywords which end blocks.")
(defun ml-block-beg-end-line ()
"Returns t if line contains matching block begin-end in Matlab-mode."
(save-excursion
(beginning-of-line)
(looking-at (concat
"\\([^%\n]*[ \t]\\)?" ml-block-beg-kw
"." "\\([^%\n]*[ \t]\\)?" ml-block-end-kw))))
(defun ml-unbal-matexp-line ()
(if (= (ml-calc-matexp-indent) 0)
()
t))
(defun ml-calc-matexp-indent ()
(let ((indent 0))
(save-excursion
(beginning-of-line)
(while (< (point) (ml-eoln-point))
(cond
((looking-at "\\[")
(setq indent (+ indent matlab-indent-level)))
((looking-at "\\]")
(setq indent (- indent matlab-indent-level))))
(forward-char)))
(* 2 indent)))
(defun ml-comment-on-line ()
"Returns t if current line contains a comment."
(save-excursion
(beginning-of-line)
(looking-at "[^\n]*%")))
(defun ml-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 'matlab-mode)
;; --- last line of matlab-mode.el ---
--
Tom Palka
Technical Details
Message-ID:
<TOMPALKA.91Mar21135828@w20-575-93.mit.edu>Path:
arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!athena.mit.edu!tompalkaReferences:
<AJT.91Mar21125536@bilbo.bhpmrl.oz.au>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103b8b,d1d7c9acd84cda9e X-Google-Attributes: gid103b8b,public X-Google-ArrivalTime: 1991-03-22 16:52:22 PST Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!snorkelwacker.mit.edu!bloom-picayune.mit.edu!athena.mit.edu!tompalka From: tompalka@athena.mit.edu (thomas m. palka) Newsgroups: gnu.emacs.help Subject: Re: matlab-mode anyone ? Message-ID: <TOMPALKA.91Mar21135828@w20-575-93.mit.edu> Date: 21 Mar 91 18:58:38 GMT References: <AJT.91Mar21125536@bilbo.bhpmrl.oz.au> Sender: news@athena.mit.edu (News system) Distribution: gnu Organization: Massachusetts Institute of Technology Lines: 355 In-Reply-To: ajt@bilbo.bhpmrl.oz.au's message of 21 Mar 91 02:55:36 GMT