diff options
| author | Eli Zaretskii | 2013-05-01 20:47:50 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-05-01 20:47:50 +0300 |
| commit | b1cb82edff21abfefd68af18370dddfd8cc1fec0 (patch) | |
| tree | fd8d8a1e1d99af024b52158a471457fc796238bc /lisp/progmodes | |
| parent | 10f81f3ac90f98160f611787e20dcad96bb500e9 (diff) | |
| parent | 2640d52e4e7873e41b0f0f1144177f84c345917e (diff) | |
| download | emacs-b1cb82edff21abfefd68af18370dddfd8cc1fec0.tar.gz emacs-b1cb82edff21abfefd68af18370dddfd8cc1fec0.zip | |
Merge from trunk.
Diffstat (limited to 'lisp/progmodes')
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 78 | ||||
| -rw-r--r-- | lisp/progmodes/octave.el | 611 |
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. |
| 78 | Used in `octave-mode' and `inferior-octave-mode' buffers. | 55 | Used in `octave-mode' and `inferior-octave-mode' buffers.") |
| 79 | All 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. |
| 305 | Non-nil means show matching begin of block when inserting a space, | 265 | Non-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. |
| 350 | Non-nil means always go to the next Octave code line after sending." | 313 | Non-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 | ||
| 511 | This mode makes it easier to write Octave code by helping with | 476 | Octave is a high-level language, primarily intended for numerical |
| 512 | indentation, doing some of the typing for you (with Abbrev mode) and by | 477 | computations. It provides a convenient command line interface |
| 513 | showing keywords, comments, strings, etc. in different faces (with | 478 | for solving linear and nonlinear problems numerically. Function |
| 514 | Font Lock mode on terminals that support it). | 479 | definitions can also be stored in files and used in batch mode." |
| 515 | 480 | :abbrev-table octave-abbrev-table | |
| 516 | Octave itself is a high-level language, primarily intended for numerical | ||
| 517 | computations. It provides a convenient command line interface for | ||
| 518 | solving linear and nonlinear problems numerically. Function definitions | ||
| 519 | can also be stored in files, and it can be used in a batch mode (which | ||
| 520 | is why you need this mode!). | ||
| 521 | |||
| 522 | The latest released version of Octave is always available via anonymous | ||
| 523 | ftp from ftp.octave.org in the directory `/pub/octave'. Complete | ||
| 524 | source and binaries for several popular systems are available. | ||
| 525 | |||
| 526 | Type \\[list-abbrevs] to display the built-in abbrevs for Octave keywords. | ||
| 527 | |||
| 528 | Keybindings | ||
| 529 | =========== | ||
| 530 | |||
| 531 | \\{octave-mode-map} | ||
| 532 | |||
| 533 | Variables 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 | |||
| 563 | Turning on Octave mode runs the hook `octave-mode-hook'. | ||
| 564 | |||
| 565 | To begin using this mode for all `.m' files that you edit, add the | ||
| 566 | following lines to your init file: | ||
| 567 | |||
| 568 | (add-to-list 'auto-mode-alist '(\"\\\\.m\\\\'\" . octave-mode)) | ||
| 569 | |||
| 570 | To automatically turn on the abbrev and auto-fill features, | ||
| 571 | add 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 | |||
| 578 | To submit a problem report, enter \\[octave-submit-bug-report] from \ | ||
| 579 | an Octave mode buffer. | ||
| 580 | This automatically sets up a mail buffer with version information | ||
| 581 | already added. You just need to add a description of the problem, | ||
| 582 | including 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. | ||
| 551 | See `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. |
| 657 | The contents of this file are sent to the inferior Octave process on | 558 | The 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. | ||
| 705 | The prompt is assumed to be any text at the beginning of the line matching | ||
| 706 | the 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." |
| 732 | Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs | 617 | :abbrev-table octave-abbrev-table |
| 733 | buffer. | 618 | (setq comint-prompt-regexp inferior-octave-prompt) |
| 734 | 619 | ||
| 735 | Entry 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\". | ||
| 875 | The 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. | ||
| 920 | See 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 "\ | ||
| 930 | a: Use function name `%s' | ||
| 931 | b: Use file name `%s' | ||
| 932 | q: 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. | ||
| 1316 | If Abbrev mode is turned on, typing ` (grave accent) followed by ? or | ||
| 1317 | \\[help-command] lists all Octave abbrevs. Any other key combination is | ||
| 1318 | executed normally. | ||
| 1319 | Note 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. |
| 1331 | Prompt for the function's name, arguments and return values (to be | 1324 | Prompt for the function's name, arguments and return values (to be |
| 1332 | entered without parens)." | 1325 | entered 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 |