home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
octave-1.1.1p1-src.tgz
/
tar.out
/
fsf
/
octave
/
octave-mode.el
< prev
next >
Wrap
Lisp/Scheme
|
1996-09-28
|
18KB
|
562 lines
;; octave-mode.el - major mode for Octave function files
;;
;; Copyright (C) 1994 John W. Eaton
;;
;; This file is part of Octave.
;;
;; Octave is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by the
;; Free Software Foundation; either version 2, or (at your option) any
;; later version.
;;
;; Octave is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
;; for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Octave; see the file COPYING. If not, write to the Free
;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
;;
;; This major mode for GNU emacs provides support for editing Octave
;; function files. It requires matlab-mode.el, which was written by
;; Matthew R. Wette <mwette@csi.jpl.nasa.gov>.
;;
;; It automatically indents block structures, line continuations
;; (e.g., ...), and comments. The usual paren matching support is
;; included. Filling and auto-fill works for comment lines. For
;; convenient use, put this file and matlab.el in your Emacs
;; load-path and 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))
;; (defun my-octave-mode-hook ()
;; (setq fill-column 76)
;; (turn-on-auto-fill))
;; (setq octave-mode-hook 'my-octave-mode-hook)
;;
;; For Lucid Emacs, add ``(font-lock-mode 1)'' to your octave-bmode-hook.
;; Customize Matlab mode for Octave users.
(setq matlab-comment-column 0)
(setq matlab-comment-line-s "# ")
(setq matlab-comment-on-line-s "# ")
(setq matlab-comment-region-s "#$$$ ")
(defconst matlab-show-vers t
"*If non-nil, shows the version number on load.")
;; octave-mode
(defun matlab-mode ()
"Major mode for editing Octave function files. Version 1.0.
Will run octave-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-hook)
(setq auto-fill-hook 'matlab-auto-fill)
(make-local-variable 'comment-indent-hook)
(setq comment-indent-hook '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)
;;(setq font-lock-keywords matlab-font-lock-keywords) ;; Lucid emacs
;;(setq (make-local-variable 'font-lock-keywords) matlab-font-lock-keywords)
(run-hooks 'matlab-mode-hook)
(if matlab-show-vers
(message "matlab-mode, Version 1.06.0 Dated 23Nov93")))
(defconst mtlb-cline-start-skip "[ \t]*%[ \t]*"
"*The regular expression for skipping comment start.")
;;
(defun matlab-auto-fill ()
"Do filling."
(interactive)
(cond
((mtlb-ltype-comment) do-auto-fill)
((mtlb-lattr-comment) do-auto-fill)
(t ())))
(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 (mtlb-ltype-block-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
((mtlb-ltype-comment)
(mtlb-set-comment-fill-prefix) (newline) (insert fill-prefix)
(matlab-indent-line))
((mtlb-lattr-comment)
(newline) (indent-to matlab-comment-column)
(insert matlab-comment-on-line-s))
(t
(newline) (matlab-comment) (matlab-indent-line))))
(defun matlab-indent-line ()
"Indent a line in matlab-mode."
(interactive)
(save-excursion
(beginning-of-line)
(delete-horizontal-space)
(indent-to (mtlb-calc-indent))
;; -- If line contains a comment, format it. --
(if (or (mtlb-ltype-comment) (mtlb-lattr-comment))
(matlab-comment)))
(skip-chars-forward " \t%"))
(defun matlab-comment ()
"Add a comment to the current line. If one already exists, format it."
(interactive)
(cond
((mtlb-ltype-empty)
(matlab-indent-line)
(insert matlab-comment-line-s))
((mtlb-ltype-comment)
(save-excursion
(if (and (= 0 (forward-line -1)) (mtlb-ltype-comment))
(progn
(mtlb-set-comment-fill-prefix)
(forward-line 1)
(beginning-of-line)
(delete-horizontal-space) (delete-char 1) (delete-horizontal-space)
(insert fill-prefix)))))
((mtlb-lattr-comment)
(beginning-of-line)
(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."
(mtlb-calc-indent))
(defun mtlb-calc-indent ()
"Return the appropriate indentation for this line as an int."
(let ((indent 0))
(save-excursion
(if (not (mtlb-prev-line))
0
(setq indent (current-indentation))
(setq indent
(+ indent
(cond
((mtlb-ltype-comment) (mtlb-set-comment-fill-prefix) 0)
((mtlb-ltype-block-beg) matlab-indent-level)
((mtlb-ltype-block-end) 0)
(t (mtlb-calc-blok-indent)))))
(if (mtlb-lattr-unbal-mexp)
(setq indent (+ indent (mtlb-calc-mexp-indent))))
(if (mtlb-lattr-cont)
(setq indent (+ indent (* 2 matlab-indent-level)))))
(if (mtlb-prev-line)
(if (mtlb-lattr-cont)
(setq indent (- indent (* 2 matlab-indent-level))))))
(if (mtlb-ltype-block-end)
(setq indent (- indent matlab-indent-level)))
(if (< indent 0) (setq indent 0))
indent))
(defun mtlb-prev-line ()
"Find the previous line. Return 0 if not found."
(interactive)
(if (/= 0 (forward-line -1))
()
(if (mtlb-ltype-empty)
(mtlb-prev-line)
t)))
(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)))
(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
((mtlb-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 mtlb-cline-start-skip)
(setq prev-indent-col (current-column))
(mtlb-set-comment-fill-prefix)
(if (/= (forward-line 1) 0)
()
(beginning-of-line)
(re-search-forward mtlb-cline-start-skip)
(if (/= prev-indent-col (current-column))
(progn (forward-line -1) ())
(mtlb-join-comment-lines)
(if (mtlb-wrap-line)
(save-excursion
(forward-line 1)
(beginning-of-line)
(insert fill-prefix)
t))))))
(defun mtlb-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 mtlb-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 mtlb-set-comment-fill-prefix ()
"Set the fill-prefix for the current comment line."
(setq fill-prefix
(save-excursion
(beginning-of-line)
(buffer-substring
(point)
(progn (re-search-forward mtlb-cline-start-skip) (point)))))
(if (equal fill-prefix "")
(setq fill-prefix nil)))
(defun matlab-justify-line ()
"Delete space on end of line and justify."
(interactive)
(save-excursion
(end-of-line)
(delete-horizontal-space)
(justify-current-line)))
;;;
;;; line attributes ...
(defun mtlb-lattr-comment ()
"Returns t if current line contains a comment."
(save-excursion
(beginning-of-line)
(looking-at ".*%")))
(defun mtlb-lattr-cont ()
"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 mtlb-lattr-unbal-mexp ()
(/= (mtlb-calc-mexp-indent) 0))
;;;
;;; line types ...
(defun mtlb-ltype-empty ()
"Returns t if current line is empty."
(save-excursion
(beginning-of-line)
(looking-at "^[ \t]*$")))
(defun mtlb-ltype-comment ()
"Returns t if current line is a MATLAB comment line."
(save-excursion
(beginning-of-line)
(looking-at "[ \t]*%")))
(defun mtlb-ltype-block-beg ()
"Returns t if line contains beginning of MATLAB block."
(save-excursion
(beginning-of-line)
(and
(looking-at (concat "[^%\n]*" mtlb-block-beg-kw))
(not (mtlb-ltype-blk-beg-end)))))
(defun mtlb-ltype-block-end ()
"Returns t if line contains end of MATLAB block."
(save-excursion
(beginning-of-line)
(and
(looking-at (concat "\\([^%\n]*[ \t]\\)?" mtlb-block-end-kw))
(not (mtlb-ltype-blk-beg-end)))))
(defun mtlb-ltype-blk-beg-end ()
"Returns t if line contains matching block begin-end in matlab-mode."
(save-excursion
(beginning-of-line)
(looking-at (concat "[^%\n]*" mtlb-block-beg-kw
"[^%\n]+" mtlb-block-end-kw))))
;;;
;;; utility functions ...
(defconst mtlb-block-beg-kw "\\b\\(for\\|while\\|if\\|else\\|elseif\\)\\b"
"Regular expression for keywords which begin blocks in matlab-mode.")
(defconst mtlb-block-end-kw "\\b\\(end\\|else\\|elseif\\)\\b"
"Regular expression for keywords which end blocks.")
(defun mtlb-calc-blok-indent ()
(let ((indent 0))
(save-excursion
(beginning-of-line)
(while (< (point) (save-excursion (end-of-line) (point)))
(cond
((looking-at mtlb-block-beg-kw)
(setq indent (+ indent matlab-indent-level)))
((looking-at mtlb-block-end-kw)
(setq indent (- indent matlab-indent-level))))
(forward-char)))
indent))
(defun mtlb-calc-mexp-indent ()
(let ((indent 0))
(save-excursion
(beginning-of-line)
(while (< (point) (save-excursion (end-of-line) (point)))
(cond
((looking-at "\\[")
(setq indent (+ indent matlab-indent-level)))
((looking-at "\\]")
(setq indent (- indent matlab-indent-level))))
(forward-char)))
(* 2 indent)))
;;;
;;; -- debugging --
(defun matlab-show-line-attr ()
"Display type and attributes of current line. Used in debugging."
(interactive)
(let ((msg "matlab-show-line-attr:"))
(cond
((mtlb-ltype-empty)
(setq msg (concat msg " empty")))
((mtlb-ltype-comment)
(setq msg (concat msg " comment")))
((mtlb-ltype-block-beg)
(setq msg (concat msg " block-begin")))
((mtlb-ltype-block-end)
(setq msg (concat msg " block-end")))
(t
(setq msg (concat msg " other"))))
(if (mtlb-lattr-cont)
(setq msg (concat msg " w/cont")))
(if (mtlb-lattr-comment)
(setq msg (concat msg " w/comm")))
(if (mtlb-lattr-unbal-mexp)
(setq msg (concat msg " w/unbal-mexp")))
(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 (mtlb-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 (mtlb-calc-mexp-indent)))
(message msg)))
;;; --- version 19 stuff ...
(defvar matlab-font-lock-keywords
(list
'("\\b\\(break\\|else\\|elseif\\|end\\|for\\|if\\|return\\|while\\)\\b"
. font-lock-keyword-face)
'("\\bfunction[^=]+=[^)]+)" . font-lock-function-name-face)
)
"Expressions to hightlight in Matlab mode.")
(if (featurep 'lhilit)
(hilit-set-mode-patterns
'matlab-mode
'(("%.*$" nil comment)
;;("'.*'" nil string)
("\\bfunction[^=]+=[^)]+)" nil defun)
;; key words
("\\<\\(load\\|save\\|clear\\)\\>" nil include)
("\\<\\(break\\|else\\|elseif\\|end\\|for\\|if\\|return\\)\\>"
nil keyword)
)))
;;; -- stuff which belongs elsewhere --
(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 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))))))))
(provide 'matlab-mode)
;; --- last line of matlab-mode.el ---