🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.soft-sys.matlab
Article #189

announcement: matlab-mode.el, version 1.07.0

#189
From: Matt Wette
Date: Mon, 10 Jul 1995 00:00
780 lines
29059 bytes
Here's a new version of matlab-mode.el, an emacs major mode for
editing MATLAB dot-m files.  I've reworked the indenting to avoid
problems with percents and keywords appearing in strings.  I've also
submitted this to the MathWorks ftp archive.

Please report problems to me <mwette@mr-ed.jpl.nasa.gov>.  

Matt


;; matlab-mode.el - major mode for MATLAB dot-m files
;;
;; This major mode for GNU emacs provides support for editing MATLAB dot-m
;; files.  It automatically indents for block structures, line continuations
;; (e.g., ...), and comments.  The usual paren matching support is included.
;; Filling and auto-fill works for comment lines.  You may wish to 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))
;;   (defun my-matlab-mode-hook ()
;;     (setq fill-column 76)
;;     (setq matlab-indent-end-before-return t)
;;     (turn-on-auto-fill))
;;   (setq matlab-mode-hook 'my-matlab-mode-hook)
;; Put this file in the emacs load-path so emacs can find it.  Some "font-lock"
;; and "hilit19" support exists.  This version now assumes that you put
;; whitespace immediately after `%' in your comments.
;;
;; Warning -
;;	MATLAB has a syntax which is it quite difficult to parse properly in
;;	elisp.  Therefore, there are certain limitations in this version of
;;	matlab-mode.  I am working on making this work better.  I'm using 
;;	heuristics to determine if keywords are part of syntax or are imbedded
;;	in a string constant.
;;
;; Copyright (C) 1991-1995 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 carry a prominant notice stating who made the last
;;	modification and the date of such modification.
;;   3. No direct charge is made for this software or works derived from it.
;;	This software may be distributed with licensed software as long as
;;	no itemized charge is made for this specific code.
;;
;; Version 1.07.0, Dated 08Jul95
;;
;; 08Jul95 by Matt Wette <mwette@mr-ed.jpl.nasa.gov>
;;	This is a fairly major rewrite of the indenting functions to fix long-
;;	standing problems arising from keywords and percents in strings.  We
;;	may have to add more heuristics later but this may work better.
;;	Changed comment region string.  Released version 1.07.0.
;;
;; 10Oct94 by Matt Wette <mwette@csi.jpl.nasa.gov>
;;	changed auto-fill-mode to auto-fill-function; changed
;;	comment-indent- to comment-indent-function; fixed percents in strings
;;	being interpreted as comments, but a % for comment should not be
;;	followed by [disx%]
;;
;; 23Nov93 by Matt Wette <mwette@csi.jpl.nasa.gov>
;;	added Lucid emacs, GNU emacs font-lock and lhilit support; repaired
;;	mtlb-block-{beg,end}-kw (Thanks to Dave Mellinger <dkm1@cornell.edu>)
;;	removed string delim entry from matlab-mode-syntax-table (MATLAB lang
;;	sucks here -- why not use " for strings?).   Released vers 1.06.0
;;
;; 10Aug93 by Matt Wette <mwette@csi.jpl.nasa.gov>
;;	added matlab-indent-end-before-return; indent may be fixed now
;;	still not working for emacs 19
;;
;; 02Aug93 by Matt Wette <mwette@csi.jpl.nasa.gov>
;;	fixed error in mtlb-calc-indent;  bumped version to 1.05.1; added
;;	mtlb-prev-line;  bumped version to 1.05.3; added mtlb-calc-blok-indent
;;
;; 01Aug93 by Matt Wette <mwette@csi.jpl.nasa.gov>
;;	Fixed bug which treated form as block-begin keyword.  Reworked 
;;	mtlb-calc-indent -- seems to work better w/ redundant cont lines now.
;; 	Bumbed version to 1.05.
;;
;; 13Jun93 by Matt Wette <mwette@csi.jpl.nasa.gov>
;;	Changed `linea' to `lattr', `linet' to `ltype', fixed
;;	Bumped version number from 1.03bb to 1.04.
;;
;; 02May91 by Matt Wette, mwette@csi.jpl.nasa.gov
;;	Added matlab-auto-fill for auto-fill-hook so that this mode doesn't
;;	try to fill matlab code, just comments.
;;
;; 22Apr91 by Matt Wette, mwette@csi.jpl.nasa.gov
;;	Changed "mtlb-ltype-cont" to "mtlb-lattr-cont", "mtlb-ltype-comment-on-
;;	line" to "mtlb-lattr-comment" and "mtlb-ltype-unbal-mexp" to "mtlb-
;;	lattr-unbal-mext" to emphasize that these are line attributes and not
;;	line types.  Modified "matlab-line-type" to reflect the change ini
;;	logic.
;;
;; 18Apr91 by Matt Wette, mwette@csi.jpl.nasa.gov
;;      Modified matlab-comment-return so that when hit on a line with a
;;	comment at the end it will go to the comment column.  To get the
;;	comment indented with the code, just hit TAB.
;;
;; 17Apr91 by Matt Wette, mwette@csi.jpl.nasa.gov
;;	Received critique from gray@scr.slb.com.  Changed ml- to mtlb- due to 
;;	possible conflict with mlsupport.el routines.  Added matlab-comment
;;	-line-s and -on-line-s.  Fixed bug in matlab-comment (set-fill-prefix).
;;	matlab-comment-return now works if called on a non-comment line.
;;
;; 04Mar91 by Matt Wette, mwette@csi.jpl.nasa.gov
;;	Added const matlab-indent-before-return.  Released Version 1.02.
;;
;; 02Feb91 by Matt Wette, mwette@csi.jpl.nasa.gov
;;	Changed names of ml-*-line to ml-ltype-*.  Cleaned up a lot. Added
;;	ml-format-comment-line, fixed ml-format-region.  Changed added "-s"
;;	on end of matlab-comment-region string.  Justify needs to be cleaned
;;	up.
;;
;; Fri Feb  1 09:03:09 1991; gray@scr.slb.com
;;      Add function matlab-comment-region, which inserts the string
;;      contained in the variable matlab-comment-region at the start
;;      of every line in the region.  With an argument the region is
;;      uncommented.  [Straight copy from fortran.el]
;;
;; 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.
;;

;;(setq debug-on-error t)

;; Variables which the user can change
(defvar matlab-indent-level 2
  "*The indentation in matlab-mode.")

(defvar matlab-cont-level 4
  "*Continuation indent.")

(defvar matlab-comment-column 40
  "*The goal comment column in matlab-mode buffers.")

(defvar matlab-comment-line-s "% "
  "*String to start comment on line by itself.")

(defvar matlab-comment-on-line-s "% "
  "*String to start comment on line with code.")

(defvar matlab-comment-region-s "% $$$ "
  "*String inserted by \\[matlab-comment-region] at start of each line in \
region.")

(defvar matlab-indent-before-return nil
  "*If non-nil, do matlab-indent-line before return (as well as after \
return).")

(defvar matlab-indent-end-before-return nil
  "*If non-nil, do matlab-indent-line before return on end-line.")

(defvar matlab-show-vers t
  "*If non-nil, shows the version number on load.")

;; 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 ?% "." matlab-mode-syntax-table)
  (modify-syntax-entry ?\n "." 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 "\^j" 'matlab-linefeed)
  (define-key matlab-mode-map "\C-c\r" 'matlab-comment-return)
  (define-key matlab-mode-map "\t" 'matlab-indent-line)
  (define-key matlab-mode-map "\M-;" 'matlab-comment)
  (define-key matlab-mode-map "\C-c;" 'matlab-comment-region)
  (define-key matlab-mode-map "\C-cq" 'matlab-fill-region)
  (define-key matlab-mode-map "\C-cf" 'matlab-fill-comment-line)
  (define-key matlab-mode-map "\C-cj" 'matlab-justify-line)
  (define-key matlab-mode-map "\C-ct" 'matlab-show-line-info)
  (define-key matlab-mode-map "\C-ci" 'matlab-show-line-indent)
  (define-key matlab-mode-map "\C-cb" 'matlab-show-blok-indent)
  (define-key matlab-mode-map "\C-cm" 'matlab-show-mexp-indent)
  (define-key matlab-mode-map "\M-\r" 'newline))


;; matlab-mode
(defun matlab-mode ()
  "Major mode for editing MATLAB dot-m files.  Version 1.07.0 dated 08Jul95.
Will run matlab-mode-hook if it is non-nil.  Filling works (comments justify).

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.
  matlab-comment-line-s	        	String to start comment line.
  matlab-comment-region-s	        String to put comment lines in region.
  matlab-indent-before-return		If t, matlab-indent-line before RET.
  matlab-indent-end-before-return	If t, indent-line before RET on end.
  matlab-show-vers			If t, show version on start-up.

Commands:
  matlab-mode                           Enter MATLAB major mode.
  matlab-return                         RET with post indenting.
  matlab-linefeed                       RET with pre and post indent.
  matlab-comment-return			RET for next-line comment.
  matlab-indent-line                    Indent line for structure.
  matlab-comment                        Add comment to current line.
  matlab-comment-indent                 Compute indent for comment.
  matlab-comment-region			Comment (with arg, uncomment) region.
  matlab-fill-region			Fill region (usually comments).
  matlab-justify-line			Delete space on end and justify.

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\)\)
  \(defun my-matlab-mode-hook \(\)
    \(setq fill-column 76\)
    \(turn-on-auto-fill\)\)
  \(setq matlab-mode-hook 'my-matlab-mode-hook\)"
  (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 'auto-fill-function)
  (setq auto-fill-function 'matlab-auto-fill)
  (make-local-variable 'comment-indent-function)
  (setq comment-indent-function 'matlab-comment-indent)
  (make-local-variable 'fill-column)
  (setq fill-column default-fill-column)
  ;;(make-local-variable 'fill-prefix)
  ;;(setq fill-prefix matlab-comment-line-s)
  (if (not window-system) ()
    (make-local-variable 'font-lock-keywords)
    (setq font-lock-keywords matlab-font-lock-keywords)
    (if (featurep 'hilit19) (matlab-hilit19-hook)))
  (run-hooks 'matlab-mode-hook)
  (if matlab-show-vers
      (message "matlab-mode, Version 1.07.0 Dated 08Jul95")))



;;; utilities =================================================================

(defconst matlab-cline-start-skip "[ \t]*%[ \t]*"
  "*The regular expression for skipping comment start.")

(defun matlab-prev-line ()
  "Find the previous line of code.  Return nil if not found."
  (interactive)
  (if (= -1 (forward-line -1)) nil
    (cond
     ((matlab-ltype-code) t)
     ((matlab-ltype-comment) (matlab-prev-line))
     ((matlab-ltype-empty) (matlab-prev-line)))))

(defun matlab-return ()
  "Handle carriage return in matlab-mode."
  (interactive)
  (if matlab-indent-before-return
      (matlab-indent-line)
    (if matlab-indent-end-before-return
	(if (save-excursion
	      (beginning-of-line)
	      (looking-at "\\s-*end"))
	    (matlab-indent-line))))
  (newline)
  (matlab-indent-line))

(defun matlab-linefeed ()
  "Handle linefeed in matlab-mode.
Has effect of matlab-return with (not matlab-indent-before-return)."
  (interactive)
  (if (not matlab-indent-before-return) (matlab-indent-line))
  (newline)
  (matlab-indent-line))

(defun matlab-comment-return ()
  "Handle carriage return for matlab comment line."
  (interactive)
  (cond
   ((matlab-ltype-comment)
    (matlab-set-comment-fill-prefix) (newline) (insert matlab-fill-prefix)
    (matlab-indent-line))
   ((matlab-lattr-comment)
    (newline) (indent-to matlab-comment-column)
    (insert matlab-comment-on-line-s))
   (t
    (newline) (matlab-comment) (matlab-indent-line))))

(defun matlab-comment ()
  "Add a comment to the current line.  If one already exists, format it."
  (interactive)
  (cond
   ((matlab-ltype-empty)
    (matlab-indent-line)
    (insert matlab-comment-line-s))
   ((matlab-ltype-comment)
    (save-excursion
      (if (and (= 0 (forward-line -1)) (matlab-ltype-comment))
	  (progn 
	    (matlab-set-comment-fill-prefix)
	    (forward-line 1)
	    (beginning-of-line)
	    (delete-horizontal-space) (delete-char 1) (delete-horizontal-space)
	    (insert matlab-fill-prefix)))))
   ((matlab-lattr-comment)
    (beginning-of-line)
    (re-search-forward "[^%]% ")
    (forward-char -1)
    (delete-horizontal-space)
    (insert " ")
    (if (< (current-column) matlab-comment-column)
	  (indent-to matlab-comment-column))
    (skip-chars-forward "% "))
   (t
    (end-of-line)
    (re-search-backward "[^ \t\n^]" 0 t)
    (forward-char)
    (delete-horizontal-space)
    (if (< (current-column) matlab-comment-column)
        (indent-to matlab-comment-column)
      (insert " "))
    (insert matlab-comment-on-line-s))))


(defun matlab-comment-indent ()
  "Indent a comment line in matlab-mode."
  (matlab-calc-indent))

(defun matlab-comment-region (beg-region end-region arg)
  "Comments every line in the region.
Puts matlab-comment-region-s at the beginning of every line in the region. 
BEG-REGION and END-REGION are args which specify the region boundaries. 
With non-nil ARG, uncomments the region."
  (interactive "*r\nP")
  (let ((end-region-mark (make-marker)) (save-point (point-marker)))
    (set-marker end-region-mark end-region)
    (goto-char beg-region)
    (beginning-of-line)
    (if (not arg)			;comment the region
	(progn (insert matlab-comment-region-s)
	       (while (and  (= (forward-line 1) 0)
			    (< (point) end-region-mark))
		 (insert matlab-comment-region-s)))
      (let ((com (regexp-quote matlab-comment-region-s))) ;uncomment the region
	(if (looking-at com)
	    (delete-region (point) (match-end 0)))
	(while (and  (= (forward-line 1) 0)
		     (< (point) end-region-mark))
	  (if (looking-at com)
	      (delete-region (point) (match-end 0))))))
    (goto-char save-point)
    (set-marker end-region-mark nil)
    (set-marker save-point nil)))


;;; filling ===================================================================

(defvar matlab-fill-prefix "")

(defun matlab-wrap-line ()
  "Wrap line so last token on line does not exceed fill-column."
  (interactive)
  (save-excursion
    (end-of-line)
    (delete-horizontal-space)
    (if (< (current-column) fill-column)
	()
      (while (> (current-column) fill-column) (forward-char -1))
      (while (not (looking-at "[ \t]")) (forward-char -1))
      (delete-horizontal-space)
      (insert "\n")
      t)))

(defun matlab-join-comment-lines ()
  "Join current comment line to previous, deleting space and comment mark."
  (interactive)
  (beginning-of-line)
  (forward-char -1) (delete-char 1)	; delete newline
  (delete-horizontal-space)
  (delete-char 1)			; delete "%"
  (delete-horizontal-space)
  (insert " "))

(defun matlab-auto-fill ()
  "Do filling."
  (interactive)
  (cond
   ((matlab-ltype-comment) (symbol-function 'do-auto-fill))
   ((matlab-lattr-comment) (symbol-function 'do-auto-fill))
   (t ())))

(defun matlab-fill-region (beg-region end-region &optional justify-flag)
  "Fill the region. Non-nil arg means justify commment lines as well."
  (interactive "*r\nP")
  (let ((end-reg-mk (make-marker)))
    (set-marker end-reg-mk end-region)
    (goto-char beg-region)
    (beginning-of-line)
    (while (< (save-excursion (forward-line 1) (point)) end-reg-mk)
      (if (save-excursion (= (forward-line 1) 0))
	  (progn 
	    (cond
	     ((matlab-ltype-comment)
	      (while (matlab-fill-comment-line))
	      (if justify-flag (justify-comment-line))))
	    (forward-line 1))))))

(defun matlab-fill-comment-line ()
  "Fill the current comment line."
  (interactive)
  (let ((prev-indent-col 0))
    (beginning-of-line)
    (re-search-forward matlab-cline-start-skip)
    (setq prev-indent-col (current-column))
    (matlab-set-comment-fill-prefix)
    (if (/= (forward-line 1) 0)
	()
      (beginning-of-line)
      (re-search-forward matlab-cline-start-skip)
      (if (/= prev-indent-col (current-column))
	  (progn (forward-line -1) ())
	(matlab-join-comment-lines)
	(if (matlab-wrap-line)
	    (save-excursion
	      (forward-line 1)
	      (beginning-of-line)
	      (insert "% ")
	      t))))))

(defun matlab-set-comment-fill-prefix ()
  "Set the fill-prefix for the current comment line."
  (setq matlab-fill-prefix
	(save-excursion
	  (beginning-of-line) 
	  (buffer-substring
	   (point)
	   (progn (re-search-forward matlab-cline-start-skip) (point))))))

(defun matlab-justify-line ()
  "Delete space on end of line and justify."
  (interactive)
  (save-excursion
    (end-of-line)
    (delete-horizontal-space)
    (justify-current-line)))


;;; regexps for MATLAB language ===============================================

(defconst matlab-block-beg-pre 
  "for\\|while\\|if"
  "partial regular express to recognize block beginnings in matlab-mode.")

(defconst matlab-block-mid-pre 
  "elseif\\|else"
  "partial regular express to recognize block midpoints in matlab-mode.")

(defconst matlab-block-end-pre
  "end"
  "partial regular express to recognize block endings in matlab-mode.")
  
(defconst matlab-block-re
  (concat "\\(^\\|[;,]\\)\\s-*\\("
	  matlab-block-beg-pre "\\|"
	  matlab-block-mid-pre "\\|"
	  matlab-block-end-pre "\\)\\b")
  "Regular expression for keywords which begin blocks in matlab-mode.")

(defconst matlab-block-beg-re
  (concat "\\(" matlab-block-beg-pre "\\)"))

(defconst matlab-block-mid-re
  (concat "\\(" matlab-block-mid-pre "\\)"))

(defconst matlab-block-end-re
  (concat "\\(" matlab-block-end-pre "\\)"))

(defvar matlab-font-lock-keywords
  (list
   '("\\(^\\|[;,]\\)\\s-*\\(for\\|while\\|if\\|else\\|elseif\\|end\\)\\b"
     2 font-lock-keyword-face t)
   '("%\\s-+.*" 0 font-lock-comment-face t))
  "Expressions to hightlight in Matlab mode.")
 
(defun matlab-hilit19-hook ()
  (if (featurep 'hilit19)
      (hilit-set-mode-patterns
       'matlab-mode
       '(("%\\s-.*$" nil comment)
	 ("\\(for\\|while\\|if\\|else\\|elseif\\|end\\)\\b" nil keyword)))))


;;; line types ================================================================

(defun matlab-ltype-empty ()		; blank line
  "Returns t if current line is empty."
  (save-excursion
    (beginning-of-line)
    (looking-at "^[ \t]*$")))

(defun matlab-ltype-comment ()		; comment line
  "Returns t if current line is a MATLAB comment line."
  (save-excursion
    (beginning-of-line)
    (looking-at "[ \t]*%")))

(defun matlab-ltype-code ()		; line of code
  "Return t if current line is a MATLAB code line."
  (and (not (matlab-ltype-empty)) (not (matlab-ltype-comment))))


;;; line attributes ===========================================================

(defconst matlab-comment-regexp "[^%]% ")

(defun matlab-lattr-comment ()		; line has comment
  "Returns t if current line contains a comment."
  (save-excursion
    (beginning-of-line)
    (looking-at ".*[^%]% ")))

(defun matlab-lattr-cont ()		; line has continuation
  "Returns t if current line ends in .. and optional comment."
  (save-excursion
    (beginning-of-line)
    (re-search-forward
     "[^; \t.][ \t]*\\.\\.\\.+[ \t]*\\(%.*\\)?$"
     (save-excursion (end-of-line) (point))
     t)))

(defun matlab-lattr-unbal-mexp ()
  (/= (matlab-calc-mexp-indent) 0))


;;; indent functions ==========================================================

(defun matlab-indent-line ()
  "Indent a line in matlab-mode."
  (interactive)
  (save-excursion
    (beginning-of-line)
    (delete-horizontal-space)
    (indent-to (matlab-calc-indent))
    ;; -- If line contains a comment, format it. --
    (if (or (matlab-ltype-comment) (matlab-lattr-comment))
	(matlab-comment)))
  (skip-chars-forward " \t%"))

(defun matlab-calc-indent ()
  "Return the appropriate indentation for this line as an int."
  (let ((indent 0))
    (save-excursion
      (if (matlab-prev-line)
	  (setq indent (+ (current-indentation) (matlab-add-to-next)))))
    (setq indent (+ indent (matlab-add-from-prev)))
    indent))

(defun matlab-add-to-next ()
  (car (cdr (matlab-calc-deltas))))

(defun matlab-add-from-prev ()
  (car (matlab-calc-deltas)))

(defun matlab-calc-deltas ()
  "returns a list of (add-from-prev add-to-next)."
  (let ((add-from-prev 0) (add-to-next 0) eol)
    (save-excursion
      (setq eol (position-at-eol))
      ;; indentation for control structures
      (beginning-of-line)
      (while (re-search-forward matlab-block-re eol t)
	(save-excursion
	  (goto-char (match-beginning 2))
	  (if (looking-at matlab-block-beg-re)
	      (setq add-to-next (+ add-to-next matlab-indent-level))
	    (if (> add-to-next 0)
		(setq add-to-next (- add-to-next matlab-indent-level))
	      (setq add-from-prev (- add-from-prev matlab-indent-level)))
	    (if (looking-at matlab-block-mid-re)
		(setq add-to-next (+ add-to-next matlab-indent-level))))))
      ;; indentation for matrix expressions
      (beginning-of-line)
      (while (re-search-forward "[][]" eol t)
	(save-excursion
	  (goto-char (match-beginning 0))
	  (if (looking-at "\\[")
	      (setq add-to-next (+ add-to-next matlab-indent-level))
	    (setq add-to-next (- add-to-next matlab-indent-level)))))
      ;; continuation lines
      (if (matlab-lattr-cont)
	  (save-excursion
	    (if (= 0 (forward-line -1))
		(if (matlab-lattr-cont)
		    ()
		  (setq add-to-next (+ add-to-next matlab-indent-level)))))
	(save-excursion
	  (if (= 0 (forward-line -1))
	      (if (matlab-lattr-cont)
		  (setq add-to-next (- add-to-next matlab-indent-level))))))
      )
    (list add-from-prev add-to-next)))


;;; matlab debugging ==========================================================

; TBD


;;; matlab-mode debugging =====================================================

(defun matlab-show-line-info ()
  "Display type and attributes of current line.  Used in debugging."
  (interactive)
  (let ((msg "line-info:") (deltas (matlab-calc-deltas)))
    (cond
     ((matlab-ltype-empty)
      (setq msg (concat msg " empty")))
     ((matlab-ltype-comment)
      (setq msg (concat msg " comment")))
     (t
      (setq msg (concat msg " code"))))
    (setq msg (concat msg " add-from-prev="
		      (int-to-string (car deltas))))
    (setq msg (concat msg " add-to-next="
		      (int-to-string (car (cdr deltas)))))
    (setq msg (concat msg " indent="
		      (int-to-string (matlab-calc-indent))))
    (if (matlab-lattr-cont)
	(setq msg (concat msg " w/cont")))
    (if (matlab-lattr-comment)
	(setq msg (concat msg " w/comm")))
    (message msg)))

(defun matlab-show-line-indent ()
  "Display indentation for line.  Used in debugging."
  (interactive)
  (let ((msg "matlab-show-line-indent: "))
    (setq msg (concat msg (matlab-calc-indent)))
    (message msg)))

(defun matlab-show-blok-indent ()
  "Display indentation for matrix expression.  Used in debugging."
  (interactive)
  (let ((msg "matlab-show-blok-indent: "))
    (setq msg (concat msg (matlab-calc-blok-indent)))
    (message msg)))

(defun matlab-show-mexp-indent ()
  "Display indentation for matrix expression.  Used in debugging."
  (interactive)
  (let ((msg "matlab-show-mexp-indent: "))
    (setq msg (concat msg (matlab-calc-mexp-indent)))
    (message msg)))


;;; stuff which belongs elsewhere =============================================

(defun position-at-eol ()		; return point for end-of-line
  (interactive)
  (save-excursion
    (end-of-line)
    (point)))

(defun justify-comment-line ()
  "Add spaces to comment line point is in, so it ends at fill-column."
  (interactive)
  (save-excursion
   (save-restriction
    (let (ncols beg)
      (beginning-of-line)
      (forward-char (length matlab-fill-prefix))
      (skip-chars-forward " \t")
      (setq beg (point))
      (end-of-line)
      (narrow-to-region beg (point))
      (goto-char beg)
      (while (re-search-forward "   *" nil t)
	(delete-region
	 (+ (match-beginning 0)
	    (if (save-excursion
		 (skip-chars-backward " ])\"'")
		 (memq (preceding-char) '(?. ?? ?!)))
		2 1))
	 (match-end 0)))
      (goto-char beg)
      (while (re-search-forward "[.?!][])""']*\n" nil t)
	(forward-char -1)
	(insert " "))
      (goto-char (point-max))
      (setq ncols (- fill-column (current-column)))
      (if (search-backward " " nil t)
	  (while (> ncols 0)
	    (let ((nmove (+ 3 (% (random) 3))))
	      (while (> nmove 0)
		(or (search-backward " " nil t)
		    (progn
		     (goto-char (point-max))
		     (search-backward " ")))
		(skip-chars-backward " ")
		(setq nmove (1- nmove))))
	    (insert " ")
	    (skip-chars-backward " ")
	    (setq ncols (1- ncols))))))))


;;; junk? =====================================================================

(if (string-match "Lucid$" emacs-version)
    (progn
      (defvar font-lock-comment-face 'font-lock-comment-face)
      (defvar font-lock-doc-string-face 'font-lock-doc-string-face)
      (defvar font-lock-string-face 'font-lock-string-face)
      (defvar font-lock-function-name-face 'font-lock-function-name-face)
      (defvar font-lock-keyword-face 'font-lock-keyword-face)
      (defvar font-lock-type-face 'font-lock-type-face)))


(provide 'matlab-mode)
;; --- last line of matlab-mode.el --- 
--
matthew.r.wette@jpl.nasa.gov
Technical Details
Message-ID: <MWETTE.95Jul10113421@mr-ed.jpl.nasa.gov>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 106e3f,3c5bc02191773f8a,start
X-Google-Attributes: gid106e3f,public
X-Google-Thread: 102b9a,3c5bc02191773f8a,start
X-Google-Attributes: gid102b9a,public
X-Google-Thread: 107729,3c5bc02191773f8a,start
X-Google-Attributes: gid107729,public
From: mwette@mr-ed.jpl.nasa.gov (Matt Wette)
Subject: announcement: matlab-mode.el, version 1.07.0
Date: 1995/07/10
Message-ID: <MWETTE.95Jul10113421@mr-ed.jpl.nasa.gov>
X-Deja-AN: 106001292
distribution: world
content-type: text/plain; charset=US-ASCII
organization: Jet Propulsion Laboratory
mime-version: 1.0
newsgroups: comp.soft-sys.matlab,comp.emacs,gnu.emacs.sources