;;; matlab.el --- major mode for MATLAB dot-m files ;; ;; Author: Matt Wette <mwette@alumni.caltech.edu> ;; Maintainer: Matt Wette <mwette@alumni.caltech.edu> ;; Created: 04 Jan 91 ;; Version: 1.08.0 ;; Keywords: matlab, octave ;; ;; LCD Archive Entry: ;; matlab|Matt Wette|mwette@alumni.caltech.edu| ;; Major mode for MATLAB dot-m files| ;; 01-Aug-96|1.08.0|~/modes/matlab.el.Z| ;; ;; Copyright (C) 1991-1996 Matthew R. Wette ;; ;; This file is part of GNU Emacs. ;; ;; GNU Emacs 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. ;; ;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ;; ;;; Commentary: ;; ;; 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 file: ;; (autoload 'matlab-mode "matlab" "Enter Matlab mode." t) ;; (setq auto-mode-alist (cons '("\\.m$" . matlab-mode) auto-mode-alist)) ;; (defun my-matlab-mode-hook () ;; (setq matlab-function-indent t) ; if you want function bodies indented ;; (setq fill-column 76) ; where auto-fill should wrap ;; (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 (check the manual). ;; To get font-lock try adding ;; (font-lock-mode 1) ;; To get hilit19 support try adding ;; (matlab-mode-hilit) ;; ;; This version now assumes that you put whitespace immediately after `%' in ;; your comments. The fact that MATLAB uses single-quote for strings and ;; tranpose makes parsing strings almost impossible. I have implemented some ;; heuristics to make matlab-mode work with strings better, but ya never know. ;; ;; Indent places the beginning of the entire comment. If placing a new ;; comment on the line use fill-prefix from previous line. If comment ;; already exists keep its existing justification. ;; ;;; Code: ;;(setq debug-on-error t) ;;; user-changable variables ================================================== ;; 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-fill-code t "*If true, auto-fill-mode causes code lines to be automatically continued.") (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-function nil "*If t, indent body of function.") (defvar matlab-vers-on-startup t "*If non-nil, shows the version number on startup.") ;;; matlab-mode variables ===================================================== ;; syntax table (defvar matlab-mode-syntax-table nil "the syntax table used in matlab-mode buffers") (if matlab-mode-syntax-table () (setq matlab-mode-syntax-table (make-syntax-table (standard-syntax-table))) (modify-syntax-entry ?_ "_" matlab-mode-syntax-table) (modify-syntax-entry ?% ".1" matlab-mode-syntax-table) (modify-syntax-entry ?\ " 2" matlab-mode-syntax-table) (modify-syntax-entry ?\t " 2" 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 "the abbrev table used in matlab-mode buffers") (define-abbrev-table 'matlab-mode-abbrev-table ()) ;; mode map (defvar matlab-mode-map () "the 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 "\M-\r" 'newline) (substitute-key-definition 'comment-region 'matlab-comment-region matlab-mode-map global-map) ;torkel ) ;; font-lock keywords (defvar matlab-font-lock-keywords (list '("\\(^\\|[^%]\\)\\(%[ \t].*\\|%\\)$" 2 font-lock-comment-face t) '("\\(^\\|[;,]\\)[ \t]*\\(\ function\\|global\\|for\\|while\\|if\\|elseif\\|else\\|end\\|return\ \\)\\b" 2 font-lock-keyword-face) '("^function[ \t]+\\(.*=[ \t]*\\)?\\([a-zA-Z0-9_]+\\)\\b" 2 font-lock-function-name-face t)) ;; Strings, from Andrew Fitzgibbon <awf@robots.oxford.ac.uk> ;;'("[^]a-zA-Z0-9_)]\\('\\([^']\\|''\\)*'\\)" 1 font-lock-string-face t) "Expressions to hightlight in Matlab mode.") ;; hilit19 patterns (defvar matlab-hilit19-patterns '(("\\(^\\|[^%]\\)\\(%[ \t].*\\|%\\)$" 2 comment) ("\\(^\\|[;,]\\)[ \t]*\\(\ function\\|global\\|for\\|while\\|if\\|elseif\\|else\\|end\\|return\ \\)\\b" 2 keyword))) ;;; matlab-mode entry point ================================================== (defun matlab-mode () "Matlab-mode is a major mode for editing MATLAB dot-m files. This is version 1.08.0, dated 01Aug96. This version + will run matlab-mode-hook if it is non-nil + supports font-lock and hilit19 + requires a whitespace (space, tab or newline) after % in comment 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 Sring to start comment line. matlab-comment-region-s String to put comment lines in region. matlab-vers-on-startup If t, show version on start-up. matlab-indent-function If t, indents body of MATLAB functions. matlab-hilit19-patterns Patterns for hilit19 matlab-font-lock-keywords Keywords for font-lock matlab-return-function Function-variable to customize RET handling 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. matlab-mode-hilit Turn on hilit19. 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\) \(font-lock-mode 1\) \(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 'indent-line-function) (setq indent-line-function 'matlab-indent-line) (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 'comment-start-skip) (setq comment-start-skip "%\\s-+") (make-local-variable 'comment-column) (setq comment-column 'matlab-comment-column) (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 'auto-fill-function) (setq auto-fill-function 'matlab-auto-fill) (make-local-variable 'fill-prefix) (make-local-variable 'font-lock-keywords) (setq font-lock-keywords matlab-font-lock-keywords) (run-hooks 'matlab-mode-hook) (make-local-variable 'auto-fill-function) ; ?? move up some? (setq auto-fill-function 'matlab-auto-fill) (matlab-reset-vars) (if matlab-vers-on-startup (matlab-show-version))) ;;; regexps for MATLAB language =============================================== ;; "-pre" means "partial regular expression" (defvar matlab-block-beg-pre-if "function\\|for\\|while\\|if") (defvar matlab-block-beg-pre-no-if "for\\|while\\|if") (defvar matlab-block-beg-pre (if matlab-indent-function matlab-block-beg-pre-if matlab-block-beg-pre-no-if) "partial regular expression to recognize matlab block-begin keywords") (defconst matlab-block-mid-pre "elseif\\|else" "partial regular expression to recognize matlab mid-block keywords") (defconst matlab-block-end-pre "end" "partial regular expression to recognize matlab block-end keywords") (defconst matlab-other-pre "function\\|return" "partial regular express to recognize matlab non-block keywords") (defvar matlab-block-re (concat "\\(^\\|[;,]\\)[ \t]*\\(" matlab-block-beg-pre "\\|" matlab-block-mid-pre "\\|" matlab-block-end-pre "\\)\\b") "regular expression for keywords which begin matlab blocks") (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 "\\)")) (defconst matlab-cline-start-skip "[ \t]*%[ \t]*" "*The regular expression for skipping comment start.") (defun matlab-reset-vars () (setq matlab-block-beg-pre (if matlab-indent-function matlab-block-beg-pre-if matlab-block-beg-pre-no-if)) (setq matlab-block-re (concat "\\(^\\|[;,]\\)[ \t]*\\(" matlab-block-beg-pre "\\|" matlab-block-mid-pre "\\|" matlab-block-end-pre "\\)\\b"))) ;;; utilities ================================================================= (defun matlab-show-version () "Show the version number in the minibuffer." (interactive) (message "matlab-mode, version 1.08.0 dated 01Aug96")) (defun matlab-find-prev-line () (if (= -1 (forward-line -1)) nil (if (matlab-ltype-empty) (matlab-find-prev-line) t))) (defun matlab-prev-line () "Go to the previous line of code. Return nil if not found." (interactive) (let ((old-point (point))) (if (matlab-find-prev-line) t (goto-char old-point) nil))) ;;; line types and attributes ================================================= (defun matlab-ltype-empty () ; blank line "Returns t if current line is empty." (save-excursion (beginning-of-line) (looking-at "^[ \t]*$"))) (defun matlab-ltype-comm () ; comment line "Returns t if current line is a MATLAB comment line." (save-excursion (beginning-of-line) (looking-at "[ \t]*%[ \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-comm)))) (defun matlab-lattr-comm () ; line has comment "Returns t if current line contains a comment." (save-excursion (beginning-of-line) (looking-at "\\(^\\|.*[^%]\\)%[ \t]"))) (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]*\\(%.*\\)?$" (position-at-eol) t))) ;;; 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 () (if (matlab-lattr-comm) (matlab-comment)))) (skip-chars-forward " \t%")) (defun matlab-calc-indent () "Return the appropriate indentation for this line as an int." (interactive) (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 () "This routine returns the list (add-from-prev add-to-next)." (let ((add-from-prev 0) (add-to-next 0) eol) (if (matlab-ltype-comm) (list 0 0) (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-cont-level))) (setq add-to-next (+ add-to-next matlab-cont-level)))) (save-excursion (if (= 0 (forward-line -1)) (if (matlab-ltype-comm) () (if (matlab-lattr-cont) (setq add-to-next (- add-to-next matlab-cont-level))))))) ) (list add-from-prev add-to-next)))) ;;; the return key ============================================================ (defvar matlab-return-function 'matlab-indent-end-before-ret "Function to handle return key. Must be one of 'matlab-plain-ret 'matlab-indent-after-ret 'matlab-indent-end-before-ret 'matlab-indent-before-ret") (defun matlab-return () "Handle carriage return in matlab-mode." (interactive) (funcall matlab-return-function)) (defun matlab-plain-ret () "Vanila new line." (interactive) (newline)) (defun matlab-indent-after-ret () "Indent after new line." (interactive) (newline) (matlab-indent-line)) (defun matlab-indent-end-before-ret () "Indent line if block end, start new line, and indent again." (interactive) (if (save-excursion (beginning-of-line) (looking-at "[ \t]*\\(elseif\\|else\\|end\\)\\b")) (matlab-indent-line)) (newline) (matlab-indent-line)) (defun matlab-indent-before-ret () "Indent line, start new line, and indent again." (interactive) (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) (matlab-indent-line) (newline) (matlab-indent-line)) (defun matlab-comment-return () "Handle carriage return for matlab comment line." (interactive) (cond ((matlab-ltype-comm) (matlab-set-comm-fill-prefix) (newline) (insert fill-prefix) (matlab-indent-line)) ((matlab-lattr-comm) (newline) (indent-to matlab-comment-column) (insert matlab-comment-on-line-s)) (t (newline) (matlab-comment) (matlab-indent-line)))) (defun matlab-comm-from-prev () "If the previous line is a comment-line then set up a comment on this line." (save-excursion ;; If the previous line is a comment-line then set the fill prefix from ;; the previous line and fill this line. (if (and (= 0 (forward-line -1)) (matlab-ltype-comm)) (progn (matlab-set-comm-fill-prefix) (forward-line 1) (beginning-of-line) (delete-horizontal-space) (if (looking-at "%") (delete-char 1)) (delete-horizontal-space) (insert fill-prefix))))) (defun matlab-comment () "Add a comment to the current line." (interactive) (cond ((matlab-ltype-empty) ; empty line (matlab-comm-from-prev) (skip-chars-forward " \t%")) ((matlab-ltype-comm) ; comment line (matlab-comm-from-prev) (skip-chars-forward " \t%")) ((matlab-lattr-comm) ; code line w/ comment (beginning-of-line) (re-search-forward "[^%]%[ \t]") (forward-char -2) (if (< (current-column) matlab-comment-column) (indent-to matlab-comment-column)) (skip-chars-forward "% \t")) (t ; code line w/o comment (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 =================================================================== (defun matlab-set-comm-fill-prefix () "Set the fill-prefix for the current (comment) line." (interactive) (setq fill-prefix (save-excursion (beginning-of-line) (buffer-substring (point) (progn (re-search-forward "[ \t]*%[ \t]+") (point)))))) (defun matlab-set-code-fill-prefix () "Set the fill-prefix for the current code line." (setq fill-prefix (save-excursion (beginning-of-line) (buffer-substring (point) (progn (re-search-forward "[ \t]*") (point)))))) (defun matlab-auto-fill () "Do filling." (interactive) (if (> (current-column) fill-column) (cond ((matlab-ltype-comm) (matlab-set-comm-fill-prefix) (do-auto-fill)) ((and (and (matlab-ltype-code) (not (matlab-lattr-comm))) matlab-fill-code) (save-excursion (while (> (current-column) fill-column) (forward-char -1)) (re-search-backward "[ \t]+") (delete-horizontal-space) (insert " ...\n") (matlab-indent-line)))))) (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-wrap-line () 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 ((matlab-ltype-comm) (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-comm-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 matlab-comment-line-s) t)))))) (defun matlab-justify-line () "Delete space on end of line and justify." (interactive) (save-excursion (end-of-line) (delete-horizontal-space) (justify-current-line))) ;;; V19 stuff ================================================================= (defun matlab-mode-hilit () "Set up hilit19 support for matlab-mode." (interactive) (cond (window-system (setq hilit-mode-enable-list '(not text-mode) hilit-background-mode 'light hilit-inhibit-hooks nil hilit-inhibit-rebinding nil) (require 'hilit19) (hilit-set-mode-patterns 'matlab-mode matlab-hilit19-patterns)))) (defun matlab-frame-init () (interactive) (modify-frame-parameters (selected-frame) '((menu-bar-lines . 2))) ;; make a menu keymap (define-key matlab-mode-map [menu-bar matlab] (cons "Matlab" (make-sparse-keymap "Matlab"))) (define-key matlab-mode-map [menu-bar matlab version] '("version" . matlab-show-version))) ;;; matlab shell and debugging ================================================ ;;; ... in development ... (require 'comint) (defvar matlab-shell-prompt-pattern "^>> *" "regexp to match prompts in the inferior shell") ;; TBD if these will be useful (defvar matlab-shell-completion-fignore nil) (defvar matlab-shell-delimiter-argument-list '()) (defvar matlab-shell-dynamic-complete-functions '()) (defvar matlab-shell-input-autoexpand nil) (defvar matlab-shell-syntax-table nil "the syntax table used in matlab-shell") (if matlab-shell-syntax-table () (setq matlab-shell-syntax-table (make-syntax-table (standard-syntax-table))) (modify-syntax-entry ?_ "_" matlab-shell-syntax-table) (modify-syntax-entry ?% ".1" matlab-shell-syntax-table) ;(modify-syntax-entry ?\ "-2" matlab-shell-syntax-table) ; prob w/ xemacs ;(modify-syntax-entry ?\t "-2" matlab-shell-syntax-table) ; prob w/ xemacs ;(modify-syntax-entry ?\n "->" matlab-shell-syntax-table) ; prob w/ xemacs (set-syntax-table matlab-shell-syntax-table)) (defvar matlab-shell-abbrev-table nil "the abbrev table used in matlab-shell buffers") (define-abbrev-table 'matlab-shell-abbrev-table ()) (defvar matlab-shell-map () "the keymap used in matlab-shell") (if matlab-shell-map () (setq matlab-shell-map (make-sparse-keymap)) (define-key matlab-shell-map "\r" 'matlab-shell-return)) (defvar matlab-shell-map () "the mode map for running MATLAB in emacs") (defun matlab-shell () "Run MATLAB in an inferior shell buffer. Special Key Bindings: \\{matlab-shell-map} Variables: Commands: matlab-shell-quit Quit MATLAB." (interactive) (progn (make-comint "matlab-shell" "matlab") (switch-to-buffer "*matlab-shell*")) (comint-mode) (setq major-mode 'matlab-shell) (setq mode-name "Matlab-shell") (use-local-map matlab-shell-map) (setq comint-prompt-regexp matlab-shell-prompt-pattern) (setq comint-completion-fignore matlab-shell-completion-fignore) (setq comint-delimiter-argument-list matlab-shell-delimiter-argument-list) (setq comint-dynamic-complete-functions matlab-shell-dynamic-complete-functions) (make-local-variable 'paragraph-start) (setq paragraph-start comint-prompt-regexp) (if t () (make-local-variable 'shell-dirstack) (setq shell-dirstack nil) (setq shell-last-dir nil) (make-local-variable 'shell-dirtrackp) (setq shell-dirtrackp t) (add-hook 'comint-input-filter-functions 'shell-directory-tracker)) (setq comint-input-autoexpand matlab-shell-input-autoexpand) (run-hooks 'matlab-shell-hook) (comint-read-input-ring t) (if matlab-vers-on-startup (matlab-show-version))) (defun matlab-shell-return () "Handle a in matlab-shell." (interactive) (beginning-of-line) (re-search-forward ">>") (let ((command "")) (setq command (buffer-substring (point) (position-at-eol))) (delete-region (point) (position-at-eol)) (process-send-string "matlab-shell" (concat command "\r")))) (defun matlab-shell-quit () "Exit matlab session." (interactive) (process-send-string "matlab" "exit")) (defun matlab-shell-filter (proc string) (let* ((obuf (current-buffer)) (buffer (process-buffer proc)) opoint (window (get-buffer-window buffer)) (pos (window-start window))) (unwind-protect (progn (set-buffer buffer) (or (= (point) (point-max)) (setq opoint (point))) (goto-char (point-max)) (insert-before-markers (matlab-shell-strip-esc string))) ;; insert-before-markers moved this marker: set it back. (set-window-start window pos) ;; Finish our save-excursion. (if opoint (goto-char opoint)) (set-buffer obuf)))) (defun matlab-shell-strip-esc (string) ;; strip out escape sequences (let ((pos 0) (str "")) (while (< pos (length string)) (if (char-equal (elt string pos) ?\e) (progn (setq pos (+ pos 1)) (cond ((char-equal (elt string pos) ?=) (setq pos (+ pos 1))) ((char-equal (elt string pos) ?>) (setq pos (+ pos 1))) ((char-equal (elt string pos) ?[) (setq pos (+ pos 4))))) (setq str (concat str (char-to-string (elt string pos)))) (setq pos (+ pos 1)))) str)) ;;; 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-comm) (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-comm) (setq msg (concat msg " w/comm"))) (message msg))) (defun matlab-clear-vars () (interactive) (makunbound 'matlab-indent-level) (makunbound 'matlab-cont-level) (makunbound 'matlab-comment-line-s) (makunbound 'matlab-comment-on-line-s) (makunbound 'matlab-comment-region-s) (makunbound 'matlab-indent-function) (makunbound 'matlab-matlab-mode-syntax-table) (makunbound 'matlab-matlab-mode-abbrev-table) (makunbound 'matlab-matlab-mode-map) (makunbound 'matlab-matlab-block-beg-pre) (makunbound 'matlab-matlab-block-mid-pre) (makunbound 'matlab-matlab-block-end-pre) (makunbound 'matlab-matlab-other-pre) (makunbound 'matlab-matlab-block-re) (makunbound 'matlab-matlab-block-beg-re) (makunbound 'matlab-matlab-block-end-re) (makunbound 'matlab-cline-start-skip) (makunbound 'matlab-matlab-font-lock-keywords)) ;;; 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 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-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) ;;; Change log ;; ;; 01Aug96 by Matt Wette <mwette@alumni.caltech.edu> ;; fixed to jive w/ emacs lib conventions: changed name of file from ;; matlab-mode.el to matlab.el (14 char limit); released as 1.08.0 ;; ;; 28Apr96 by Matt Wette <mwette@alumni.caltech.edu> ;; comments lines w/ just % are now hilighted; syntax table: "-2" changed ;; to " 2"; released 1.07.6 ;; ;; 30Jan96 by Matt Wette <mwette@alumni.caltech.edu> ;; fixed problem w/ emacs-19.30 filling and auto-fill problem thanks to ;; Mats BengTsson <matsb@s3.kth.se>; started implementation of matlab- ;; shell, based on comint and shell-mode; released 1.07.5 ;; ;; 25Jan96 by Matt Wette <mwette@alumni.caltech.edu> ;; added "global" to font-lock, hilit keywords; fixed indenting of 2nd ;; line if first ends in ...; filling is broken for FSF19.30 (works for ;; FSF19.28); torkel fixes to matlab-reset-vars; fixed indent bug ;; reported by Trevor Cooper; ;; ;; 20Jan96 by Matt Wette <mwette@alumni.caltech.edu> ;; cleaned up commenting; added preliminary matlab-shell mode, rel 1.07.4 ;; ;; 19Jan96 by Matt Wette <mwette@alumni.caltech.edu> ;; commented out debug-on-error; got hilit to work for sam ;; ;; 18Jan96 by Matt Wette <mwette@alumni.caltech.edu> ;; fixed problem int matlab-prev-line which caused fatal matlab-mode; ;; crash fixed problem with indenting when keywords in comments; still ;; haven't cleaned up comment formatting ... ;; ;; 21Jul95 by Matt Wette <mwette@alumni.caltech.edu> ;; fixes by Bjorn Torkelsson <torkel@cs.umu.se>: replaced lattr-comment ;; w/ lattr-comm to fix inconsistency; added function to font-lock ;; keywords, added function name to font-lock-function-name-face. He had ;; also added funtion as a block begin keyword. This should be an option ;; since it will cause the body of a function to be indented. Worked on ;; filling. More work on filling. fixed many bugs reported by Rob ;; Cunningham. Pulled cadr. ;; ;; 13Jul95 by Matt Wette <mwette@mr-ed.jpl.nasa.gov> ;; changed indenting for continuation lines in calc-deltas to use ;; cont-level; changed syntab-table; changed the way the return key is ;; mapped; released version 1.07.1 ;; ;; 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. ;; ;;; matlab.el ends here