aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorEli Zaretskii2013-05-01 20:47:50 +0300
committerEli Zaretskii2013-05-01 20:47:50 +0300
commitb1cb82edff21abfefd68af18370dddfd8cc1fec0 (patch)
treefd8d8a1e1d99af024b52158a471457fc796238bc /lisp/progmodes
parent10f81f3ac90f98160f611787e20dcad96bb500e9 (diff)
parent2640d52e4e7873e41b0f0f1144177f84c345917e (diff)
downloademacs-b1cb82edff21abfefd68af18370dddfd8cc1fec0.tar.gz
emacs-b1cb82edff21abfefd68af18370dddfd8cc1fec0.zip
Merge from trunk.
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-engine.el78
-rw-r--r--lisp/progmodes/octave.el611
2 files changed, 361 insertions, 328 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 4fc270792fc..6a23da1f2cd 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6475,6 +6475,52 @@ comment at the start of cc-engine.el for more info."
6475 (c-go-list-forward) 6475 (c-go-list-forward)
6476 t))) 6476 t)))
6477 6477
6478(defun c-back-over-member-initializers ()
6479 ;; Test whether we are in a C++ member initializer list, and if so, go back
6480 ;; to the introducing ":", returning the position of the opening paren of
6481 ;; the function's arglist. Otherwise return nil, leaving point unchanged.
6482 (let ((here (point))
6483 (paren-state (c-parse-state))
6484 res)
6485
6486 (setq res
6487 (catch 'done
6488 (if (not (c-at-toplevel-p))
6489 (progn
6490 (while (not (c-at-toplevel-p))
6491 (goto-char (c-pull-open-brace paren-state)))
6492 (c-backward-syntactic-ws)
6493 (when (not (c-simple-skip-symbol-backward))
6494 (throw 'done nil))
6495 (c-backward-syntactic-ws))
6496 (c-backward-syntactic-ws)
6497 (when (memq (char-before) '(?\) ?}))
6498 (when (not (c-go-list-backward))
6499 (throw 'done nil))
6500 (c-backward-syntactic-ws))
6501 (when (c-simple-skip-symbol-backward)
6502 (c-backward-syntactic-ws)))
6503
6504 (while (eq (char-before) ?,)
6505 (backward-char)
6506 (c-backward-syntactic-ws)
6507
6508 (when (not (memq (char-before) '(?\) ?})))
6509 (throw 'done nil))
6510 (when (not (c-go-list-backward))
6511 (throw 'done nil))
6512 (c-backward-syntactic-ws)
6513 (when (not (c-simple-skip-symbol-backward))
6514 (throw 'done nil))
6515 (c-backward-syntactic-ws))
6516
6517 (and
6518 (eq (char-before) ?:)
6519 (c-just-after-func-arglist-p))))
6520
6521 (or res (goto-char here))
6522 res))
6523
6478 6524
6479;; Handling of large scale constructs like statements and declarations. 6525;; Handling of large scale constructs like statements and declarations.
6480 6526
@@ -9677,18 +9723,13 @@ comment at the start of cc-engine.el for more info."
9677 ;; 2007-11-09) 9723 ;; 2007-11-09)
9678 )))) 9724 ))))
9679 9725
9680 ;; CASE 5B: After a function header but before the body (or 9726 ;; CASE 5R: Member init list. (Used to be part of CASE 5B.1)
9681 ;; the ending semicolon if there's no body). 9727 ;; Note there is no limit on the backward search here, since member
9728 ;; init lists can, in practice, be very large.
9682 ((save-excursion 9729 ((save-excursion
9683 (when (setq placeholder (c-just-after-func-arglist-p 9730 (when (setq placeholder (c-back-over-member-initializers))
9684 (max lim (c-determine-limit 500))))
9685 (setq tmp-pos (point)))) 9731 (setq tmp-pos (point))))
9686 (cond 9732 (if (= (c-point 'bosws) (1+ tmp-pos))
9687
9688 ;; CASE 5B.1: Member init list.
9689 ((eq (char-after tmp-pos) ?:)
9690 (if (or (>= tmp-pos indent-point)
9691 (= (c-point 'bosws) (1+ tmp-pos)))
9692 (progn 9733 (progn
9693 ;; There is no preceding member init clause. 9734 ;; There is no preceding member init clause.
9694 ;; Indent relative to the beginning of indentation 9735 ;; Indent relative to the beginning of indentation
@@ -9701,6 +9742,23 @@ comment at the start of cc-engine.el for more info."
9701 (c-forward-syntactic-ws) 9742 (c-forward-syntactic-ws)
9702 (c-add-syntax 'member-init-cont (point)))) 9743 (c-add-syntax 'member-init-cont (point))))
9703 9744
9745 ;; CASE 5B: After a function header but before the body (or
9746 ;; the ending semicolon if there's no body).
9747 ((save-excursion
9748 (when (setq placeholder (c-just-after-func-arglist-p
9749 (max lim (c-determine-limit 500))))
9750 (setq tmp-pos (point))))
9751 (cond
9752
9753 ;; CASE 5B.1: Member init list.
9754 ((eq (char-after tmp-pos) ?:)
9755 ;; There is no preceding member init clause.
9756 ;; Indent relative to the beginning of indentation
9757 ;; for the topmost-intro line that contains the
9758 ;; prototype's open paren.
9759 (goto-char placeholder)
9760 (c-add-syntax 'member-init-intro (c-point 'boi)))
9761
9704 ;; CASE 5B.2: K&R arg decl intro 9762 ;; CASE 5B.2: K&R arg decl intro
9705 ((and c-recognize-knr-p 9763 ((and c-recognize-knr-p
9706 (c-in-knr-argdecl lim)) 9764 (c-in-knr-argdecl lim))
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index 0e540ea348a..4b02645e463 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -1,4 +1,4 @@
1;;; octave.el --- editing octave source files under emacs 1;;; octave.el --- editing octave source files under emacs -*- lexical-binding: t; -*-
2 2
3;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. 3;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc.
4 4
@@ -34,63 +34,42 @@
34;;; Code: 34;;; Code:
35(require 'comint) 35(require 'comint)
36 36
37;;; For emacs < 24.3.
38(require 'newcomment)
39(eval-when-compile
40 (unless (fboundp 'setq-local)
41 (defmacro setq-local (var val)
42 "Set variable VAR to value VAL in current buffer."
43 (list 'set (list 'make-local-variable (list 'quote var)) val))))
44
37(defgroup octave nil 45(defgroup octave nil
38 "Editing Octave code." 46 "Editing Octave code."
39 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) 47 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
40 :group 'languages) 48 :group 'languages)
41 49
42(defconst octave-maintainer-address 50(define-obsolete-function-alias 'octave-submit-bug-report
43 "Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>, bug-gnu-emacs@gnu.org" 51 'report-emacs-bug "24.4")
44 "Current maintainer of the Emacs Octave package.") 52
45 53(define-abbrev-table 'octave-abbrev-table nil
46(define-abbrev-table 'octave-abbrev-table
47 (mapcar (lambda (e) (append e '(nil 0 t)))
48 '(("`a" "all_va_args")
49 ("`b" "break")
50 ("`cs" "case")
51 ("`ca" "catch")
52 ("`c" "continue")
53 ("`el" "else")
54 ("`eli" "elseif")
55 ("`et" "end_try_catch")
56 ("`eu" "end_unwind_protect")
57 ("`ef" "endfor")
58 ("`efu" "endfunction")
59 ("`ei" "endif")
60 ("`es" "endswitch")
61 ("`ew" "endwhile")
62 ("`f" "for")
63 ("`fu" "function")
64 ("`gl" "global")
65 ("`gp" "gplot")
66 ("`gs" "gsplot")
67 ("`if" "if ()")
68 ("`o" "otherwise")
69 ("`rp" "replot")
70 ("`r" "return")
71 ("`s" "switch")
72 ("`t" "try")
73 ("`u" "until ()")
74 ("`up" "unwind_protect")
75 ("`upc" "unwind_protect_cleanup")
76 ("`w" "while ()")))
77 "Abbrev table for Octave's reserved words. 54 "Abbrev table for Octave's reserved words.
78Used in `octave-mode' and `inferior-octave-mode' buffers. 55Used in `octave-mode' and `inferior-octave-mode' buffers.")
79All Octave abbrevs start with a grave accent (`)."
80 :regexp "\\(?:[^`]\\|^\\)\\(\\(?:\\<\\|`\\)\\w+\\)\\W*")
81 56
82(defvar octave-comment-char ?# 57(defvar octave-comment-char ?#
83 "Character to start an Octave comment.") 58 "Character to start an Octave comment.")
59
84(defvar octave-comment-start 60(defvar octave-comment-start
85 (string octave-comment-char ?\s) 61 (string octave-comment-char ?\s)
86 "String to insert to start a new Octave in-line comment.") 62 "String to insert to start a new Octave in-line comment.")
63
87(defvar octave-comment-start-skip "\\s<+\\s-*" 64(defvar octave-comment-start-skip "\\s<+\\s-*"
88 "Regexp to match the start of an Octave comment up to its body.") 65 "Regexp to match the start of an Octave comment up to its body.")
89 66
90(defvar octave-begin-keywords 67(defvar octave-begin-keywords
91 '("do" "for" "function" "if" "switch" "try" "unwind_protect" "while")) 68 '("do" "for" "function" "if" "switch" "try" "unwind_protect" "while"))
69
92(defvar octave-else-keywords 70(defvar octave-else-keywords
93 '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup")) 71 '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup"))
72
94(defvar octave-end-keywords 73(defvar octave-end-keywords
95 '("endfor" "endfunction" "endif" "endswitch" "end_try_catch" 74 '("endfor" "endfunction" "endif" "endswitch" "end_try_catch"
96 "end_unwind_protect" "endwhile" "until" "end")) 75 "end_unwind_protect" "endwhile" "until" "end"))
@@ -109,37 +88,6 @@ All Octave abbrevs start with a grave accent (`)."
109 "which" "who" "whos") 88 "which" "who" "whos")
110 "Text functions in Octave.") 89 "Text functions in Octave.")
111 90
112(defvar octave-variables
113 '("DEFAULT_EXEC_PATH" "DEFAULT_LOADPATH"
114 "EDITOR" "EXEC_PATH" "F_DUPFD" "F_GETFD" "F_GETFL" "F_SETFD"
115 "F_SETFL" "I" "IMAGE_PATH" "Inf" "J"
116 "NaN" "OCTAVE_VERSION" "O_APPEND" "O_CREAT" "O_EXCL"
117 "O_NONBLOCK" "O_RDONLY" "O_RDWR" "O_TRUNC" "O_WRONLY" "PAGER" "PS1"
118 "PS2" "PS4" "PWD" "SEEK_CUR" "SEEK_END" "SEEK_SET" "__F_DUPFD__"
119 "__F_GETFD__" "__F_GETFL__" "__F_SETFD__" "__F_SETFL__" "__I__"
120 "__Inf__" "__J__" "__NaN__" "__OCTAVE_VERSION__" "__O_APPEND__"
121 "__O_CREAT__" "__O_EXCL__" "__O_NONBLOCK__" "__O_RDONLY__"
122 "__O_RDWR__" "__O_TRUNC__" "__O_WRONLY__" "__PWD__" "__SEEK_CUR__"
123 "__SEEK_END__" "__SEEK_SET__" "__argv__" "__e__" "__eps__"
124 "__i__" "__inf__" "__j__" "__nan__" "__pi__"
125 "__program_invocation_name__" "__program_name__" "__realmax__"
126 "__realmin__" "__stderr__" "__stdin__" "__stdout__" "ans" "argv"
127 "beep_on_error" "completion_append_char"
128 "crash_dumps_octave_core" "default_save_format"
129 "e" "echo_executing_commands" "eps"
130 "error_text" "gnuplot_binary" "history_file"
131 "history_size" "ignore_function_time_stamp"
132 "inf" "nan" "nargin" "output_max_field_width" "output_precision"
133 "page_output_immediately" "page_screen_output" "pi"
134 "print_answer_id_name" "print_empty_dimensions"
135 "program_invocation_name" "program_name"
136 "realmax" "realmin" "return_last_computed_value" "save_precision"
137 "saving_history" "sighup_dumps_octave_core" "sigterm_dumps_octave_core"
138 "silent_functions" "split_long_rows" "stderr" "stdin" "stdout"
139 "string_fill_char" "struct_levels_to_print"
140 "suppress_verbose_help_message")
141 "Builtin variables in Octave.")
142
143(defvar octave-function-header-regexp 91(defvar octave-function-header-regexp
144 (concat "^\\s-*\\_<\\(function\\)\\_>" 92 (concat "^\\s-*\\_<\\(function\\)\\_>"
145 "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>") 93 "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>")
@@ -156,14 +104,22 @@ parenthetical grouping.")
156 octave-text-functions)) 104 octave-text-functions))
157 "\\)\\_>") 105 "\\)\\_>")
158 'font-lock-keyword-face) 106 'font-lock-keyword-face)
107 ;; Note: 'end' also serves as the last index in an indexing expression.
108 ;; Ref: http://www.mathworks.com/help/matlab/ref/end.html
109 '("\\_<end\\_>" (0 (save-excursion
110 (condition-case nil
111 (progn
112 (goto-char (match-beginning 0))
113 (backward-up-list)
114 (unless (eq (char-after) ?\()
115 font-lock-keyword-face))
116 (error font-lock-keyword-face)))
117 t))
159 ;; Fontify all builtin operators. 118 ;; Fontify all builtin operators.
160 (cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)" 119 (cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)"
161 (if (boundp 'font-lock-builtin-face) 120 (if (boundp 'font-lock-builtin-face)
162 'font-lock-builtin-face 121 'font-lock-builtin-face
163 'font-lock-preprocessor-face)) 122 'font-lock-preprocessor-face))
164 ;; Fontify all builtin variables.
165 (cons (concat "\\_<" (regexp-opt octave-variables) "\\_>")
166 'font-lock-variable-name-face)
167 ;; Fontify all function declarations. 123 ;; Fontify all function declarations.
168 (list octave-function-header-regexp 124 (list octave-function-header-regexp
169 '(1 font-lock-keyword-face) 125 '(1 font-lock-keyword-face)
@@ -196,10 +152,8 @@ parenthetical grouping.")
196 152
197(defvar octave-mode-map 153(defvar octave-mode-map
198 (let ((map (make-sparse-keymap))) 154 (let ((map (make-sparse-keymap)))
199 (define-key map "`" 'octave-abbrev-start)
200 (define-key map "\e\n" 'octave-indent-new-comment-line) 155 (define-key map "\e\n" 'octave-indent-new-comment-line)
201 (define-key map "\M-\C-q" 'octave-indent-defun) 156 (define-key map "\M-\C-q" 'octave-indent-defun)
202 (define-key map "\C-c\C-b" 'octave-submit-bug-report)
203 (define-key map "\C-c\C-p" 'octave-previous-code-line) 157 (define-key map "\C-c\C-p" 'octave-previous-code-line)
204 (define-key map "\C-c\C-n" 'octave-next-code-line) 158 (define-key map "\C-c\C-n" 'octave-next-code-line)
205 (define-key map "\C-c\C-a" 'octave-beginning-of-line) 159 (define-key map "\C-c\C-a" 'octave-beginning-of-line)
@@ -208,6 +162,7 @@ parenthetical grouping.")
208 (define-key map "\C-c\M-\C-h" 'octave-mark-block) 162 (define-key map "\C-c\M-\C-h" 'octave-mark-block)
209 (define-key map "\C-c]" 'smie-close-block) 163 (define-key map "\C-c]" 'smie-close-block)
210 (define-key map "\C-c/" 'smie-close-block) 164 (define-key map "\C-c/" 'smie-close-block)
165 (define-key map "\C-c;" 'octave-update-function-file-comment)
211 (define-key map "\C-c\C-f" 'octave-insert-defun) 166 (define-key map "\C-c\C-f" 'octave-insert-defun)
212 (define-key map "\C-c\C-il" 'octave-send-line) 167 (define-key map "\C-c\C-il" 'octave-send-line)
213 (define-key map "\C-c\C-ib" 'octave-send-block) 168 (define-key map "\C-c\C-ib" 'octave-send-block)
@@ -242,7 +197,8 @@ parenthetical grouping.")
242 ["Close Block" smie-close-block t]) 197 ["Close Block" smie-close-block t])
243 ("Functions" 198 ("Functions"
244 ["Indent Function" octave-indent-defun t] 199 ["Indent Function" octave-indent-defun t]
245 ["Insert Function" octave-insert-defun t]) 200 ["Insert Function" octave-insert-defun t]
201 ["Update function file comment" octave-update-function-file-comment t])
246 "-" 202 "-"
247 ("Debug" 203 ("Debug"
248 ["Send Current Line" octave-send-line t] 204 ["Send Current Line" octave-send-line t]
@@ -255,16 +211,14 @@ parenthetical grouping.")
255 "-" 211 "-"
256 ["Indent Line" indent-according-to-mode t] 212 ["Indent Line" indent-according-to-mode t]
257 ["Complete Symbol" completion-at-point t] 213 ["Complete Symbol" completion-at-point t]
258 "-"
259 ["Toggle Abbrev Mode" abbrev-mode
260 :style toggle :selected abbrev-mode]
261 ["Toggle Auto-Fill Mode" auto-fill-mode 214 ["Toggle Auto-Fill Mode" auto-fill-mode
262 :style toggle :selected auto-fill-function] 215 :style toggle :selected auto-fill-function]
263 "-" 216 "-"
264 ["Submit Bug Report" octave-submit-bug-report t]
265 "-"
266 ["Describe Octave Mode" describe-mode t] 217 ["Describe Octave Mode" describe-mode t]
267 ["Lookup Octave Index" info-lookup-symbol t])) 218 ["Lookup Octave Index" info-lookup-symbol t]
219 ["Customize Octave" (customize-group 'octave) t]
220 "-"
221 ["Submit Bug Report" report-emacs-bug t]))
268 222
269(defvar octave-mode-syntax-table 223(defvar octave-mode-syntax-table
270 (let ((table (make-syntax-table))) 224 (let ((table (make-syntax-table)))
@@ -300,6 +254,12 @@ parenthetical grouping.")
300 table) 254 table)
301 "Syntax table in use in `octave-mode' buffers.") 255 "Syntax table in use in `octave-mode' buffers.")
302 256
257(defcustom octave-font-lock-texinfo-comment t
258 "Control whether to highlight the texinfo comment block."
259 :type 'boolean
260 :group 'octave
261 :version "24.4")
262
303(defcustom octave-blink-matching-block t 263(defcustom octave-blink-matching-block t
304 "Control the blinking of matching Octave block keywords. 264 "Control the blinking of matching Octave block keywords.
305Non-nil means show matching begin of block when inserting a space, 265Non-nil means show matching begin of block when inserting a space,
@@ -320,15 +280,17 @@ newline or semicolon after an else or end keyword."
320 "Extra indentation applied to Octave continuation lines." 280 "Extra indentation applied to Octave continuation lines."
321 :type 'integer 281 :type 'integer
322 :group 'octave) 282 :group 'octave)
283
323(eval-and-compile 284(eval-and-compile
324 (defconst octave-continuation-marker-regexp "\\\\\\|\\.\\.\\.")) 285 (defconst octave-continuation-marker-regexp "\\\\\\|\\.\\.\\."))
286
325(defvar octave-continuation-regexp 287(defvar octave-continuation-regexp
326 (concat "[^#%\n]*\\(" octave-continuation-marker-regexp 288 (concat "[^#%\n]*\\(" octave-continuation-marker-regexp
327 "\\)\\s-*\\(\\s<.*\\)?$")) 289 "\\)\\s-*\\(\\s<.*\\)?$"))
328(defcustom octave-continuation-string "\\" 290
329 "Character string used for Octave continuation lines. Normally \\." 291;; Char \ is considered a bad decision for continuing a line.
330 :type 'string 292(defconst octave-continuation-string "..."
331 :group 'octave) 293 "Character string used for Octave continuation lines.")
332 294
333(defvar octave-mode-imenu-generic-expression 295(defvar octave-mode-imenu-generic-expression
334 (list 296 (list
@@ -345,11 +307,13 @@ newline or semicolon after an else or end keyword."
345 "Non-nil means display `inferior-octave-buffer' after sending to it." 307 "Non-nil means display `inferior-octave-buffer' after sending to it."
346 :type 'boolean 308 :type 'boolean
347 :group 'octave) 309 :group 'octave)
310
348(defcustom octave-send-line-auto-forward t 311(defcustom octave-send-line-auto-forward t
349 "Control auto-forward after sending to the inferior Octave process. 312 "Control auto-forward after sending to the inferior Octave process.
350Non-nil means always go to the next Octave code line after sending." 313Non-nil means always go to the next Octave code line after sending."
351 :type 'boolean 314 :type 'boolean
352 :group 'octave) 315 :group 'octave)
316
353(defcustom octave-send-echo-input t 317(defcustom octave-send-echo-input t
354 "Non-nil means echo input sent to the inferior Octave process." 318 "Non-nil means echo input sent to the inferior Octave process."
355 :type 'boolean 319 :type 'boolean
@@ -462,11 +426,12 @@ Non-nil means always go to the next Octave code line after sending."
462 (forward-comment 1)) 426 (forward-comment 1))
463 (cond 427 (cond
464 ((and (looking-at "$\\|[%#]") 428 ((and (looking-at "$\\|[%#]")
465 (not (smie-rule-bolp)) 429 ;; Ignore it if it's within parentheses or if the newline does not end
466 ;; Ignore it if it's within parentheses. 430 ;; some preceding text.
467 (prog1 (let ((ppss (syntax-ppss))) 431 (prog1 (and (not (smie-rule-bolp))
468 (not (and (nth 1 ppss) 432 (let ((ppss (syntax-ppss)))
469 (eq ?\( (char-after (nth 1 ppss)))))) 433 (not (and (nth 1 ppss)
434 (eq ?\( (char-after (nth 1 ppss)))))))
470 (forward-comment (point-max)))) 435 (forward-comment (point-max))))
471 ;; Why bother distinguishing \n and ;? 436 ;; Why bother distinguishing \n and ;?
472 ";") ;;"\n" 437 ";") ;;"\n"
@@ -508,130 +473,59 @@ Non-nil means always go to the next Octave code line after sending."
508(define-derived-mode octave-mode prog-mode "Octave" 473(define-derived-mode octave-mode prog-mode "Octave"
509 "Major mode for editing Octave code. 474 "Major mode for editing Octave code.
510 475
511This mode makes it easier to write Octave code by helping with 476Octave is a high-level language, primarily intended for numerical
512indentation, doing some of the typing for you (with Abbrev mode) and by 477computations. It provides a convenient command line interface
513showing keywords, comments, strings, etc. in different faces (with 478for solving linear and nonlinear problems numerically. Function
514Font Lock mode on terminals that support it). 479definitions can also be stored in files and used in batch mode."
515 480 :abbrev-table octave-abbrev-table
516Octave itself is a high-level language, primarily intended for numerical
517computations. It provides a convenient command line interface for
518solving linear and nonlinear problems numerically. Function definitions
519can also be stored in files, and it can be used in a batch mode (which
520is why you need this mode!).
521
522The latest released version of Octave is always available via anonymous
523ftp from ftp.octave.org in the directory `/pub/octave'. Complete
524source and binaries for several popular systems are available.
525
526Type \\[list-abbrevs] to display the built-in abbrevs for Octave keywords.
527
528Keybindings
529===========
530
531\\{octave-mode-map}
532
533Variables you can use to customize Octave mode
534==============================================
535
536`octave-blink-matching-block'
537 Non-nil means show matching begin of block when inserting a space,
538 newline or semicolon after an else or end keyword. Default is t.
539
540`octave-block-offset'
541 Extra indentation applied to statements in block structures.
542 Default is 2.
543
544`octave-continuation-offset'
545 Extra indentation applied to Octave continuation lines.
546 Default is 4.
547
548`octave-continuation-string'
549 String used for Octave continuation lines.
550 Default is a backslash.
551
552`octave-send-echo-input'
553 Non-nil means always display `inferior-octave-buffer' after sending a
554 command to the inferior Octave process.
555
556`octave-send-line-auto-forward'
557 Non-nil means always go to the next unsent line of Octave code after
558 sending a line to the inferior Octave process.
559
560`octave-send-echo-input'
561 Non-nil means echo input sent to the inferior Octave process.
562
563Turning on Octave mode runs the hook `octave-mode-hook'.
564
565To begin using this mode for all `.m' files that you edit, add the
566following lines to your init file:
567
568 (add-to-list 'auto-mode-alist '(\"\\\\.m\\\\'\" . octave-mode))
569
570To automatically turn on the abbrev and auto-fill features,
571add the following lines to your init file as well:
572
573 (add-hook 'octave-mode-hook
574 (lambda ()
575 (abbrev-mode 1)
576 (auto-fill-mode 1)))
577
578To submit a problem report, enter \\[octave-submit-bug-report] from \
579an Octave mode buffer.
580This automatically sets up a mail buffer with version information
581already added. You just need to add a description of the problem,
582including a reproducible test case and send the message."
583 (setq local-abbrev-table octave-abbrev-table)
584 481
585 (smie-setup octave-smie-grammar #'octave-smie-rules 482 (smie-setup octave-smie-grammar #'octave-smie-rules
586 :forward-token #'octave-smie-forward-token 483 :forward-token #'octave-smie-forward-token
587 :backward-token #'octave-smie-backward-token) 484 :backward-token #'octave-smie-backward-token)
588 (set (make-local-variable 'smie-indent-basic) 'octave-block-offset) 485 (setq-local smie-indent-basic 'octave-block-offset)
589 486
590 (set (make-local-variable 'smie-blink-matching-triggers) 487 (setq-local smie-blink-matching-triggers
591 (cons ?\; smie-blink-matching-triggers)) 488 (cons ?\; smie-blink-matching-triggers))
592 (unless octave-blink-matching-block 489 (unless octave-blink-matching-block
593 (remove-hook 'post-self-insert-hook #'smie-blink-matching-open 'local)) 490 (remove-hook 'post-self-insert-hook #'smie-blink-matching-open 'local))
594 491
595 (set (make-local-variable 'electric-indent-chars) 492 (setq-local electric-indent-chars
596 (cons ?\; electric-indent-chars)) 493 (cons ?\; electric-indent-chars))
597 ;; IIUC matlab-mode takes the opposite approach: it makes RET insert 494 ;; IIUC matlab-mode takes the opposite approach: it makes RET insert
598 ;; a ";" at those places where it's correct (i.e. outside of parens). 495 ;; a ";" at those places where it's correct (i.e. outside of parens).
599 (set (make-local-variable 'electric-layout-rules) '((?\; . after))) 496 (setq-local electric-layout-rules '((?\; . after)))
600 497
601 (set (make-local-variable 'comment-start) octave-comment-start) 498 (setq-local comment-start octave-comment-start)
602 (set (make-local-variable 'comment-end) "") 499 (setq-local comment-end "")
603 ;; Don't set it here: it's not really a property of the language, 500 ;; Don't set it here: it's not really a property of the language,
604 ;; just a personal preference of the author. 501 ;; just a personal preference of the author.
605 ;; (set (make-local-variable 'comment-column) 32) 502 ;; (setq-local comment-column 32)
606 (set (make-local-variable 'comment-start-skip) "\\s<+\\s-*") 503 (setq-local comment-start-skip "\\s<+\\s-*")
607 (set (make-local-variable 'comment-add) 1) 504 (setq-local comment-add 1)
608 505
609 (set (make-local-variable 'parse-sexp-ignore-comments) t) 506 (setq-local parse-sexp-ignore-comments t)
610 (set (make-local-variable 'paragraph-start) 507 (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
611 (concat "\\s-*$\\|" page-delimiter)) 508 (setq-local paragraph-separate paragraph-start)
612 (set (make-local-variable 'paragraph-separate) paragraph-start) 509 (setq-local paragraph-ignore-fill-prefix t)
613 (set (make-local-variable 'paragraph-ignore-fill-prefix) t) 510 (setq-local fill-paragraph-function 'octave-fill-paragraph)
614 (set (make-local-variable 'fill-paragraph-function) 'octave-fill-paragraph)
615 ;; FIXME: Why disable it? 511 ;; FIXME: Why disable it?
616 ;; (set (make-local-variable 'adaptive-fill-regexp) nil) 512 ;; (setq-local adaptive-fill-regexp nil)
617 ;; Again, this is not a property of the language, don't set it here. 513 ;; Again, this is not a property of the language, don't set it here.
618 ;; (set (make-local-variable 'fill-column) 72) 514 ;; (setq fill-column 72)
619 (set (make-local-variable 'normal-auto-fill-function) 'octave-auto-fill) 515 (setq-local normal-auto-fill-function 'octave-auto-fill)
620 516
621 (set (make-local-variable 'font-lock-defaults) 517 (setq font-lock-defaults '(octave-font-lock-keywords))
622 '(octave-font-lock-keywords))
623 518
624 (set (make-local-variable 'syntax-propertize-function) 519 (setq-local syntax-propertize-function #'octave-syntax-propertize-function)
625 #'octave-syntax-propertize-function)
626 520
627 (set (make-local-variable 'imenu-generic-expression) 521 (setq imenu-generic-expression octave-mode-imenu-generic-expression)
628 octave-mode-imenu-generic-expression) 522 (setq imenu-case-fold-search nil)
629 (set (make-local-variable 'imenu-case-fold-search) nil)
630 523
631 (add-hook 'completion-at-point-functions 524 (add-hook 'completion-at-point-functions
632 'octave-completion-at-point-function nil t) 525 'octave-completion-at-point-function nil t)
633 (set (make-local-variable 'beginning-of-defun-function) 526 (add-hook 'before-save-hook 'octave-sync-function-file-names nil t)
634 'octave-beginning-of-defun) 527 (setq-local beginning-of-defun-function 'octave-beginning-of-defun)
528 (and octave-font-lock-texinfo-comment (octave-font-lock-texinfo-comment))
635 529
636 (easy-menu-add octave-mode-menu)) 530 (easy-menu-add octave-mode-menu))
637 531
@@ -652,6 +546,13 @@ including a reproducible test case and send the message."
652 :type 'regexp 546 :type 'regexp
653 :group 'octave) 547 :group 'octave)
654 548
549(defcustom inferior-octave-prompt-read-only comint-prompt-read-only
550 "If non-nil, the Octave prompt is read only.
551See `comint-prompt-read-only' for details."
552 :type 'boolean
553 :group 'octave
554 :version "24.4")
555
655(defcustom inferior-octave-startup-file nil 556(defcustom inferior-octave-startup-file nil
656 "Name of the inferior Octave startup file. 557 "Name of the inferior Octave startup file.
657The contents of this file are sent to the inferior Octave process on 558The contents of this file are sent to the inferior Octave process on
@@ -696,28 +597,12 @@ mode, set this to (\"-q\" \"--traditional\")."
696 ;; Could certainly do more font locking in inferior Octave ... 597 ;; Could certainly do more font locking in inferior Octave ...
697 "Additional expressions to highlight in Inferior Octave mode.") 598 "Additional expressions to highlight in Inferior Octave mode.")
698 599
699
700;;; Compatibility functions
701(if (not (fboundp 'comint-line-beginning-position))
702 ;; comint-line-beginning-position is defined in Emacs 21
703 (defun comint-line-beginning-position ()
704 "Returns the buffer position of the beginning of the line, after any prompt.
705The prompt is assumed to be any text at the beginning of the line matching
706the regular expression `comint-prompt-regexp', a buffer local variable."
707 (save-excursion (comint-bol nil) (point))))
708
709
710(defvar inferior-octave-output-list nil) 600(defvar inferior-octave-output-list nil)
711(defvar inferior-octave-output-string nil) 601(defvar inferior-octave-output-string nil)
712(defvar inferior-octave-receive-in-progress nil) 602(defvar inferior-octave-receive-in-progress nil)
713 603
714(defvar inferior-octave-startup-hook nil) 604(define-obsolete-variable-alias 'inferior-octave-startup-hook
715 605 'inferior-octave-mode-hook "24.4")
716(defvar inferior-octave-complete-impossible nil
717 "Non-nil means that `inferior-octave-complete' is impossible.")
718
719(defvar inferior-octave-has-built-in-variables nil
720 "Non-nil means that Octave has built-in variables.")
721 606
722(defvar inferior-octave-dynamic-complete-functions 607(defvar inferior-octave-dynamic-complete-functions
723 '(inferior-octave-completion-at-point comint-filename-completion) 608 '(inferior-octave-completion-at-point comint-filename-completion)
@@ -728,31 +613,25 @@ in the Inferior Octave buffer.")
728(defvar info-lookup-mode) 613(defvar info-lookup-mode)
729 614
730(define-derived-mode inferior-octave-mode comint-mode "Inferior Octave" 615(define-derived-mode inferior-octave-mode comint-mode "Inferior Octave"
731 "Major mode for interacting with an inferior Octave process. 616 "Major mode for interacting with an inferior Octave process."
732Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs 617 :abbrev-table octave-abbrev-table
733buffer. 618 (setq comint-prompt-regexp inferior-octave-prompt)
734 619
735Entry to this mode successively runs the hooks `comint-mode-hook' and 620 (setq-local comment-start octave-comment-start)
736`inferior-octave-mode-hook'." 621 (setq-local comment-end "")
737 (setq comint-prompt-regexp inferior-octave-prompt 622 (setq comment-column 32)
738 mode-line-process '(":%s") 623 (setq-local comment-start-skip octave-comment-start-skip)
739 local-abbrev-table octave-abbrev-table)
740 624
741 (set (make-local-variable 'comment-start) octave-comment-start) 625 (setq font-lock-defaults '(inferior-octave-font-lock-keywords nil nil))
742 (set (make-local-variable 'comment-end) "")
743 (set (make-local-variable 'comment-column) 32)
744 (set (make-local-variable 'comment-start-skip) octave-comment-start-skip)
745 626
746 (set (make-local-variable 'font-lock-defaults) 627 (setq info-lookup-mode 'octave-mode)
747 '(inferior-octave-font-lock-keywords nil nil))
748
749 (set (make-local-variable 'info-lookup-mode) 'octave-mode)
750 628
751 (setq comint-input-ring-file-name 629 (setq comint-input-ring-file-name
752 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist") 630 (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist")
753 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)) 631 comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024))
754 (set (make-local-variable 'comint-dynamic-complete-functions) 632 (setq-local comint-dynamic-complete-functions
755 inferior-octave-dynamic-complete-functions) 633 inferior-octave-dynamic-complete-functions)
634 (setq-local comint-prompt-read-only inferior-octave-prompt-read-only)
756 (add-hook 'comint-input-filter-functions 635 (add-hook 'comint-input-filter-functions
757 'inferior-octave-directory-tracker nil t) 636 'inferior-octave-directory-tracker nil t)
758 (comint-read-input-ring t)) 637 (comint-read-input-ring t))
@@ -816,20 +695,11 @@ startup file, `~/.emacs-octave'."
816 'identity inferior-octave-output-list "\n") 695 'identity inferior-octave-output-list "\n")
817 "\n")))) 696 "\n"))))
818 697
819 ;; Find out whether Octave has built-in variables.
820 (inferior-octave-send-list-and-digest
821 (list "exist \"LOADPATH\"\n"))
822 (setq inferior-octave-has-built-in-variables
823 (string-match "101$" (car inferior-octave-output-list)))
824
825 ;; An empty secondary prompt, as e.g. obtained by '--braindead', 698 ;; An empty secondary prompt, as e.g. obtained by '--braindead',
826 ;; means trouble. 699 ;; means trouble.
827 (inferior-octave-send-list-and-digest (list "PS2\n")) 700 (inferior-octave-send-list-and-digest (list "PS2\n"))
828 (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list)) 701 (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list))
829 (inferior-octave-send-list-and-digest 702 (inferior-octave-send-list-and-digest (list "PS2 (\"> \");\n")))
830 (list (if inferior-octave-has-built-in-variables
831 "PS2 = \"> \"\n"
832 "PS2 (\"> \");\n"))))
833 703
834 ;; O.k., now we are ready for the Inferior Octave startup commands. 704 ;; O.k., now we are ready for the Inferior Octave startup commands.
835 (let* (commands 705 (let* (commands
@@ -840,9 +710,7 @@ startup file, `~/.emacs-octave'."
840 (list "more off;\n" 710 (list "more off;\n"
841 (if (not (string-equal 711 (if (not (string-equal
842 inferior-octave-output-string ">> ")) 712 inferior-octave-output-string ">> "))
843 (if inferior-octave-has-built-in-variables 713 "PS1 (\"\\\\s> \");\n")
844 "PS1=\"\\\\s> \";\n"
845 "PS1 (\"\\\\s> \");\n"))
846 (if (file-exists-p file) 714 (if (file-exists-p file)
847 (format "source (\"%s\");\n" file)))) 715 (format "source (\"%s\");\n" file))))
848 (inferior-octave-send-list-and-digest commands)) 716 (inferior-octave-send-list-and-digest commands))
@@ -853,28 +721,20 @@ startup file, `~/.emacs-octave'."
853 'identity inferior-octave-output-list "\n") 721 'identity inferior-octave-output-list "\n")
854 "\n")) 722 "\n"))
855 inferior-octave-output-string)) 723 inferior-octave-output-string))
856 ;; Next, we check whether Octave supports `completion_matches' ...
857 (inferior-octave-send-list-and-digest
858 (list "exist \"completion_matches\"\n"))
859 (setq inferior-octave-complete-impossible
860 (not (string-match "5$" (car inferior-octave-output-list))))
861 724
862 ;; And finally, everything is back to normal. 725 ;; And finally, everything is back to normal.
863 (set-process-filter proc 'inferior-octave-output-filter) 726 (set-process-filter proc 'inferior-octave-output-filter)
864 (run-hooks 'inferior-octave-startup-hook)
865 (run-hooks 'inferior-octave-startup-hook)
866 ;; Just in case, to be sure a cd in the startup file 727 ;; Just in case, to be sure a cd in the startup file
867 ;; won't have detrimental effects. 728 ;; won't have detrimental effects.
868 (inferior-octave-resync-dirs))) 729 (inferior-octave-resync-dirs)))
869 730
870(defun inferior-octave-completion-table () 731(defun inferior-octave-completion-table ()
871 (unless inferior-octave-complete-impossible 732 (completion-table-dynamic
872 (completion-table-dynamic 733 (lambda (command)
873 (lambda (command) 734 (inferior-octave-send-list-and-digest
874 (inferior-octave-send-list-and-digest 735 (list (concat "completion_matches (\"" command "\");\n")))
875 (list (concat "completion_matches (\"" command "\");\n"))) 736 (sort (delete-dups inferior-octave-output-list)
876 (sort (delete-dups inferior-octave-output-list) 737 'string-lessp))))
877 'string-lessp)))))
878 738
879(defun inferior-octave-completion-at-point () 739(defun inferior-octave-completion-at-point ()
880 "Return the data to complete the Octave symbol at point." 740 "Return the data to complete the Octave symbol at point."
@@ -883,13 +743,8 @@ startup file, `~/.emacs-octave'."
883 (save-excursion 743 (save-excursion
884 (skip-syntax-backward "w_" (comint-line-beginning-position)) 744 (skip-syntax-backward "w_" (comint-line-beginning-position))
885 (point)))) 745 (point))))
886 (cond ((eq start end) nil) 746 (when (> end start)
887 (inferior-octave-complete-impossible 747 (list start end (inferior-octave-completion-table)))))
888 (message (concat
889 "Your Octave does not have `completion_matches'. "
890 "Please upgrade to version 2.X."))
891 nil)
892 (t (list start end (inferior-octave-completion-table))))))
893 748
894(define-obsolete-function-alias 'inferior-octave-complete 749(define-obsolete-function-alias 'inferior-octave-complete
895 'completion-at-point "24.1") 750 'completion-at-point "24.1")
@@ -989,19 +844,17 @@ directory and makes this the current buffer's default directory."
989 844
990;;; Miscellaneous useful functions 845;;; Miscellaneous useful functions
991 846
992(defsubst octave-in-comment-p () 847(defun octave-in-comment-p ()
993 "Return t if point is inside an Octave comment." 848 "Return non-nil if point is inside an Octave comment."
994 (nth 4 (syntax-ppss))) 849 (nth 4 (syntax-ppss)))
995 850
996(defsubst octave-in-string-p () 851(defun octave-in-string-p ()
997 "Return t if point is inside an Octave string." 852 "Return non-nil if point is inside an Octave string."
998 (nth 3 (syntax-ppss))) 853 (nth 3 (syntax-ppss)))
999 854
1000(defsubst octave-not-in-string-or-comment-p () 855(defun octave-in-string-or-comment-p ()
1001 "Return t if point is not inside an Octave string or comment." 856 "Return non-nil if point is inside an Octave string or comment."
1002 (let ((pps (syntax-ppss))) 857 (nth 8 (syntax-ppss)))
1003 (not (or (nth 3 pps) (nth 4 pps)))))
1004
1005 858
1006(defun octave-looking-at-kw (regexp) 859(defun octave-looking-at-kw (regexp)
1007 "Like `looking-at', but sets `case-fold-search' nil." 860 "Like `looking-at', but sets `case-fold-search' nil."
@@ -1016,6 +869,163 @@ directory and makes this the current buffer's default directory."
1016 nil 869 nil
1017 (delete-horizontal-space) 870 (delete-horizontal-space)
1018 (insert (concat " " octave-continuation-string)))) 871 (insert (concat " " octave-continuation-string))))
872
873(defun octave-function-file-p ()
874 "Return non-nil if the first token is \"function\".
875The value is (START END NAME-START NAME-END) of the function."
876 (save-excursion
877 (goto-char (point-min))
878 (when (equal (funcall smie-forward-token-function) "function")
879 (forward-word -1)
880 (let* ((start (point))
881 (end (progn (forward-sexp 1) (point)))
882 (name (when (progn
883 (goto-char start)
884 (re-search-forward octave-function-header-regexp
885 end t))
886 (list (match-beginning 3) (match-end 3)))))
887 (cons start (cons end name))))))
888
889;; Like forward-comment but stop at non-comment blank
890(defun octave-skip-comment-forward (limit)
891 (let ((ppss (syntax-ppss)))
892 (if (nth 4 ppss)
893 (goto-char (nth 8 ppss))
894 (goto-char (or (comment-search-forward limit t) (point)))))
895 (while (and (< (point) limit) (looking-at-p "\\s<"))
896 (forward-comment 1)))
897
898;;; First non-copyright comment block
899(defun octave-function-file-comment ()
900 "Beginning and end positions of the function file comment."
901 (save-excursion
902 (goto-char (point-min))
903 ;; Copyright block: octave/libinterp/parse-tree/lex.ll around line 1634
904 (while (save-excursion
905 (when (comment-search-forward (point-max) t)
906 (when (eq (char-after) ?\{) ; case of block comment
907 (forward-char 1))
908 (skip-syntax-forward "-")
909 (let ((case-fold-search t))
910 (looking-at-p "\\(?:copyright\\|author\\)\\_>"))))
911 (octave-skip-comment-forward (point-max)))
912 (let ((beg (comment-search-forward (point-max) t)))
913 (when beg
914 (goto-char beg)
915 (octave-skip-comment-forward (point-max))
916 (list beg (point))))))
917
918(defun octave-sync-function-file-names ()
919 "Ensure function name agree with function file name.
920See Info node `(octave)Function Files'."
921 (interactive)
922 (when buffer-file-name
923 (pcase-let ((`(,start ,_end ,name-start ,name-end)
924 (octave-function-file-p)))
925 (when (and start name-start)
926 (let* ((func (buffer-substring name-start name-end))
927 (file (file-name-sans-extension
928 (file-name-nondirectory buffer-file-name)))
929 (help-form (format "\
930a: Use function name `%s'
931b: Use file name `%s'
932q: Don't fix\n" func file))
933 (c (unless (equal file func)
934 (save-window-excursion
935 (help-form-show)
936 (read-char-choice
937 "Which name to use? (a/b/q) " '(?a ?b ?q))))))
938 (pcase c
939 (`?a (let ((newname (expand-file-name
940 (concat func (file-name-extension
941 buffer-file-name t)))))
942 (when (or (not (file-exists-p newname))
943 (yes-or-no-p
944 (format "Target file %s exists; proceed? " newname)))
945 (when (file-exists-p buffer-file-name)
946 (rename-file buffer-file-name newname t))
947 (set-visited-file-name newname))))
948 (`?b (save-excursion
949 (goto-char name-start)
950 (delete-region name-start name-end)
951 (insert file)))))))))
952
953(defun octave-update-function-file-comment (beg end)
954 "Query replace function names in function file comment."
955 (interactive
956 (progn
957 (barf-if-buffer-read-only)
958 (if (use-region-p)
959 (list (region-beginning) (region-end))
960 (or (octave-function-file-comment)
961 (error "No function file comment found")))))
962 (save-excursion
963 (let* ((bounds (or (octave-function-file-p)
964 (error "Not in a function file buffer")))
965 (func (if (cddr bounds)
966 (apply #'buffer-substring (cddr bounds))
967 (error "Function name not found")))
968 (old-func (progn
969 (goto-char beg)
970 (when (re-search-forward
971 "[=}]\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>"
972 (min (line-end-position 4) end)
973 t)
974 (match-string 1))))
975 (old-func (read-string (format (if old-func
976 "Name to replace (default %s): "
977 "Name to replace: ")
978 old-func)
979 nil nil old-func)))
980 (if (and func old-func (not (equal func old-func)))
981 (perform-replace old-func func 'query
982 nil 'delimited nil nil beg end)
983 (message "Function names match")))))
984
985;; Adapted from texinfo-font-lock-keywords
986(defvar octave-texinfo-font-lock-keywords
987 `(("@\\([a-zA-Z]+\\|[^ \t\n]\\)" 1 font-lock-keyword-face prepend) ;commands
988 ("^\\*\\([^\n:]*\\)" 1 font-lock-function-name-face prepend) ;menu items
989 ("@\\(emph\\|i\\|sc\\){\\([^}]+\\)" 2 'italic prepend)
990 ("@\\(strong\\|b\\){\\([^}]+\\)" 2 'bold prepend)
991 ("@\\(kbd\\|key\\|url\\|uref\\){\\([^}]+\\)"
992 2 font-lock-string-face prepend)
993 ("@\\(file\\|email\\){\\([^}]+\\)" 2 font-lock-string-face prepend)
994 ("@\\(samp\\|code\\|var\\|math\\|env\\|command\\|option\\){\\([^}]+\\)"
995 2 font-lock-variable-name-face prepend)
996 ("@\\(cite\\|x?ref\\|pxref\\|dfn\\|inforef\\){\\([^}]+\\)"
997 2 font-lock-constant-face prepend)
998 ("@\\(anchor\\){\\([^}]+\\)" 2 font-lock-type-face prepend)
999 ("@\\(dmn\\|acronym\\|value\\){\\([^}]+\\)"
1000 2 font-lock-builtin-face prepend)
1001 ("@\\(end\\|itemx?\\) +\\(.+\\)" 2 font-lock-keyword-face prepend))
1002 "Additional keywords to highlight in texinfo comment block.")
1003
1004(defface octave-function-comment-block
1005 '((t (:inherit font-lock-doc-face)))
1006 "Face used to highlight function comment block."
1007 :group 'octave)
1008
1009(defun octave-font-lock-texinfo-comment ()
1010 (font-lock-add-keywords
1011 nil
1012 '(((lambda (limit)
1013 (while (and (search-forward "-*- texinfo -*-" limit t)
1014 (octave-in-comment-p))
1015 (let ((beg (nth 8 (syntax-ppss)))
1016 (end (progn
1017 (octave-skip-comment-forward (point-max))
1018 (point))))
1019 (put-text-property beg end 'font-lock-multiline t)
1020 (font-lock-prepend-text-property
1021 beg end 'face 'octave-function-comment-block)
1022 (dolist (kw octave-texinfo-font-lock-keywords)
1023 (goto-char beg)
1024 (while (re-search-forward (car kw) end 'move)
1025 (font-lock-apply-highlight (cdr kw))))))
1026 nil)))
1027 'append))
1028
1019 1029
1020;;; Indentation 1030;;; Indentation
1021 1031
@@ -1149,8 +1159,8 @@ Returns t unless search stops at the beginning or end of the buffer."
1149 (while (and (/= arg 0) 1159 (while (and (/= arg 0)
1150 (setq found 1160 (setq found
1151 (re-search-backward "\\_<function\\_>" inc))) 1161 (re-search-backward "\\_<function\\_>" inc)))
1152 (if (octave-not-in-string-or-comment-p) 1162 (unless (octave-in-string-or-comment-p)
1153 (setq arg (- arg inc)))) 1163 (setq arg (- arg inc))))
1154 (if found 1164 (if found
1155 (progn 1165 (progn
1156 (and (< inc 0) (goto-char (match-beginning 0))) 1166 (and (< inc 0) (goto-char (match-beginning 0)))
@@ -1303,34 +1313,17 @@ otherwise."
1303 (process-live-p inferior-octave-process) 1313 (process-live-p inferior-octave-process)
1304 (inferior-octave-completion-table)) 1314 (inferior-octave-completion-table))
1305 (append octave-reserved-words 1315 (append octave-reserved-words
1306 octave-text-functions 1316 octave-text-functions)))))
1307 octave-variables)))))
1308 1317
1309(define-obsolete-function-alias 'octave-complete-symbol 1318(define-obsolete-function-alias 'octave-complete-symbol
1310 'completion-at-point "24.1") 1319 'completion-at-point "24.1")
1311 1320
1312;;; Electric characters && friends 1321;;; Electric characters && friends
1313
1314(defun octave-abbrev-start ()
1315 "Start entering an Octave abbreviation.
1316If Abbrev mode is turned on, typing ` (grave accent) followed by ? or
1317\\[help-command] lists all Octave abbrevs. Any other key combination is
1318executed normally.
1319Note that all Octave mode abbrevs start with a grave accent."
1320 (interactive)
1321 (self-insert-command 1)
1322 (when abbrev-mode
1323 (set-temporary-overlay-map
1324 (let ((map (make-sparse-keymap)))
1325 (define-key map [??] 'list-abbrevs)
1326 (define-key map (vector help-char) 'list-abbrevs)
1327 map))))
1328
1329(define-skeleton octave-insert-defun 1322(define-skeleton octave-insert-defun
1330 "Insert an Octave function skeleton. 1323 "Insert an Octave function skeleton.
1331Prompt for the function's name, arguments and return values (to be 1324Prompt for the function's name, arguments and return values (to be
1332entered without parens)." 1325entered without parens)."
1333 (let* ((defname (substring (buffer-name) 0 -2)) 1326 (let* ((defname (file-name-sans-extension (buffer-name)))
1334 (name (read-string (format "Function name (default %s): " defname) 1327 (name (read-string (format "Function name (default %s): " defname)
1335 nil nil defname)) 1328 nil nil defname))
1336 (args (read-string "Arguments: ")) 1329 (args (read-string "Arguments: "))
@@ -1342,10 +1335,11 @@ entered without parens)."
1342 (t (concat vals " = "))) 1335 (t (concat vals " = ")))
1343 name 1336 name
1344 args)) 1337 args))
1345 \n "function " > str \n \n 1338 \n octave-block-comment-start "usage: " str \n
1346 octave-block-comment-start "usage: " str \n 1339 octave-block-comment-start '(delete-horizontal-space) \n
1347 octave-block-comment-start \n octave-block-comment-start 1340 octave-block-comment-start '(delete-horizontal-space) \n
1348 \n _ \n 1341 "function " > str \n
1342 _ \n
1349 "endfunction" > \n) 1343 "endfunction" > \n)
1350 1344
1351;;; Communication with the inferior Octave process 1345;;; Communication with the inferior Octave process
@@ -1450,26 +1444,7 @@ code line."
1450 "\n"))) 1444 "\n")))
1451 (mapconcat 'identity inferior-octave-output-list "\n"))) 1445 (mapconcat 'identity inferior-octave-output-list "\n")))
1452 (terpri))) 1446 (terpri)))
1453 1447
1454;;; Bug reporting
1455(defun octave-submit-bug-report ()
1456 "Submit a bug report on the Emacs Octave package via mail."
1457 (interactive)
1458 (require 'reporter)
1459 (and
1460 (y-or-n-p "Do you want to submit a bug report? ")
1461 (reporter-submit-bug-report
1462 octave-maintainer-address
1463 (concat "Emacs version " emacs-version)
1464 (list
1465 'octave-blink-matching-block
1466 'octave-block-offset
1467 'octave-comment-char
1468 'octave-continuation-offset
1469 'octave-continuation-string
1470 'octave-send-echo-input
1471 'octave-send-line-auto-forward
1472 'octave-send-show-buffer))))
1473 1448
1474(provide 'octave) 1449(provide 'octave)
1475;;; octave.el ends here 1450;;; octave.el ends here