diff options
| author | Richard M. Stallman | 1996-04-21 01:39:51 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1996-04-21 01:39:51 +0000 |
| commit | 8ca3cd44629036e51f108e0e82cdd3c8a6778e1d (patch) | |
| tree | 9b8a5ae4371533733898d18bc0458a8c217c4f84 /lisp/progmodes | |
| parent | c80718ccb9e66011245253acb3c7df2c6199bfec (diff) | |
| download | emacs-8ca3cd44629036e51f108e0e82cdd3c8a6778e1d.tar.gz emacs-8ca3cd44629036e51f108e0e82cdd3c8a6778e1d.zip | |
(simula-tab-always-indent, simula-indent-level)
(simula-substatement-offset, simula-continued-statement-offset)
(simula-label-offset, simula-if-indent, simula-inspect-indent)
(simula-electric-indent, simula-abbrev-keyword, simula-abbrev-stdproc):
Added default constants.
(simula-emacs-features): new constant to hold information
on which flavor if emacs is running (from cc-mode.el).
(simula-mode-menu): Menu definition for Lucid Emacs
(simula-mode-map): Bound new command simula-indent-exp to C-M-q
and added lots of commands to [menu-bar].
(simula-popup-menu): New function for Lucid menus.
(simula-keep-region-active): New function for Lucid menus.
(simula-indent-exp): New command that indents a whole expression.
(simula-indent-line): New strategies for finding the right amount to indent.
(simula-skip-comment-backward): Added optional parameter stop-at-end
to stop at the first END statement.
(simula-expand-stdproc): Added abbrev expansion to verbatim copy
of abbrev table, same for function simula-expand-keyword.
(simula-search-backward): Added Doc string, and lots of error checking.
(simula-search-forward): Added Doc string, and lots of error checking.
Added hilit19 config code.
(simula-version): New variable and function to report value.
(simula-submit-bug-report): New function to submit bug report.
Diffstat (limited to 'lisp/progmodes')
| -rw-r--r-- | lisp/progmodes/simula.el | 592 |
1 files changed, 492 insertions, 100 deletions
diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el index 45cb24b331d..6661a109bb5 100644 --- a/lisp/progmodes/simula.el +++ b/lisp/progmodes/simula.el | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | ;;; simula.el --- SIMULA 87 code editing commands for Emacs | 1 | ;;; simula.el --- SIMULA 87 code editing commands for Emacs |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1992 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1994 Hans Henrik Eriksen |
| 4 | ;; Copyright (C) 1992, 1994 Free Software Foundation, Inc. | ||
| 4 | 5 | ||
| 5 | ;; Author: Hans Henrik Eriksen <hhe@ifi.uio.no> | 6 | ;; Author: Hans Henrik Eriksen <hhe@ifi.uio.no> |
| 6 | ;; Maintainer: simula-mode@ifi.uio.no | 7 | ;; Maintainer: simula-mode@ifi.uio.no |
| 7 | ;; Version: 0.992 | 8 | ;; Version: 0.994 |
| 8 | ;; Adapted-By: ESR | 9 | ;; Adapted-By: ESR |
| 9 | ;; Keywords: languages | 10 | ;; Keywords: languages |
| 10 | 11 | ||
| @@ -37,50 +38,92 @@ | |||
| 37 | 38 | ||
| 38 | ;;; Code: | 39 | ;;; Code: |
| 39 | 40 | ||
| 40 | (provide 'simula-mode) | 41 | |
| 42 | (defconst simula-tab-always-indent-default nil | ||
| 43 | "Non-nil means TAB in SIMULA mode should always reindent the current line. | ||
| 44 | Otherwise TAB indents only when point is within | ||
| 45 | the run of whitespace at the beginning of the line.") | ||
| 41 | 46 | ||
| 42 | (defconst simula-tab-always-indent nil | 47 | (defvar simula-tab-always-indent simula-tab-always-indent-default |
| 43 | "*Non-nil means TAB in SIMULA mode should always reindent the current line. | 48 | "*Non-nil means TAB in SIMULA mode should always reindent the current line. |
| 44 | Otherwise TAB indents only when point is within | 49 | Otherwise TAB indents only when point is within |
| 45 | the run of whitespace at the beginning of the line.") | 50 | the run of whitespace at the beginning of the line.") |
| 46 | 51 | ||
| 47 | (defconst simula-indent-level 3 | 52 | (defconst simula-indent-level-default 3 |
| 53 | "Indentation of SIMULA statements with respect to containing block.") | ||
| 54 | |||
| 55 | (defvar simula-indent-level simula-indent-level-default | ||
| 48 | "*Indentation of SIMULA statements with respect to containing block.") | 56 | "*Indentation of SIMULA statements with respect to containing block.") |
| 49 | 57 | ||
| 50 | (defconst simula-substatement-offset 3 | 58 | (defconst simula-substatement-offset-default 3 |
| 59 | "Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE.") | ||
| 60 | |||
| 61 | (defvar simula-substatement-offset simula-substatement-offset-default | ||
| 51 | "*Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE.") | 62 | "*Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE.") |
| 52 | 63 | ||
| 53 | (defconst simula-continued-statement-offset 3 | 64 | (defconst simula-continued-statement-offset-default 3 |
| 65 | "Extra indentation for lines not starting a statement or substatement. | ||
| 66 | If value is a list, each line in a multipleline continued statement | ||
| 67 | will have the car of the list extra indentation with respect to | ||
| 68 | the previous line of the statement.") | ||
| 69 | |||
| 70 | (defvar simula-continued-statement-offset simula-continued-statement-offset-default | ||
| 54 | "*Extra indentation for lines not starting a statement or substatement. | 71 | "*Extra indentation for lines not starting a statement or substatement. |
| 55 | If value is a list, each line in a multipleline continued statement | 72 | If value is a list, each line in a multipleline continued statement |
| 56 | will have the car of the list extra indentation with respect to | 73 | will have the car of the list extra indentation with respect to |
| 57 | the previous line of the statement.") | 74 | the previous line of the statement.") |
| 58 | 75 | ||
| 59 | (defconst simula-label-offset -4711 | 76 | (defconst simula-label-offset-default -4711 |
| 77 | "Offset of SIMULA label lines relative to usual indentation.") | ||
| 78 | |||
| 79 | (defvar simula-label-offset simula-label-offset-default | ||
| 60 | "*Offset of SIMULA label lines relative to usual indentation.") | 80 | "*Offset of SIMULA label lines relative to usual indentation.") |
| 61 | 81 | ||
| 62 | (defconst simula-if-indent '(0 . 0) | 82 | (defconst simula-if-indent-default '(0 . 0) |
| 83 | "Extra indentation of THEN and ELSE with respect to the starting IF. | ||
| 84 | Value is a cons cell, the car is extra THEN indentation and the cdr | ||
| 85 | extra ELSE indentation. IF after ELSE is indented as the starting IF.") | ||
| 86 | |||
| 87 | (defvar simula-if-indent simula-if-indent-default | ||
| 63 | "*Extra indentation of THEN and ELSE with respect to the starting IF. | 88 | "*Extra indentation of THEN and ELSE with respect to the starting IF. |
| 64 | Value is a cons cell, the car is extra THEN indentation and the cdr | 89 | Value is a cons cell, the car is extra THEN indentation and the cdr |
| 65 | extra ELSE indentation. IF after ELSE is indented as the starting IF.") | 90 | extra ELSE indentation. IF after ELSE is indented as the starting IF.") |
| 66 | 91 | ||
| 67 | (defconst simula-inspect-indent '(0 . 0) | 92 | (defconst simula-inspect-indent-default '(0 . 0) |
| 93 | "Extra indentation of WHEN and OTHERWISE with respect to the INSPECT. | ||
| 94 | Value is a cons cell, the car is extra WHEN indentation | ||
| 95 | and the cdr extra OTHERWISE indentation.") | ||
| 96 | |||
| 97 | (defvar simula-inspect-indent simula-inspect-indent-default | ||
| 68 | "*Extra indentation of WHEN and OTHERWISE with respect to the INSPECT. | 98 | "*Extra indentation of WHEN and OTHERWISE with respect to the INSPECT. |
| 69 | Value is a cons cell, the car is extra WHEN indentation | 99 | Value is a cons cell, the car is extra WHEN indentation |
| 70 | and the cdr extra OTHERWISE indentation.") | 100 | and the cdr extra OTHERWISE indentation.") |
| 71 | 101 | ||
| 72 | (defconst simula-electric-indent nil | 102 | (defconst simula-electric-indent-default nil |
| 103 | "Non-nil means `simula-indent-line' function may reindent previous line.") | ||
| 104 | |||
| 105 | (defvar simula-electric-indent simula-electric-indent-default | ||
| 73 | "*Non-nil means `simula-indent-line' function may reindent previous line.") | 106 | "*Non-nil means `simula-indent-line' function may reindent previous line.") |
| 74 | 107 | ||
| 75 | (defconst simula-abbrev-keyword 'upcase | 108 | (defconst simula-abbrev-keyword-default 'upcase |
| 109 | "Specify how to convert case for SIMULA keywords. | ||
| 110 | Value is one of the symbols `upcase', `downcase', `capitalize', | ||
| 111 | (as in) `abbrev-table' or nil if they should not be changed.") | ||
| 112 | |||
| 113 | (defvar simula-abbrev-keyword simula-abbrev-keyword-default | ||
| 76 | "*Specify how to convert case for SIMULA keywords. | 114 | "*Specify how to convert case for SIMULA keywords. |
| 77 | Value is one of the symbols `upcase', `downcase', `capitalize', | 115 | Value is one of the symbols `upcase', `downcase', `capitalize', |
| 78 | \(as in) `abbrev-table' or nil if they should not be changed.") | 116 | (as in) `abbrev-table' or nil if they should not be changed.") |
| 117 | |||
| 118 | (defconst simula-abbrev-stdproc-default 'abbrev-table | ||
| 119 | "Specify how to convert case for standard SIMULA procedure and class names. | ||
| 120 | Value is one of the symbols `upcase', `downcase', `capitalize', | ||
| 121 | (as in) `abbrev-table', or nil if they should not be changed.") | ||
| 79 | 122 | ||
| 80 | (defconst simula-abbrev-stdproc 'abbrev-table | 123 | (defvar simula-abbrev-stdproc simula-abbrev-stdproc-default |
| 81 | "*Specify how to convert case for standard SIMULA procedure and class names. | 124 | "*Specify how to convert case for standard SIMULA procedure and class names. |
| 82 | Value is one of the symbols `upcase', `downcase', `capitalize', | 125 | Value is one of the symbols `upcase', `downcase', `capitalize', |
| 83 | \(as in) `abbrev-table', or nil if they should not be changed.") | 126 | (as in) `abbrev-table', or nil if they should not be changed.") |
| 84 | 127 | ||
| 85 | (defvar simula-abbrev-file nil | 128 | (defvar simula-abbrev-file nil |
| 86 | "*File with extra abbrev definitions for use in SIMULA mode. | 129 | "*File with extra abbrev definitions for use in SIMULA mode. |
| @@ -91,6 +134,55 @@ for SIMULA mode to function correctly.") | |||
| 91 | (defvar simula-mode-syntax-table nil | 134 | (defvar simula-mode-syntax-table nil |
| 92 | "Syntax table in SIMULA mode buffers.") | 135 | "Syntax table in SIMULA mode buffers.") |
| 93 | 136 | ||
| 137 | ; The following function is taken from cc-mode.el, | ||
| 138 | ; it determines the flavor of the Emacs running | ||
| 139 | (defconst simula-emacs-features | ||
| 140 | (let ((major (and (boundp 'emacs-major-version) | ||
| 141 | emacs-major-version)) | ||
| 142 | (minor (and (boundp 'emacs-minor-version) | ||
| 143 | emacs-minor-version)) | ||
| 144 | flavor comments) | ||
| 145 | ;; figure out version numbers if not already discovered | ||
| 146 | (and (or (not major) (not minor)) | ||
| 147 | (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version) | ||
| 148 | (setq major (string-to-int (substring emacs-version | ||
| 149 | (match-beginning 1) | ||
| 150 | (match-end 1))) | ||
| 151 | minor (string-to-int (substring emacs-version | ||
| 152 | (match-beginning 2) | ||
| 153 | (match-end 2))))) | ||
| 154 | (if (not (and major minor)) | ||
| 155 | (error "Cannot figure out the major and minor version numbers.")) | ||
| 156 | ;; calculate the major version | ||
| 157 | (cond | ||
| 158 | ((= major 18) (setq major 'v18)) ;Emacs 18 | ||
| 159 | ((= major 4) (setq major 'v18)) ;Epoch 4 | ||
| 160 | ((= major 19) (setq major 'v19 ;Emacs 19 | ||
| 161 | flavor (if (string-match "Lucid" emacs-version) | ||
| 162 | 'Lucid 'FSF))) | ||
| 163 | ;; I don't know | ||
| 164 | (t (error "Cannot recognize major version number: %s" major))) | ||
| 165 | (list major flavor comments)) | ||
| 166 | "A list of features extant in the Emacs you are using. | ||
| 167 | There are many flavors of Emacs out there, each with different | ||
| 168 | features supporting those needed by simula-mode. Here's the current | ||
| 169 | supported list, along with the values for this variable: | ||
| 170 | |||
| 171 | Emacs 19: (v19 FSF 1-bit) | ||
| 172 | Vanilla Emacs 18/Epoch 4: (v18 no-dual-comments) | ||
| 173 | Emacs 18/Epoch 4 (patch2): (v18 8-bit) | ||
| 174 | Lucid Emacs 19: (v19 Lucid 8-bit).") | ||
| 175 | |||
| 176 | (defvar simula-mode-menu | ||
| 177 | '(["Report Bug" simula-submit-bug-report t] | ||
| 178 | ["Indent Line" simula-indent-line t] | ||
| 179 | ["Backward Statement" simula-previous-statement t] | ||
| 180 | ["Forward Statement" simula-next-statement t] | ||
| 181 | ["Backward Up Level" simula-backward-up-level t] | ||
| 182 | ["Forward Down Statement" simula-forward-down-level t] | ||
| 183 | ) | ||
| 184 | "Lucid Emacs menu for SIMULA mode.") | ||
| 185 | |||
| 94 | (if simula-mode-syntax-table | 186 | (if simula-mode-syntax-table |
| 95 | () | 187 | () |
| 96 | (setq simula-mode-syntax-table (copy-syntax-table (standard-syntax-table))) | 188 | (setq simula-mode-syntax-table (copy-syntax-table (standard-syntax-table))) |
| @@ -123,7 +215,65 @@ for SIMULA mode to function correctly.") | |||
| 123 | ;(define-key simula-mode-map "\C-c\C-h" 'simula-standard-help) | 215 | ;(define-key simula-mode-map "\C-c\C-h" 'simula-standard-help) |
| 124 | (define-key simula-mode-map "\177" 'backward-delete-char-untabify) | 216 | (define-key simula-mode-map "\177" 'backward-delete-char-untabify) |
| 125 | (define-key simula-mode-map ":" 'simula-electric-label) | 217 | (define-key simula-mode-map ":" 'simula-electric-label) |
| 126 | (define-key simula-mode-map "\t" 'simula-indent-command)) | 218 | (define-key simula-mode-map "\e\C-q" 'simula-indent-exp) |
| 219 | (define-key simula-mode-map "\t" 'simula-indent-command) | ||
| 220 | ;; Emacs 19 defines menus in the mode map | ||
| 221 | (if (memq 'FSF simula-emacs-features) | ||
| 222 | (progn | ||
| 223 | (define-key simula-mode-map [menu-bar] (make-sparse-keymap)) | ||
| 224 | |||
| 225 | (define-key simula-mode-map [menu-bar simula] | ||
| 226 | (cons "SIMULA" (make-sparse-keymap "SIMULA"))) | ||
| 227 | (define-key simula-mode-map [menu-bar simula bug-report] | ||
| 228 | '("Submit Bug Report" . simula-submit-bug-report)) | ||
| 229 | (define-key simula-mode-map [menu-bar simula separator-indent] | ||
| 230 | '("--")) | ||
| 231 | (define-key simula-mode-map [menu-bar simula indent-exp] | ||
| 232 | '("Indent Expression" . simula-indent-exp)) | ||
| 233 | (define-key simula-mode-map [menu-bar simula indent-line] | ||
| 234 | '("Indent Line" . simula-indent-command)) | ||
| 235 | (define-key simula-mode-map [menu-bar simula separator-navigate] | ||
| 236 | '("--")) | ||
| 237 | (define-key simula-mode-map [menu-bar simula backward-stmt] | ||
| 238 | '("Previous Statement" . simula-previous-statement)) | ||
| 239 | (define-key simula-mode-map [menu-bar simula forward-stmt] | ||
| 240 | '("Next Statement" . simula-next-statement)) | ||
| 241 | (define-key simula-mode-map [menu-bar simula backward-up] | ||
| 242 | '("Backward Up Level" . simula-backward-up-level)) | ||
| 243 | (define-key simula-mode-map [menu-bar simula forward-down] | ||
| 244 | '("Forward Down Statement" . simula-forward-down-level)) | ||
| 245 | |||
| 246 | (put 'simula-next-statement 'menu-enable '(not (eobp))) | ||
| 247 | (put 'simula-previous-statement 'menu-enable '(not (bobp))) | ||
| 248 | (put 'simula-forward-down-level 'menu-enable '(not (eobp))) | ||
| 249 | (put 'simula-backward-up-level 'menu-enable '(not (bobp))) | ||
| 250 | (put 'simula-indent-command 'menu-enable '(not buffer-read-only)) | ||
| 251 | (put 'simula-indent-exp 'menu-enable '(not buffer-read-only)))) | ||
| 252 | |||
| 253 | ;; RMS: mouse-3 should not select this menu. mouse-3's global | ||
| 254 | ;; definition is useful in SIMULA mode and we should not interfere | ||
| 255 | ;; with that. The menu is mainly for beginners, and for them, | ||
| 256 | ;; the menubar requires less memory than a special click. | ||
| 257 | ;; in Lucid Emacs, we want the menu to popup when the 3rd button is | ||
| 258 | ;; hit. In 19.10 and beyond this is done automatically if we put | ||
| 259 | ;; the menu on mode-popup-menu variable, see c-common-init [cc-mode.el] | ||
| 260 | (if (memq 'Lucid simula-emacs-features) | ||
| 261 | (if (not (boundp 'mode-popup-menu)) | ||
| 262 | (define-key simula-mode-map 'button3 'simula-popup-menu)))) | ||
| 263 | |||
| 264 | ;; menus for Lucid | ||
| 265 | (defun simula-popup-menu (e) | ||
| 266 | "Pops up the SIMULA menu." | ||
| 267 | (interactive "@e") | ||
| 268 | (popup-menu (cons (concat mode-name " Mode Commands") simula-mode-menu)) | ||
| 269 | (simula-keep-region-active)) | ||
| 270 | |||
| 271 | ;; active regions, and auto-newline/hungry delete key | ||
| 272 | (defun simula-keep-region-active () | ||
| 273 | ;; do whatever is necessary to keep the region active in | ||
| 274 | ;; Lucid. ignore byte-compiler warnings you might see | ||
| 275 | (and (boundp 'zmacs-region-stays) | ||
| 276 | (setq zmacs-region-stays t))) | ||
| 127 | 277 | ||
| 128 | (defvar simula-mode-abbrev-table nil | 278 | (defvar simula-mode-abbrev-table nil |
| 129 | "Abbrev table in SIMULA mode buffers") | 279 | "Abbrev table in SIMULA mode buffers") |
| @@ -180,8 +330,8 @@ at all." | |||
| 180 | (setq mode-name "SIMULA") | 330 | (setq mode-name "SIMULA") |
| 181 | (make-local-variable 'comment-column) | 331 | (make-local-variable 'comment-column) |
| 182 | (setq comment-column 40) | 332 | (setq comment-column 40) |
| 183 | (make-local-variable 'end-comment-column) | 333 | ; (make-local-variable 'end-comment-column) |
| 184 | (setq end-comment-column 75) | 334 | ; (setq end-comment-column 75) |
| 185 | (set-syntax-table simula-mode-syntax-table) | 335 | (set-syntax-table simula-mode-syntax-table) |
| 186 | (make-local-variable 'paragraph-start) | 336 | (make-local-variable 'paragraph-start) |
| 187 | (setq paragraph-start "[ \t]*$\\|\\f") | 337 | (setq paragraph-start "[ \t]*$\\|\\f") |
| @@ -213,6 +363,27 @@ at all." | |||
| 213 | (run-hooks 'simula-mode-hook)) | 363 | (run-hooks 'simula-mode-hook)) |
| 214 | 364 | ||
| 215 | 365 | ||
| 366 | (defun simula-indent-exp () | ||
| 367 | "Indent SIMULA expression following point." | ||
| 368 | (interactive) | ||
| 369 | (let ((here (point)) | ||
| 370 | (simula-electric-indent nil) | ||
| 371 | end) | ||
| 372 | (simula-skip-comment-forward) | ||
| 373 | (if (eobp) | ||
| 374 | (goto-char here) | ||
| 375 | (unwind-protect | ||
| 376 | (progn | ||
| 377 | (simula-next-statement 1) | ||
| 378 | (setq end (point-marker)) | ||
| 379 | (simula-previous-statement 1) | ||
| 380 | (beginning-of-line) | ||
| 381 | (while (< (point) end) | ||
| 382 | (if (not (looking-at "[ \t]*$")) | ||
| 383 | (simula-indent-line)) | ||
| 384 | (forward-line 1))) | ||
| 385 | (and end (set-marker end nil)))))) | ||
| 386 | |||
| 216 | 387 | ||
| 217 | (defun simula-indent-line () | 388 | (defun simula-indent-line () |
| 218 | "Indent this line as SIMULA code. | 389 | "Indent this line as SIMULA code. |
| @@ -221,27 +392,26 @@ If `simula-electric-indent' is non-nil, indent previous line if necessary." | |||
| 221 | (indent (simula-calculate-indent)) | 392 | (indent (simula-calculate-indent)) |
| 222 | (case-fold-search t)) | 393 | (case-fold-search t)) |
| 223 | (unwind-protect | 394 | (unwind-protect |
| 224 | (progn | 395 | (if simula-electric-indent |
| 225 | ;; | 396 | (progn |
| 226 | ;; manually expand abbrev on last line, if any | 397 | ;; |
| 227 | ;; | 398 | ;; manually expand abbrev on last line, if any |
| 228 | (end-of-line 0) | 399 | ;; |
| 229 | (expand-abbrev) | 400 | (end-of-line 0) |
| 230 | ;; now maybe we should reindent that line | 401 | (expand-abbrev) |
| 231 | (if simula-electric-indent | 402 | ;; now maybe we should reindent that line |
| 232 | (progn | 403 | (beginning-of-line) |
| 233 | (beginning-of-line) | 404 | (skip-chars-forward " \t\f") |
| 234 | (skip-chars-forward " \t\f") | 405 | (if (and |
| 235 | (if (and | 406 | (looking-at |
| 236 | (looking-at | 407 | "\\(end\\|if\\|then\\|else\\|when\\|otherwise\\)\\>") |
| 237 | "\\(end\\|if\\|then\\|else\\|when\\|otherwise\\)\\>") | 408 | (not (simula-context))) |
| 238 | (not (simula-context))) | 409 | ;; yes - reindent |
| 239 | ;; yes - reindent | 410 | (let ((post-indent (simula-calculate-indent))) |
| 240 | (let ((post-indent (simula-calculate-indent))) | 411 | (if (eq (current-indentation) post-indent) |
| 241 | (if (eq (current-indentation) post-indent) | 412 | () |
| 242 | () | 413 | (delete-horizontal-space) |
| 243 | (delete-horizontal-space) | 414 | (indent-to post-indent)))))) |
| 244 | (indent-to post-indent))))))) | ||
| 245 | (goto-char (- (point-max) origin)) | 415 | (goto-char (- (point-max) origin)) |
| 246 | (if (eq (current-indentation) indent) | 416 | (if (eq (current-indentation) indent) |
| 247 | (back-to-indentation) | 417 | (back-to-indentation) |
| @@ -364,14 +534,22 @@ The relative indentation among the lines of the statement are preserved." | |||
| 364 | (cond | 534 | (cond |
| 365 | ((memq (preceding-char) '(?d ?D)) | 535 | ((memq (preceding-char) '(?d ?D)) |
| 366 | (setq return-value 2) | 536 | (setq return-value 2) |
| 367 | (while (and (memq (preceding-char) '(?d ?D)) (not return-value)) | 537 | (while (and (re-search-forward |
| 368 | (while (and (re-search-forward | 538 | ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\|^%" |
| 369 | ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\|^%" | 539 | origin 'move) |
| 370 | origin 'move) | 540 | ;; found another END? |
| 371 | (eq (preceding-char) ?%)) | 541 | (or (memq (preceding-char) '(?d ?D)) |
| 372 | (beginning-of-line 2))) | 542 | ;; if directive, skip line |
| 373 | (if (looking-at "[ \t\n\f]*\\(;\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\)") | 543 | (and (eq (preceding-char) ?%) |
| 374 | (setq return-value nil))) | 544 | (beginning-of-line 2)) |
| 545 | ;; found other keyword, out of END comment | ||
| 546 | (setq return-value nil)))) | ||
| 547 | (if (and (eq (char-syntax (preceding-char)) ?w) | ||
| 548 | (eq (char-syntax (following-char)) ?w)) | ||
| 549 | (save-excursion | ||
| 550 | (backward-word 1) | ||
| 551 | (if (looking-at "end\\>\\|else\\>\\|otherwise\\>\\|when\\>") | ||
| 552 | (setq return-value nil))))) | ||
| 375 | ((memq (preceding-char) '(?! ?t ?T)) | 553 | ((memq (preceding-char) '(?! ?t ?T)) |
| 376 | ; skip comment | 554 | ; skip comment |
| 377 | (setq return-value 0) | 555 | (setq return-value 0) |
| @@ -406,10 +584,11 @@ The relative indentation among the lines of the statement are preserved." | |||
| 406 | (let ((origin (- (point-max) (point))) | 584 | (let ((origin (- (point-max) (point))) |
| 407 | (case-fold-search t) | 585 | (case-fold-search t) |
| 408 | ;; don't mix a label with an assignment operator := :- | 586 | ;; don't mix a label with an assignment operator := :- |
| 409 | ;; therefore look at next typed character... | 587 | ;; therefore take a peek at next typed character... |
| 410 | (next-char (setq unread-command-events (list (read-event)))) | 588 | (next-char (read-event))) |
| 411 | (com-char last-command-char)) | ||
| 412 | (unwind-protect | 589 | (unwind-protect |
| 590 | (setq unread-command-events (append unread-command-events | ||
| 591 | (list next-char))) | ||
| 413 | ;; Problem: find out if character just read is a command char | 592 | ;; Problem: find out if character just read is a command char |
| 414 | ;; that would insert something after ':' making it a label. | 593 | ;; that would insert something after ':' making it a label. |
| 415 | ;; At least \n, \r (and maybe \t) falls into this category. | 594 | ;; At least \n, \r (and maybe \t) falls into this category. |
| @@ -516,6 +695,7 @@ If COUNT is negative, move forward instead." | |||
| 516 | (case-fold-search t) | 695 | (case-fold-search t) |
| 517 | (origin (point))) | 696 | (origin (point))) |
| 518 | (condition-case () | 697 | (condition-case () |
| 698 | ;; | ||
| 519 | (progn | 699 | (progn |
| 520 | (simula-skip-comment-backward) | 700 | (simula-skip-comment-backward) |
| 521 | (if (memq (preceding-char) '(?n ?N)) | 701 | (if (memq (preceding-char) '(?n ?N)) |
| @@ -524,7 +704,8 @@ If COUNT is negative, move forward instead." | |||
| 524 | (if (not (looking-at "\\<begin\\>")) | 704 | (if (not (looking-at "\\<begin\\>")) |
| 525 | (backward-word -1))) | 705 | (backward-word -1))) |
| 526 | (if (eq (preceding-char) ?\;) | 706 | (if (eq (preceding-char) ?\;) |
| 527 | (backward-char 1))) | 707 | (backward-char 1)) |
| 708 | ) | ||
| 528 | (while (and (natnump (setq count (1- count))) | 709 | (while (and (natnump (setq count (1- count))) |
| 529 | (setq status (simula-search-backward | 710 | (setq status (simula-search-backward |
| 530 | ";\\|\\<begin\\>" nil 'move)))) | 711 | ";\\|\\<begin\\>" nil 'move)))) |
| @@ -564,7 +745,7 @@ If COUNT is negative, move backward instead." | |||
| 564 | (quit (progn (goto-char origin) (signal 'quit nil))))))) | 745 | (quit (progn (goto-char origin) (signal 'quit nil))))))) |
| 565 | 746 | ||
| 566 | 747 | ||
| 567 | (defun simula-skip-comment-backward () | 748 | (defun simula-skip-comment-backward (&optional stop-at-end) |
| 568 | "Search towards bob to find first char that is outside a comment." | 749 | "Search towards bob to find first char that is outside a comment." |
| 569 | (interactive) | 750 | (interactive) |
| 570 | (catch 'simula-out | 751 | (catch 'simula-out |
| @@ -574,7 +755,9 @@ If COUNT is negative, move backward instead." | |||
| 574 | (if (eq (preceding-char) ?\;) | 755 | (if (eq (preceding-char) ?\;) |
| 575 | (save-excursion | 756 | (save-excursion |
| 576 | (backward-char 1) | 757 | (backward-char 1) |
| 577 | (setq context (simula-context))) | 758 | (setq context (simula-context)) |
| 759 | (if (and stop-at-end (eq context 2)) | ||
| 760 | (setq context nil))) | ||
| 578 | (setq context (simula-context))) | 761 | (setq context (simula-context))) |
| 579 | (cond | 762 | (cond |
| 580 | ((memq context '(nil 3 4)) | 763 | ((memq context '(nil 3 4)) |
| @@ -591,9 +774,10 @@ If COUNT is negative, move backward instead." | |||
| 591 | (while (and (re-search-backward "!\\|\\<comment\\>") | 774 | (while (and (re-search-backward "!\\|\\<comment\\>") |
| 592 | (memq (simula-context) '(0 1))))) | 775 | (memq (simula-context) '(0 1))))) |
| 593 | ((eq context 1) | 776 | ((eq context 1) |
| 594 | (end-of-line 0) | 777 | (beginning-of-line) |
| 595 | (if (bobp) | 778 | (if (bobp) |
| 596 | (throw 'simula-out nil))) | 779 | (throw 'simula-out nil) |
| 780 | (backward-char))) | ||
| 597 | ((eq context 2) | 781 | ((eq context 2) |
| 598 | ;; an END-comment must belong to an END | 782 | ;; an END-comment must belong to an END |
| 599 | (re-search-backward "\\<end\\>") | 783 | (re-search-backward "\\<end\\>") |
| @@ -610,6 +794,8 @@ If COUNT is negative, move backward instead." | |||
| 610 | (catch 'simula-out | 794 | (catch 'simula-out |
| 611 | (while t | 795 | (while t |
| 612 | (skip-chars-forward " \t\n\f") | 796 | (skip-chars-forward " \t\n\f") |
| 797 | ;; BUG: the following (0 2) branches don't take into account intermixing | ||
| 798 | ;; directive lines | ||
| 613 | (cond | 799 | (cond |
| 614 | ((looking-at "!\\|\\<comment\\>") | 800 | ((looking-at "!\\|\\<comment\\>") |
| 615 | (search-forward ";" nil 'move)) | 801 | (search-forward ";" nil 'move)) |
| @@ -666,6 +852,11 @@ If COUNT is negative, move backward instead." | |||
| 666 | (prog1 | 852 | (prog1 |
| 667 | (current-column) | 853 | (current-column) |
| 668 | (goto-char origin))) | 854 | (goto-char origin))) |
| 855 | ((eq where 1) | ||
| 856 | ;; | ||
| 857 | ;; Directive. Always 0. | ||
| 858 | ;; | ||
| 859 | 0) | ||
| 669 | ;; | 860 | ;; |
| 670 | ;; Detect missing string delimiters | 861 | ;; Detect missing string delimiters |
| 671 | ;; | 862 | ;; |
| @@ -722,7 +913,7 @@ If COUNT is negative, move backward instead." | |||
| 722 | (looking-at "[a-z0-9_]*[ \t\f]*:[^-=]")) | 913 | (looking-at "[a-z0-9_]*[ \t\f]*:[^-=]")) |
| 723 | (setq indent simula-label-offset))) | 914 | (setq indent simula-label-offset))) |
| 724 | ;; find line with non-comment text | 915 | ;; find line with non-comment text |
| 725 | (simula-skip-comment-backward) | 916 | (simula-skip-comment-backward 'dont-skip-end) |
| 726 | (if (and found-end | 917 | (if (and found-end |
| 727 | (not (eq (preceding-char) ?\;)) | 918 | (not (eq (preceding-char) ?\;)) |
| 728 | (if (memq (preceding-char) '(?N ?n)) | 919 | (if (memq (preceding-char) '(?N ?n)) |
| @@ -933,7 +1124,14 @@ If COUNT is negative, move backward instead." | |||
| 933 | (cond | 1124 | (cond |
| 934 | ((eq simula-abbrev-stdproc 'upcase) (upcase-word -1)) | 1125 | ((eq simula-abbrev-stdproc 'upcase) (upcase-word -1)) |
| 935 | ((eq simula-abbrev-stdproc 'downcase) (downcase-word -1)) | 1126 | ((eq simula-abbrev-stdproc 'downcase) (downcase-word -1)) |
| 936 | ((eq simula-abbrev-stdproc 'capitalize) (capitalize-word -1))))) | 1127 | ((eq simula-abbrev-stdproc 'capitalize) (capitalize-word -1)) |
| 1128 | ((eq simula-abbrev-stdproc 'abbrev-table) | ||
| 1129 | ;; If not in lowercase, expansions are always capitalized. | ||
| 1130 | ;; We then want to replace with the exact expansion. | ||
| 1131 | (if (equal (symbol-name last-abbrev) last-abbrev-text) | ||
| 1132 | () | ||
| 1133 | (downcase-word -1) | ||
| 1134 | (expand-abbrev)))))) | ||
| 937 | 1135 | ||
| 938 | 1136 | ||
| 939 | (defun simula-expand-keyword () | 1137 | (defun simula-expand-keyword () |
| @@ -942,7 +1140,12 @@ If COUNT is negative, move backward instead." | |||
| 942 | (cond | 1140 | (cond |
| 943 | ((eq simula-abbrev-keyword 'upcase) (upcase-word -1)) | 1141 | ((eq simula-abbrev-keyword 'upcase) (upcase-word -1)) |
| 944 | ((eq simula-abbrev-keyword 'downcase) (downcase-word -1)) | 1142 | ((eq simula-abbrev-keyword 'downcase) (downcase-word -1)) |
| 945 | ((eq simula-abbrev-keyword 'capitalize) (capitalize-word -1))))) | 1143 | ((eq simula-abbrev-keyword 'capitalize) (capitalize-word -1)) |
| 1144 | ((eq simula-abbrev-stdproc 'abbrev-table) | ||
| 1145 | (if (equal (symbol-name last-abbrev) last-abbrev-text) | ||
| 1146 | () | ||
| 1147 | (downcase-word -1) | ||
| 1148 | (expand-abbrev)))))) | ||
| 946 | 1149 | ||
| 947 | 1150 | ||
| 948 | (defun simula-electric-keyword () | 1151 | (defun simula-electric-keyword () |
| @@ -1007,48 +1210,125 @@ If COUNT is negative, move backward instead." | |||
| 1007 | (quit (goto-char (- (point-max) pos)))))))) | 1210 | (quit (goto-char (- (point-max) pos)))))))) |
| 1008 | 1211 | ||
| 1009 | 1212 | ||
| 1010 | (defun simula-search-backward (string &optional limit move) | 1213 | (defun simula-search-backward (regexp &optional bound noerror) |
| 1011 | (setq string (concat string "\\|\\<end\\>")) | 1214 | "Search backward from point for regular expression REGEXP, ignoring matches |
| 1012 | (let (level) | 1215 | found inside SIMULA comments, string literals, and BEGIN..END blocks. |
| 1013 | (catch 'simula-out | 1216 | Set point to the end of the occurrence found, and return point. |
| 1014 | (while (re-search-backward string limit move) | 1217 | An optional second argument BOUND bounds the search, it is a buffer position. |
| 1015 | (if (simula-context) | 1218 | The match found must not extend after that position. Optional third argument |
| 1016 | () | 1219 | NOERROR, if t, means if fail just return nil (no error). |
| 1017 | (if (looking-at "\\<end\\>") | 1220 | If not nil and not t, move to limit of search and return nil." |
| 1018 | (progn | 1221 | (let (begin end context (comb-regexp (concat regexp "\\|\\<end\\>")) |
| 1019 | (setq level 0) | 1222 | match (start-point (point))) |
| 1020 | (while (natnump level) | 1223 | (catch 'simula-backward |
| 1021 | (re-search-backward "\\<begin\\>\\|\\<end\\>") | 1224 | (while (re-search-backward comb-regexp bound 1) |
| 1022 | (if (simula-context) | 1225 | ;; We have a match, check SIMULA context at match-beginning |
| 1023 | () | 1226 | ;; to see if we are outside comments etc. |
| 1024 | (setq level (if (memq (following-char) '(?b ?B)) | 1227 | ;; Set MATCH to t if we found a true match, |
| 1025 | (1- level) | 1228 | ;; set MATCH to 'BLOCK if we found a BEGIN..END block, |
| 1026 | (1+ level)))))) | 1229 | ;; else set MATCH to nil. |
| 1027 | (throw 'simula-out t))))))) | 1230 | (save-match-data |
| 1028 | 1231 | (setq context (simula-context)) | |
| 1029 | 1232 | (cond | |
| 1030 | (defun simula-search-forward (string &optional limit move) | 1233 | ((eq context nil) |
| 1031 | (setq string (concat string "\\|\\<begin\\>")) | 1234 | (setq match (if (looking-at regexp) t 'BLOCK))) |
| 1032 | (let (level) | 1235 | ;;; A comment-ending semicolon is part of the comment, and shouldn't match. |
| 1033 | (catch 'exit | 1236 | ;;; ((eq context 0) |
| 1034 | (while (re-search-forward string limit move) | 1237 | ;;; (setq match (if (eq (following-char) ?\;) t nil))) |
| 1035 | (goto-char (match-beginning 0)) | 1238 | ((eq context 2) |
| 1036 | (if (simula-context) | 1239 | (setq match (if (and (looking-at regexp) |
| 1037 | (goto-char (1- (match-end 0))) | 1240 | (looking-at ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>")) |
| 1038 | (if (looking-at "\\<begin\\>") | 1241 | t |
| 1039 | (progn | 1242 | (if (looking-at "\\<end\\>") 'BLOCK nil)))) |
| 1040 | (goto-char (1- (match-end 0))) | 1243 | (t (setq match nil)))) |
| 1041 | (setq level 0) | 1244 | ;; Exit if true match |
| 1042 | (while (natnump level) | 1245 | (if (eq match t) (throw 'simula-backward (point))) |
| 1043 | (re-search-forward "\\<begin\\>\\|\\<end\\>") | 1246 | (if (eq match 'BLOCK) |
| 1044 | (backward-word 1) | 1247 | ;; We found the END of a block |
| 1045 | (if (not (simula-context)) | 1248 | (let ((level 0)) |
| 1046 | (setq level (if (memq (following-char) '(?e ?E)) | 1249 | (while (natnump level) |
| 1047 | (1- level) | 1250 | (if (re-search-backward "\\<begin\\>\\|\\<end\\>" bound 1) |
| 1048 | (1+ level)))) | 1251 | (let ((context (simula-context))) |
| 1049 | (backward-word -1))) | 1252 | ;; We found a BEGIN -> decrease level count |
| 1050 | (goto-char (1- (match-end 0))) | 1253 | (cond ((and (eq context nil) |
| 1051 | (throw 'exit t))))))) | 1254 | (memq (following-char) '(?b ?B))) |
| 1255 | (setq level (1- level))) | ||
| 1256 | ;; END -> increase level count | ||
| 1257 | ((and (memq context '(nil 2)) | ||
| 1258 | (memq (following-char) '(?e ?E))) | ||
| 1259 | (setq level (1+ level))))) | ||
| 1260 | ;; Block search failed. Action depends on noerror. | ||
| 1261 | (if (or (not noerror) (eq noerror t)) | ||
| 1262 | (goto-char start-point)) | ||
| 1263 | (if (not noerror) | ||
| 1264 | (signal 'search-failed (list regexp))) | ||
| 1265 | (throw 'simula-backward nil)))))) | ||
| 1266 | ;; Search failed. Action depends on noerror. | ||
| 1267 | (if (or (not noerror) (eq noerror t)) | ||
| 1268 | (goto-char start-point)) | ||
| 1269 | (if noerror | ||
| 1270 | nil | ||
| 1271 | (signal 'search-failed (list regexp)))))) | ||
| 1272 | |||
| 1273 | |||
| 1274 | (defun simula-search-forward (regexp &optional bound noerror) | ||
| 1275 | "Search forward from point for regular expression REGEXP, ignoring matches | ||
| 1276 | found inside SIMULA comments, string literals, and BEGIN..END blocks. | ||
| 1277 | Set point to the end of the occurrence found, and return point. | ||
| 1278 | An optional second argument BOUND bounds the search, it is a buffer position. | ||
| 1279 | The match found must not extend after that position. Optional third argument | ||
| 1280 | NOERROR, if t, means if fail just return nil (no error). | ||
| 1281 | If not nil and not t, move to limit of search and return nil." | ||
| 1282 | (let (begin end context (comb-regexp (concat regexp "\\|\\<begin\\>")) | ||
| 1283 | match (start-point (point))) | ||
| 1284 | (catch 'simula-forward | ||
| 1285 | (while (re-search-forward comb-regexp bound 1) | ||
| 1286 | ;; We have a match, check SIMULA context at match-beginning | ||
| 1287 | ;; to see if we are outside comments. | ||
| 1288 | ;; Set MATCH to t if we found a true match, | ||
| 1289 | ;; set MATCH to 'BLOCK if we found a BEGIN..END block, | ||
| 1290 | ;; else set MATCH to nil. | ||
| 1291 | (save-match-data | ||
| 1292 | (save-excursion | ||
| 1293 | (goto-char (match-beginning 0)) | ||
| 1294 | (setq context (simula-context)) | ||
| 1295 | (cond | ||
| 1296 | ((not context) | ||
| 1297 | (setq match (if (looking-at regexp) t 'BLOCK))) | ||
| 1298 | ;;; A comment-ending semicolon is part of the comment, and shouldn't match. | ||
| 1299 | ;;; ((eq context 0) | ||
| 1300 | ;;; (setq match (if (eq (following-char) ?\;) t nil))) | ||
| 1301 | ((eq context 2) | ||
| 1302 | (setq match (if (and (looking-at regexp) | ||
| 1303 | (looking-at ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>")) t nil))) | ||
| 1304 | (t (setq match nil))))) | ||
| 1305 | ;; Exit if true match | ||
| 1306 | (if (eq match t) (throw 'simula-forward (point))) | ||
| 1307 | (if (eq match 'BLOCK) | ||
| 1308 | ;; We found the BEGINning of a block | ||
| 1309 | (let ((level 0)) | ||
| 1310 | (while (natnump level) | ||
| 1311 | (if (re-search-forward "\\<begin\\>\\|\\<end\\>" bound 1) | ||
| 1312 | (let ((context (simula-context))) | ||
| 1313 | ;; We found a BEGIN -> increase level count | ||
| 1314 | (cond ((eq context nil) (setq level (1+ level))) | ||
| 1315 | ;; END -> decrease level count | ||
| 1316 | ((and (eq context 2) | ||
| 1317 | ;; Don't match BEGIN inside END comment | ||
| 1318 | (memq (preceding-char) '(?d ?D))) | ||
| 1319 | (setq level (1- level))))) | ||
| 1320 | ;; Block search failed. Action depends on noerror. | ||
| 1321 | (if (or (not noerror) (eq noerror t)) | ||
| 1322 | (goto-char start-point)) | ||
| 1323 | (if (not noerror) | ||
| 1324 | (signal 'search-failed (list regexp))) | ||
| 1325 | (throw 'simula-forward nil)))))) | ||
| 1326 | ;; Search failed. Action depends on noerror. | ||
| 1327 | (if (or (not noerror) (eq noerror t)) | ||
| 1328 | (goto-char start-point)) | ||
| 1329 | (if noerror | ||
| 1330 | nil | ||
| 1331 | (signal 'search-failed (list regexp)))))) | ||
| 1052 | 1332 | ||
| 1053 | 1333 | ||
| 1054 | (defun simula-install-standard-abbrevs () | 1334 | (defun simula-install-standard-abbrevs () |
| @@ -1288,4 +1568,116 @@ If COUNT is negative, move backward instead." | |||
| 1288 | ("when" "WHEN" simula-electric-keyword) | 1568 | ("when" "WHEN" simula-electric-keyword) |
| 1289 | ("while" "WHILE" simula-expand-keyword)))) | 1569 | ("while" "WHILE" simula-expand-keyword)))) |
| 1290 | 1570 | ||
| 1571 | (if (and (fboundp 'hilit-set-mode-patterns) | ||
| 1572 | (boundp 'hilit-patterns-alist) | ||
| 1573 | (not (assoc 'simula-mode hilit-patterns-alist))) | ||
| 1574 | (hilit-set-mode-patterns | ||
| 1575 | 'simula-mode | ||
| 1576 | '( | ||
| 1577 | ("^%\\([ \t\f].*\\)?$" nil comment) | ||
| 1578 | ("^%include\\>" nil include) | ||
| 1579 | ("\"[^\"\n]*\"\\|'.'\\|'![0-9]+!'" nil string) | ||
| 1580 | ("\\<\\(ACTIVATE\\|AFTER\\|AND\\|ARRAY\\|AT\\|BEFORE\\|BEGIN\\|BOOLEAN\\|CHARACTER\\|CLASS\\|DELAY\\|DO\\|ELSE\\|END\\|EQ\\|EQV\\|EXTERNAL\\|FALSE\\|FOR\\|GE\\|GO\\|GOTO\\|GT\\|HIDDEN\\|IF\\|IMP\\|IN\\|INNER\\|INSPECT\\|INTEGER\\|IS\\|LABEL\\|LE\\|LONG\\|LT\\|NAME\\|NE\\|NEW\\|NONE\\|NOT\\|NOTEXT\\|OR\\|OTHERWISE\\|PRIOR\\|PROCEDURE\\|PROTECTED\\|QUA\\|REACTIVATE\\|REAL\\|REF\\|SHORT\\|STEP\\|SWITCH\\|TEXT\\|THEN\\|THIS\\|TO\\|TRUE\\|UNTIL\\|VALUE\\|VIRTUAL\\|WHEN\\|WHILE\\)\\>" nil keyword) | ||
| 1581 | ("!\\|\\<COMMENT\\>" ";" comment)) | ||
| 1582 | nil 'case-insensitive)) | ||
| 1583 | |||
| 1584 | (setq simula-find-comment-point -1 | ||
| 1585 | simula-find-comment-context nil) | ||
| 1586 | |||
| 1587 | ;; function used by hilit19 | ||
| 1588 | (defun simula-find-next-comment-region (param) | ||
| 1589 | "Return region (start end) cons of comment after point, or NIL" | ||
| 1590 | (let (start end) | ||
| 1591 | ;; This function is called repeatedly, check if point is | ||
| 1592 | ;; where we left it in the last call | ||
| 1593 | (if (not (eq simula-find-comment-point (point))) | ||
| 1594 | (setq simula-find-comment-point (point) | ||
| 1595 | simula-find-comment-context (simula-context))) | ||
| 1596 | ;; loop as long as we haven't found the end of a comment | ||
| 1597 | (if (memq simula-find-comment-context '(0 1 2)) | ||
| 1598 | (setq start (point)) | ||
| 1599 | (if (re-search-forward "\\<end\\>\\|!\\|\"\\|'\\|^%\\|\\<comment\\>" | ||
| 1600 | nil 'move) | ||
| 1601 | (let ((previous-char (preceding-char))) | ||
| 1602 | (cond | ||
| 1603 | ((memq previous-char '(?d ?D)) | ||
| 1604 | (setq start (point) | ||
| 1605 | simula-find-comment-context 2)) | ||
| 1606 | ((memq previous-char '(?t ?T ?\!)) | ||
| 1607 | (setq start (point) | ||
| 1608 | simula-find-comment-context 0)) | ||
| 1609 | ((eq previous-char ?%) | ||
| 1610 | (setq start (point) | ||
| 1611 | simula-find-comment-context 0)))))) | ||
| 1612 | ;; BUG: the following (0 2) branches don't take into account intermixing | ||
| 1613 | ;; directive lines | ||
| 1614 | (cond | ||
| 1615 | ((eq simula-find-comment-context 0) | ||
| 1616 | (search-forward ";" nil 'move)) | ||
| 1617 | ((eq simula-find-comment-context 1) | ||
| 1618 | (beginning-of-line 2)) | ||
| 1619 | ((eq simula-find-comment-context 2) | ||
| 1620 | (re-search-forward ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\" (point-max) 'move))) | ||
| 1621 | (if start | ||
| 1622 | (setq end (point))) | ||
| 1623 | ;; save point for later calls to this function | ||
| 1624 | (setq simula-find-comment-point (if end (point) -1)) | ||
| 1625 | (and end (cons start end)))) | ||
| 1626 | |||
| 1627 | (if (not (fboundp 'save-match-data)) | ||
| 1628 | (defmacro save-match-data (&rest body) | ||
| 1629 | "Execute the BODY forms, restoring the global value of the match data." | ||
| 1630 | (let ((original (make-symbol "match-data"))) | ||
| 1631 | (list | ||
| 1632 | 'let (list (list original '(match-data))) | ||
| 1633 | (list 'unwind-protect | ||
| 1634 | (cons 'progn body) | ||
| 1635 | (list 'store-match-data original)))))) | ||
| 1636 | |||
| 1637 | |||
| 1638 | ;; defuns for submitting bug reports | ||
| 1639 | |||
| 1640 | (defconst simula-version "0.994" | ||
| 1641 | "simula-mode version number.") | ||
| 1642 | (defconst simula-mode-help-address "simula-mode@ifi.uio.no" | ||
| 1643 | "Address accepting submission of simula-mode bug reports.") | ||
| 1644 | |||
| 1645 | (defun simula-version () | ||
| 1646 | "Echo the current version of simula-mode in the minibuffer." | ||
| 1647 | (interactive) | ||
| 1648 | (message "Using simula-mode version %s" simula-version) | ||
| 1649 | (simula-keep-region-active)) | ||
| 1650 | |||
| 1651 | ;; get reporter-submit-bug-report when byte-compiling | ||
| 1652 | (and (fboundp 'eval-when-compile) | ||
| 1653 | (eval-when-compile | ||
| 1654 | (require 'reporter))) | ||
| 1655 | |||
| 1656 | (defun simula-submit-bug-report () | ||
| 1657 | "Submit via mail a bug report on simula-mode." | ||
| 1658 | (interactive) | ||
| 1659 | (and | ||
| 1660 | (y-or-n-p "Do you want to submit a report on simula-mode? ") | ||
| 1661 | (require 'reporter) | ||
| 1662 | (reporter-submit-bug-report | ||
| 1663 | simula-mode-help-address | ||
| 1664 | (concat "simula-mode " simula-version) | ||
| 1665 | (list | ||
| 1666 | ;; report only the vars that affect indentation | ||
| 1667 | 'simula-emacs-features | ||
| 1668 | 'simula-indent-level | ||
| 1669 | 'simula-substatement-offset | ||
| 1670 | 'simula-continued-statement-offset | ||
| 1671 | 'simula-label-offset | ||
| 1672 | 'simula-if-indent | ||
| 1673 | 'simula-inspect-indent | ||
| 1674 | 'simula-electric-indent | ||
| 1675 | 'simula-abbrev-keyword | ||
| 1676 | 'simula-abbrev-stdproc | ||
| 1677 | 'simula-abbrev-file | ||
| 1678 | 'simula-tab-always-indent | ||
| 1679 | )))) | ||
| 1680 | |||
| 1681 | (provide 'simula-mode) | ||
| 1682 | |||
| 1291 | ;;; simula.el ends here | 1683 | ;;; simula.el ends here |