-;; octave-mod.el --- editing Octave source files under Emacs
+;;; octave-mod.el --- editing Octave source files under Emacs
-;;; Copyright (C) 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;; Free Software Foundation, Inc.
-;; Author: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
+;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
;; Author: John Eaton <jwe@bevo.che.wisc.edu>
-;; Maintainer: Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>
+;; Maintainer: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
;; Keywords: languages
;; 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)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; `run-octave' for further information on usage and customization.
;;; Code:
+(require 'custom)
+
+(defgroup octave nil
+ "Major mode for editing Octave source files."
+ :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
+ :group 'languages)
+
+(defvar inferior-octave-output-list nil)
+(defvar inferior-octave-output-string nil)
+(defvar inferior-octave-receive-in-progress nil)
(defconst octave-maintainer-address
- "Kurt Hornik <Kurt.Hornik@ci.tuwien.ac.at>, bug-gnu-emacs@prep.ai.mit.edu"
+ "Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>, bug-gnu-emacs@gnu.org"
"Current maintainer of the Emacs Octave package.")
(defvar octave-abbrev-table nil
"Abbrev table for Octave's reserved words.
-Used in octave-mode and inferior-octave-mode buffers.
+Used in `octave-mode' and inferior-octave-mode buffers.
All Octave abbrevs start with a grave accent (`).")
-(if octave-abbrev-table
- ()
- (let ((ac abbrevs-changed))
- (define-abbrev-table 'octave-abbrev-table ())
- (define-abbrev octave-abbrev-table "`a" "all_va_args" nil)
- (define-abbrev octave-abbrev-table "`b" "break" nil)
- (define-abbrev octave-abbrev-table "`cs" "case" nil)
- (define-abbrev octave-abbrev-table "`ca" "catch" nil)
- (define-abbrev octave-abbrev-table "`c" "continue" nil)
- (define-abbrev octave-abbrev-table "`el" "else" nil)
- (define-abbrev octave-abbrev-table "`eli" "elseif" nil)
- (define-abbrev octave-abbrev-table "`et" "end_try_catch" nil)
- (define-abbrev octave-abbrev-table "`eu" "end_unwind_protect" nil)
- (define-abbrev octave-abbrev-table "`ef" "endfor" nil)
- (define-abbrev octave-abbrev-table "`efu" "endfunction" nil)
- (define-abbrev octave-abbrev-table "`ei" "endif" nil)
- (define-abbrev octave-abbrev-table "`es" "endswitch" nil)
- (define-abbrev octave-abbrev-table "`ew" "endwhile" nil)
- (define-abbrev octave-abbrev-table "`f" "for" nil)
- (define-abbrev octave-abbrev-table "`fu" "function" nil)
- (define-abbrev octave-abbrev-table "`gl" "global" nil)
- (define-abbrev octave-abbrev-table "`gp" "gplot" nil)
- (define-abbrev octave-abbrev-table "`gs" "gsplot" nil)
- (define-abbrev octave-abbrev-table "`if" "if ()" nil)
- (define-abbrev octave-abbrev-table "`o" "otherwise" nil)
- (define-abbrev octave-abbrev-table "`rp" "replot" nil)
- (define-abbrev octave-abbrev-table "`r" "return" nil)
- (define-abbrev octave-abbrev-table "`s" "switch" nil)
- (define-abbrev octave-abbrev-table "`t" "try" nil)
- (define-abbrev octave-abbrev-table "`up" "unwind_protect" nil)
- (define-abbrev octave-abbrev-table "`upc" "unwind_protect_cleanup" nil)
- (define-abbrev octave-abbrev-table "`w" "while ()" nil)
- (setq abbrevs-changed ac)))
+(unless octave-abbrev-table
+ (define-abbrev-table 'octave-abbrev-table ()))
+
+(let ((ac abbrevs-changed))
+ (define-abbrev octave-abbrev-table "`a" "all_va_args" nil 0 t)
+ (define-abbrev octave-abbrev-table "`b" "break" nil 0 t)
+ (define-abbrev octave-abbrev-table "`cs" "case" nil 0 t)
+ (define-abbrev octave-abbrev-table "`ca" "catch" nil 0 t)
+ (define-abbrev octave-abbrev-table "`c" "continue" nil 0 t)
+ (define-abbrev octave-abbrev-table "`el" "else" nil 0 t)
+ (define-abbrev octave-abbrev-table "`eli" "elseif" nil 0 t)
+ (define-abbrev octave-abbrev-table "`et" "end_try_catch" nil 0 t)
+ (define-abbrev octave-abbrev-table "`eu" "end_unwind_protect" nil 0 t)
+ (define-abbrev octave-abbrev-table "`ef" "endfor" nil 0 t)
+ (define-abbrev octave-abbrev-table "`efu" "endfunction" nil 0 t)
+ (define-abbrev octave-abbrev-table "`ei" "endif" nil 0 t)
+ (define-abbrev octave-abbrev-table "`es" "endswitch" nil 0 t)
+ (define-abbrev octave-abbrev-table "`ew" "endwhile" nil 0 t)
+ (define-abbrev octave-abbrev-table "`f" "for" nil 0 t)
+ (define-abbrev octave-abbrev-table "`fu" "function" nil 0 t)
+ (define-abbrev octave-abbrev-table "`gl" "global" nil 0 t)
+ (define-abbrev octave-abbrev-table "`gp" "gplot" nil 0 t)
+ (define-abbrev octave-abbrev-table "`gs" "gsplot" nil 0 t)
+ (define-abbrev octave-abbrev-table "`if" "if ()" nil 0 t)
+ (define-abbrev octave-abbrev-table "`o" "otherwise" nil 0 t)
+ (define-abbrev octave-abbrev-table "`rp" "replot" nil 0 t)
+ (define-abbrev octave-abbrev-table "`r" "return" nil 0 t)
+ (define-abbrev octave-abbrev-table "`s" "switch" nil 0 t)
+ (define-abbrev octave-abbrev-table "`t" "try" nil 0 t)
+ (define-abbrev octave-abbrev-table "`up" "unwind_protect" nil 0 t)
+ (define-abbrev octave-abbrev-table "`upc" "unwind_protect_cleanup" nil 0 t)
+ (define-abbrev octave-abbrev-table "`w" "while ()" nil 0 t)
+ (setq abbrevs-changed ac))
(defvar octave-comment-char ?#
"Character to start an Octave comment.")
(defvar octave-comment-start
- (concat (make-string 1 octave-comment-char) " ")
+ (string octave-comment-char ?\ )
"String to insert to start a new Octave in-line comment.")
(defvar octave-comment-start-skip "\\s<+\\s-*"
"Regexp to match the start of an Octave comment up to its body.")
'font-lock-keyword-face)
;; Fontify all builtin operators.
(cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)"
- 'font-lock-reference-face)
+ (if (boundp 'font-lock-builtin-face)
+ 'font-lock-builtin-face
+ 'font-lock-preprocessor-face))
;; Fontify all builtin variables.
(cons (concat "\\<\\("
(mapconcat 'identity octave-variables "\\|")
'(3 font-lock-function-name-face nil t)))
"Additional Octave expressions to highlight.")
-(defvar inferior-octave-buffer "*Inferior Octave*"
- "*Name of buffer for running an inferior Octave process.")
+(defcustom inferior-octave-buffer "*Inferior Octave*"
+ "*Name of buffer for running an inferior Octave process."
+ :type 'string
+ :group 'octave-inferior)
(defvar inferior-octave-process nil)
\f
(define-key map "\n" 'octave-reindent-then-newline-and-indent)
(define-key map "\t" 'indent-according-to-mode)
(define-key map "\e;" 'octave-indent-for-comment)
- (define-key map "\e\n" 'octave-indent-new-comment-line)
+ (define-key map "\e\n" 'octave-indent-new-comment-line)
(define-key map "\e\t" 'octave-complete-symbol)
(define-key map "\M-\C-a" 'octave-beginning-of-defun)
(define-key map "\M-\C-e" 'octave-end-of-defun)
(define-key map "\M-\C-h" 'octave-mark-defun)
- (define-key map "\M-\C-q" 'octave-indent-defun)
+ (define-key map "\M-\C-q" 'octave-indent-defun)
(define-key map "\C-c;" 'octave-comment-region)
- (define-key map "\C-c:" 'octave-uncomment-region)
+ (define-key map "\C-c:" 'octave-uncomment-region)
(define-key map "\C-c\C-b" 'octave-submit-bug-report)
(define-key map "\C-c\C-p" 'octave-previous-code-line)
(define-key map "\C-c\C-n" 'octave-next-code-line)
(define-key map "\C-c\C-a" 'octave-beginning-of-line)
- (define-key map "\C-c\C-e" 'octave-end-of-line)
+ (define-key map "\C-c\C-e" 'octave-end-of-line)
(define-key map "\C-c\M-\C-n" 'octave-forward-block)
(define-key map "\C-c\M-\C-p" 'octave-backward-block)
(define-key map "\C-c\M-\C-u" 'octave-backward-up-block)
(define-key map "\C-c\M-\C-d" 'octave-down-block)
(define-key map "\C-c\M-\C-h" 'octave-mark-block)
(define-key map "\C-c]" 'octave-close-block)
- (define-key map "\C-cf" 'octave-insert-defun)
+ (define-key map "\C-c\C-f" 'octave-insert-defun)
(define-key map "\C-c\C-h" 'octave-help)
- (define-key map "\C-cil" 'octave-send-line)
- (define-key map "\C-cib" 'octave-send-block)
- (define-key map "\C-cif" 'octave-send-defun)
- (define-key map "\C-cir" 'octave-send-region)
- (define-key map "\C-cis" 'octave-show-process-buffer)
- (define-key map "\C-cih" 'octave-hide-process-buffer)
- (define-key map "\C-cik" 'octave-kill-process)
+ (define-key map "\C-c\C-il" 'octave-send-line)
+ (define-key map "\C-c\C-ib" 'octave-send-block)
+ (define-key map "\C-c\C-if" 'octave-send-defun)
+ (define-key map "\C-c\C-ir" 'octave-send-region)
+ (define-key map "\C-c\C-is" 'octave-show-process-buffer)
+ (define-key map "\C-c\C-ih" 'octave-hide-process-buffer)
+ (define-key map "\C-c\C-ik" 'octave-kill-process)
+ (define-key map "\C-c\C-i\C-l" 'octave-send-line)
+ (define-key map "\C-c\C-i\C-b" 'octave-send-block)
+ (define-key map "\C-c\C-i\C-f" 'octave-send-defun)
+ (define-key map "\C-c\C-i\C-r" 'octave-send-region)
+ (define-key map "\C-c\C-i\C-s" 'octave-show-process-buffer)
+ (define-key map "\C-c\C-i\C-h" 'octave-hide-process-buffer)
+ (define-key map "\C-c\C-i\C-k" 'octave-kill-process)
(setq octave-mode-map map)))
(defvar octave-mode-menu
["Lookup Octave Index" octave-help t])
"Menu for Octave mode.")
-(defvar octave-mode-syntax-table nil
- "Syntax table in use in octave-mode buffers.")
-(if octave-mode-syntax-table
- ()
+(defvar octave-mode-syntax-table
(let ((table (make-syntax-table)))
(modify-syntax-entry ?\r " " table)
(modify-syntax-entry ?+ "." table)
(modify-syntax-entry ?\" "\"" table)
(modify-syntax-entry ?. "w" table)
(modify-syntax-entry ?_ "w" table)
- (modify-syntax-entry ?\% "." table)
+ (modify-syntax-entry ?\% "<" table)
(modify-syntax-entry ?\# "<" table)
(modify-syntax-entry ?\n ">" table)
- (setq octave-mode-syntax-table table)))
+ table)
+ "Syntax table in use in `octave-mode' buffers.")
-(defvar octave-auto-newline nil
- "*Non-nil means automatically newline after a semicolon in Octave mode.")
+(defcustom octave-auto-indent nil
+ "*Non-nil means indent line after a semicolon or space in Octave mode."
+ :type 'boolean
+ :group 'octave)
-(defvar octave-blink-matching-block t
+(defcustom octave-auto-newline nil
+ "*Non-nil means automatically newline after a semicolon in Octave mode."
+ :type 'boolean
+ :group 'octave)
+
+(defcustom octave-blink-matching-block t
"*Control the blinking of matching Octave block keywords.
Non-nil means show matching begin of block when inserting a space,
-newline or semicolon after an else or end keyword.")
-(defvar octave-block-offset 2
- "*Extra indentation applied to statements in Octave block structures.")
+newline or semicolon after an else or end keyword."
+ :type 'boolean
+ :group 'octave)
+(defcustom octave-block-offset 2
+ "*Extra indentation applied to statements in Octave block structures."
+ :type 'integer
+ :group 'octave)
(defvar octave-block-begin-regexp
(concat "\\<\\("
'(("for" . ("end" "endfor"))
("function" . ("end" "endfunction"))
("if" . ("else" "elseif" "end" "endif"))
- ("switch" . ("case" "end" "endswitch" "otherwise"))
+ ("switch" . ("case" "otherwise" "end" "endswitch"))
("try" . ("catch" "end" "end_try_catch"))
("unwind_protect" . ("unwind_protect_cleanup" "end"
"end_unwind_protect"))
(concat (make-string 2 octave-comment-char) " ")
"String to insert to start a new Octave comment on an empty line.")
-(defvar octave-continuation-offset 4
- "*Extra indentation applied to Octave continuation lines.")
+(defcustom octave-continuation-offset 4
+ "*Extra indentation applied to Octave continuation lines."
+ :type 'integer
+ :group 'octave)
(defvar octave-continuation-regexp
"[^#%\n]*\\(\\\\\\|\\.\\.\\.\\)\\s-*\\(\\s<.*\\)?$")
-(defvar octave-continuation-string "\\"
- "*Character string used for Octave continuation lines. Normally \\.")
+(defcustom octave-continuation-string "\\"
+ "*Character string used for Octave continuation lines. Normally \\."
+ :type 'string
+ :group 'octave)
(defvar octave-completion-alist nil
"Alist of Octave symbols for completion in Octave mode.
Each element looks like (VAR . VAR), where the car and cdr are the same
symbol (an Octave command or variable name).
-Currently, only builtin variables can be completed.")
+Currently, only builtin variables can be completed.")
(defvar octave-mode-imenu-generic-expression
(list
(list nil octave-function-header-regexp 3))
"Imenu expression for Octave mode. See `imenu-generic-expression'.")
-(defvar octave-mode-startup-message t
- "*Nil means do not display the Octave mode startup message.")
-
-(defvar octave-mode-hook nil
- "*Hook to be run when Octave mode is started.")
-
-(defvar octave-send-show-buffer t
- "*Non-nil means display `inferior-octave-buffer' after sending to it.")
-(defvar octave-send-line-auto-forward t
+(defcustom octave-mode-startup-message t
+ "*nil means do not display the Octave mode startup message."
+ :type 'boolean
+ :group 'octave)
+
+(defcustom octave-mode-hook nil
+ "*Hook to be run when Octave mode is started."
+ :type 'hook
+ :group 'octave)
+
+(defcustom octave-send-show-buffer t
+ "*Non-nil means display `inferior-octave-buffer' after sending to it."
+ :type 'boolean
+ :group 'octave)
+(defcustom octave-send-line-auto-forward t
"*Control auto-forward after sending to the inferior Octave process.
-Non-nil means always go to the next Octave code line after sending.")
-(defvar octave-send-echo-input t
- "*Non-nil means echo input sent to the inferior Octave process.")
+Non-nil means always go to the next Octave code line after sending."
+ :type 'boolean
+ :group 'octave)
+(defcustom octave-send-echo-input t
+ "*Non-nil means echo input sent to the inferior Octave process."
+ :type 'boolean
+ :group 'octave)
\f
;;;###autoload
Variables you can use to customize Octave mode
==============================================
+octave-auto-indent
+ Non-nil means indent current line after a semicolon or space.
+ Default is nil.
+
octave-auto-newline
Non-nil means auto-insert a newline and indent after a semicolon.
Default is nil.
Default is a backslash.
octave-mode-startup-message
- Nil means do not display the Octave mode startup message.
+ nil means do not display the Octave mode startup message.
Default is t.
octave-send-echo-input
(setq mode-name "Octave")
(setq local-abbrev-table octave-abbrev-table)
(set-syntax-table octave-mode-syntax-table)
-
+
(make-local-variable 'indent-line-function)
(setq indent-line-function 'octave-indent-line)
- (make-local-variable 'comment-start)
+ (make-local-variable 'comment-start)
(setq comment-start octave-comment-start)
(make-local-variable 'comment-end)
(setq comment-end "")
(make-local-variable 'comment-column)
- (setq comment-column 32)
+ (setq comment-column 32)
(make-local-variable 'comment-start-skip)
(setq comment-start-skip "\\s<+\\s-*")
(make-local-variable 'comment-indent-function)
(setq font-lock-defaults '(octave-font-lock-keywords nil nil))
(make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression octave-mode-imenu-generic-expression)
+ (setq imenu-generic-expression octave-mode-imenu-generic-expression
+ imenu-case-fold-search nil)
(octave-add-octave-menu)
(octave-initialize-completions)
- (run-hooks 'octave-mode-hook))
+ (run-mode-hooks 'octave-mode-hook))
\f
;;; Miscellaneous useful functions
(defun octave-describe-major-mode ()
(interactive)
(describe-function major-mode))
-(defun octave-point (position)
- "Returns the value of point at certain positions."
- (save-excursion
- (cond
- ((eq position 'bol) (beginning-of-line))
- ((eq position 'eol) (end-of-line))
- ((eq position 'boi) (back-to-indentation))
- ((eq position 'bonl) (forward-line 1))
- ((eq position 'bopl) (forward-line -1))
- (t (error "unknown buffer position requested: %s" position)))
- (point)))
-
(defsubst octave-in-comment-p ()
- "Returns t if point is inside an Octave comment, nil otherwise."
+ "Return t if point is inside an Octave comment."
(interactive)
(save-excursion
- (nth 4 (parse-partial-sexp (octave-point 'bol) (point)))))
+ (nth 4 (parse-partial-sexp (line-beginning-position) (point)))))
(defsubst octave-in-string-p ()
- "Returns t if point is inside an Octave string, nil otherwise."
+ "Return t if point is inside an Octave string."
(interactive)
(save-excursion
- (nth 3 (parse-partial-sexp (octave-point 'bol) (point)))))
+ (nth 3 (parse-partial-sexp (line-beginning-position) (point)))))
(defsubst octave-not-in-string-or-comment-p ()
- "Returns t iff point is not inside an Octave string or comment."
- (let ((pps (parse-partial-sexp (octave-point 'bol) (point))))
+ "Return t if point is not inside an Octave string or comment."
+ (let ((pps (parse-partial-sexp (line-beginning-position) (point))))
(not (or (nth 3 pps) (nth 4 pps)))))
(defun octave-in-block-p ()
- "Returns t if point is inside an Octave block, nil otherwise.
+ "Return t if point is inside an Octave block.
The block is taken to start at the first letter of the begin keyword and
to end after the end keyword."
(let ((pos (point)))
(< pos (point)))))
(defun octave-in-defun-p ()
- "Returns t iff point is inside an Octave function declaration.
+ "Return t if point is inside an Octave function declaration.
The function is taken to start at the `f' of `function' and to end after
the end keyword."
(let ((pos (point)))
(error nil))
(< pos (point)))))))
+(defun octave-maybe-insert-continuation-string ()
+ (if (or (octave-in-comment-p)
+ (save-excursion
+ (beginning-of-line)
+ (looking-at octave-continuation-regexp)))
+ nil
+ (delete-horizontal-space)
+ (insert (concat " " octave-continuation-string))))
+
+(defvar octave-xemacs-p
+ (string-match "XEmacs\\|Lucid" emacs-version))
+
;;; Comments
(defun octave-comment-region (beg end &optional arg)
"Comment or uncomment each line in the region as Octave code.
(interactive "r\nP")
(let ((comment-start (char-to-string octave-comment-char)))
(comment-region beg end arg)))
-
+
(defun octave-uncomment-region (beg end &optional arg)
"Uncomment each line in the region as Octave code."
(interactive "r\nP")
(back-to-indentation)
(setq icol (current-column))
(let ((bot (point))
- (eol (octave-point 'eol)))
+ (eol (line-end-position)))
(while (< (point) eol)
(if (octave-not-in-string-or-comment-p)
(cond
((and (looking-at octave-block-end-regexp)
(octave-not-in-string-or-comment-p))
(setq icol (- icol (octave-block-end-offset))))
- ((looking-at "\\s<\\s<\\s<\\S<")
+ ((or (looking-at "\\s<\\s<\\s<\\S<")
+ (octave-before-magic-comment-p))
(setq icol (list 0 icol)))
((looking-at "\\s<\\S<")
(setq icol (list comment-column icol)))))
(* octave-block-offset
(if (string-match (match-string 0) "switch") 2 1))))
+(defun octave-before-magic-comment-p ()
+ (save-excursion
+ (beginning-of-line)
+ (and (bobp) (looking-at "\\s-*#!"))))
+
(defun octave-comment-indent ()
- (if (looking-at "\\s<\\s<\\s<")
+ (if (or (looking-at "\\s<\\s<\\s<")
+ (octave-before-magic-comment-p))
0
(if (looking-at "\\s<\\s<")
(calculate-octave-indent)
(defun octave-indent-for-comment ()
"Maybe insert and indent an Octave comment.
If there is no comment already on this line, create a code-level comment
-(started by two comment characters) if the line is empty, or an in-line
-comment (started by one comment character) otherwise.
+\(started by two comment characters) if the line is empty, or an in-line
+comment (started by one comment character) otherwise.
Point is left after the start of the comment which is properly aligned."
(interactive)
- (indent-for-comment)
+ (beginning-of-line)
+ (if (looking-at "^\\s-*$")
+ (insert octave-block-comment-start)
+ (indent-for-comment))
(indent-according-to-mode))
(defun octave-indent-line (&optional arg)
(defun octave-indent-new-comment-line ()
"Break Octave line at point, continuing comment if within one.
If within code, insert `octave-continuation-string' before breaking the
-line. If within a string, signal an error.
-The new line is properly indented."
+line. If within a string, signal an error.
+The new line is properly indented."
(interactive)
(delete-horizontal-space)
(cond
(setq n (forward-line inc)))
(setq arg (- arg inc)))
n))
-
+
(defun octave-previous-code-line (&optional arg)
"Move ARG lines of Octave code backward (forward if ARG is negative).
Skips past all empty and comment lines. Default for ARG is 1.
(looking-at octave-continuation-regexp)))
(zerop (forward-line 1)))))
(end-of-line)))
-
+
(defun octave-scan-blocks (from count depth)
"Scan from character number FROM by COUNT Octave begin-end blocks.
Returns the character number of the position thus found.
(buffer-substring-no-properties
(match-beginning 0) pos)
pos (+ pos 1)
- eol (octave-point 'eol)
+ eol (line-end-position)
bb-arg
(save-excursion
(save-restriction
(interactive "p")
(or arg (setq arg 1))
(and (< arg 0) (skip-syntax-backward "w"))
- (and (> arg 0) (skip-syntax-forward "w"))
+ (and (> arg 0) (skip-syntax-forward "w"))
(if (octave-in-defun-p)
(setq arg (- arg 1)))
(if (= arg 0) (setq arg -1))
(exchange-point-and-mark))
(goto-char pos)
(message "No function to mark found"))))
-
+
\f
;;; Filling
(defun octave-auto-fill ()
- "Perform auto-fill in Octave mode."
- (if (> (current-column) (current-fill-column))
- (if (octave-in-comment-p)
- (do-auto-fill)
- (if (> (current-column) (current-fill-column))
- (let ((fill-column (- (current-fill-column)
- (length octave-continuation-string))))
- (do-auto-fill)
- (save-excursion
- (forward-line -1)
- (end-of-line)
- (insert (concat " " octave-continuation-string)))
- (indent-according-to-mode))))))
+ "Perform auto-fill in Octave mode.
+Returns nil if no feasible place to break the line could be found, and t
+otherwise."
+ (let (fc give-up)
+ (if (or (null (setq fc (current-fill-column)))
+ (save-excursion
+ (beginning-of-line)
+ (and auto-fill-inhibit-regexp
+ (looking-at auto-fill-inhibit-regexp))))
+ nil ; Can't do anything
+ (if (and (not (octave-in-comment-p))
+ (> (current-column) fc))
+ (setq fc (- fc (+ (length octave-continuation-string) 1))))
+ (while (and (not give-up) (> (current-column) fc))
+ (let* ((opoint (point))
+ (fpoint
+ (save-excursion
+ (move-to-column (+ fc 1))
+ (skip-chars-backward "^ \t\n")
+ ;; If we're at the beginning of the line, break after
+ ;; the first word
+ (if (bolp)
+ (re-search-forward "[ \t]" opoint t))
+ ;; If we're in a comment line, don't break after the
+ ;; comment chars
+ (if (save-excursion
+ (skip-syntax-backward " <")
+ (bolp))
+ (re-search-forward "[ \t]" (line-end-position)
+ 'move))
+ ;; If we're not in a comment line and just ahead the
+ ;; continuation string, don't break here.
+ (if (and (not (octave-in-comment-p))
+ (looking-at
+ (concat "\\s-*"
+ (regexp-quote
+ octave-continuation-string)
+ "\\s-*$")))
+ (end-of-line))
+ (skip-chars-backward " \t")
+ (point))))
+ (if (save-excursion
+ (goto-char fpoint)
+ (not (or (bolp) (eolp))))
+ (let ((prev-column (current-column)))
+ (if (save-excursion
+ (skip-chars-backward " \t")
+ (= (point) fpoint))
+ (progn
+ (octave-maybe-insert-continuation-string)
+ (indent-new-comment-line t))
+ (save-excursion
+ (goto-char fpoint)
+ (octave-maybe-insert-continuation-string)
+ (indent-new-comment-line t)))
+ (if (>= (current-column) prev-column)
+ (setq give-up t)))
+ (setq give-up t))))
+ (not give-up))))
(defun octave-fill-paragraph (&optional arg)
"Fill paragraph of Octave code, handling Octave comments."
(interactive "P")
- (save-excursion
+ (save-excursion
(let ((end (progn (forward-paragraph) (point)))
(beg (progn
(forward-paragraph -1)
(beginning-of-line)
(looking-at "^\\s-*\\s<+\\s-*$"))))
;; This is a nonempty comment line which does not extend
- ;; past the fill column. If it is followed by an nonempty
+ ;; past the fill column. If it is followed by a nonempty
;; comment line with the same comment prefix, try to
;; combine them, and repeat this until either we reach the
;; fill-column or there is nothing more to combine.
(delete-region (match-beginning 0) (match-end 0))
(fixup-whitespace)
(move-to-column cfc))))
+ ;; We might also try to combine continued code lines> Perhaps
+ ;; some other time ...
(skip-chars-forward "^ \t\n")
(delete-horizontal-space)
(if (or (< (current-column) cfc)
(and (= (current-column) cfc) (eolp)))
(forward-line 1)
(if (not (eolp)) (insert " "))
- (octave-auto-fill))))
+ (or (octave-auto-fill)
+ (forward-line 1)))))
t)))
\f
(let ((list (all-completions string octave-completion-alist))
(conf (current-window-configuration)))
;; Taken from comint.el
- (message "Making completion list...")
+ (message "Making completion list...")
(with-output-to-temp-buffer "*Completions*"
- (display-completion-list list))
+ (display-completion-list list string))
(message "Hit space to flush")
(let (key first)
(if (save-excursion
(set-window-configuration conf)
(setq unread-command-events
(listify-key-sequence key))))))))))
-
+
\f
;;; Electric characters && friends
(defun octave-reindent-then-newline-and-indent ()
(defun octave-electric-semi ()
"Insert a semicolon in Octave mode.
-Always reindent the line. Insert a newline if `octave-auto-newline' is
-non-nil."
+Maybe expand abbrevs and blink matching block open keywords.
+Reindent the line of `octave-auto-indent' is non-nil.
+Insert a newline if `octave-auto-newline' is non-nil."
(interactive)
(if (not (octave-not-in-string-or-comment-p))
(insert ";")
(if abbrev-mode (expand-abbrev))
(if octave-blink-matching-block
(octave-blink-matching-block-open))
- (indent-according-to-mode)
+ (if octave-auto-indent
+ (indent-according-to-mode))
(insert ";")
(if octave-auto-newline
(newline-and-indent))))
(defun octave-electric-space ()
"Insert a space in Octave mode.
-Maybe expand abbrevs and blink matching block open keywords."
+Maybe expand abbrevs and blink matching block open keywords.
+Reindent the line of `octave-auto-indent' is non-nil."
(interactive)
(setq last-command-char ? )
- (if (not (octave-not-in-string-or-comment-p))
+ (if (and octave-auto-indent
+ (not (octave-not-in-string-or-comment-p)))
(progn
(indent-according-to-mode)
(self-insert-command 1))
(if abbrev-mode (expand-abbrev))
(if octave-blink-matching-block
(octave-blink-matching-block-open))
- (if (save-excursion
- (skip-syntax-backward " ")
- (not (bolp)))
+ (if (and octave-auto-indent
+ (save-excursion
+ (skip-syntax-backward " ")
+ (not (bolp))))
(indent-according-to-mode))
(self-insert-command 1)))
(self-insert-command 1)
(let (c)
(insert last-command-char)
- (if (or (eq (setq c (read-event)) ??)
- (eq c help-char))
- (let ((abbrev-table-name-list '(octave-mode-abbrev-table)))
+ (if (if octave-xemacs-p
+ (or (eq (event-to-character (setq c (next-event))) ??)
+ (eq (event-to-character c) help-char))
+ (or (eq (setq c (read-event)) ??)
+ (eq c help-char)))
+ (let ((abbrev-table-name-list '(octave-abbrev-table)))
(list-abbrevs))
(setq unread-command-events (list c))))))
(indent-according-to-mode)
(newline 2)
(insert prefix "usage: " string)
- (reindent-then-newline-and-indent)
+ (reindent-then-newline-and-indent)
(insert prefix)
- (reindent-then-newline-and-indent)
+ (reindent-then-newline-and-indent)
(insert prefix)
(indent-according-to-mode)
(save-excursion
(newline 2)
(insert "endfunction")
(indent-according-to-mode))))
-
+
\f
;;; Menu
(defun octave-add-octave-menu ()
"Adds the `Octave' menu to the menu bar in Octave mode."
- (require 'easymenu)
+ (require 'easymenu)
(easy-menu-define octave-mode-menu-map octave-mode-map
"Menu keymap for Octave mode." octave-mode-menu)
(easy-menu-add octave-mode-menu-map octave-mode-map))
(defun octave-send-region (beg end)
"Send current region to the inferior Octave process."
(interactive "r")
- (inferior-octave t)
+ (inferior-octave t)
(let ((proc inferior-octave-process)
(string (buffer-substring-no-properties beg end))
line)
(display-buffer inferior-octave-buffer)))
(defun octave-send-block ()
- "Send current Octave block to the inferior Octave process."
+ "Send current Octave block to the inferior Octave process."
(interactive)
(save-excursion
(octave-mark-block)
(print-escape-newlines nil)
(opoint (point)))
(terpri)
- (prin1
+ (prin1
(save-excursion
(forward-sexp -1)
(inferior-octave-send-list-and-digest
octave-maintainer-address
(concat "Emacs version " emacs-version)
(list
+ 'octave-auto-indent
'octave-auto-newline
'octave-blink-matching-block
'octave-block-offset
(provide 'octave-mod)
+;;; arch-tag: 05f1ce09-be87-4c00-803e-4919ffa26c23
;;; octave-mod.el ends here