diff options
| -rw-r--r-- | lisp/progmodes/simula.el | 209 |
1 files changed, 160 insertions, 49 deletions
diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el index 31cae0b0fc5..bf4fec8c465 100644 --- a/lisp/progmodes/simula.el +++ b/lisp/progmodes/simula.el | |||
| @@ -132,6 +132,85 @@ for SIMULA mode to function correctly.") | |||
| 132 | (defvar simula-mode-syntax-table nil | 132 | (defvar simula-mode-syntax-table nil |
| 133 | "Syntax table in SIMULA mode buffers.") | 133 | "Syntax table in SIMULA mode buffers.") |
| 134 | 134 | ||
| 135 | ;; Regexps written with help from Alf-Ivar Holm <alfh@ifi.uio.no>. | ||
| 136 | (defconst simula-font-lock-keywords-1 | ||
| 137 | (list | ||
| 138 | ;; | ||
| 139 | ;; Comments and strings. | ||
| 140 | '(simula-match-string-or-comment 0 | ||
| 141 | (if (match-beginning 1) font-lock-string-face font-lock-comment-face)) | ||
| 142 | ;; | ||
| 143 | ;; Compiler directives. | ||
| 144 | '("^%\\([^ \t\n].*\\)" 1 font-lock-reference-face) | ||
| 145 | ;; | ||
| 146 | ;; Class and procedure names. | ||
| 147 | '("\\<\\(class\\|procedure\\)\\>[ \t]*\\(\\sw+\\)?" | ||
| 148 | (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) | ||
| 149 | ) | ||
| 150 | "Subdued level highlighting for Simula mode.") | ||
| 151 | |||
| 152 | (defconst simula-font-lock-keywords-2 | ||
| 153 | (append simula-font-lock-keywords-1 | ||
| 154 | (list | ||
| 155 | ;; | ||
| 156 | ;; Constants as references. | ||
| 157 | '("\\<\\(false\\|none\\|notext\\|true\\)\\>" . font-lock-reference-face) | ||
| 158 | ;; | ||
| 159 | ;; Keywords. | ||
| 160 | (concat "\\<\\(" | ||
| 161 | ; (make-regexp | ||
| 162 | ; '("activate" "after" "and" "at" "before" "begin" "delay" "do" | ||
| 163 | ; "else" "end" "eq" "eqv" "external" "for" "ge" "go" "goto" "gt" | ||
| 164 | ; "hidden" "if" "imp" "in" "inner" "inspect" "is" "label" "le" | ||
| 165 | ; "lt" "ne" "new" "not" "or" "otherwise" "prior" "protected" | ||
| 166 | ; "qua" "reactivate" "step" "switch" "then" "this" "to" "until" | ||
| 167 | ; "virtual" "when" "while")) | ||
| 168 | "a\\(ctivate\\|fter\\|nd\\|t\\)\\|be\\(fore\\|gin\\)\\|" | ||
| 169 | "d\\(elay\\|o\\)\\|e\\(lse\\|nd\\|qv?\\|xternal\\)\\|for\\|" | ||
| 170 | "g\\([eot]\\|oto\\)\\|hidden\\|i\\([fns]\\|mp\\|n\\(ner\\|" | ||
| 171 | "spect\\)\\)\\|l\\([et]\\|abel\\)\\|n\\(ew?\\|ot\\)\\|" | ||
| 172 | "o\\(r\\|therwise\\)\\|pr\\(ior\\|otected\\)\\|qua\\|" | ||
| 173 | "reactivate\\|s\\(tep\\|witch\\)\\|t\\(h\\(en\\|is\\)\\|o\\)\\|" | ||
| 174 | "until\\|virtual\\|wh\\(en\\|ile\\)" | ||
| 175 | "\\)\\>") | ||
| 176 | ;; | ||
| 177 | ;; Types. | ||
| 178 | (cons (concat "\\<\\(array\\|boolean\\|character\\|integer\\|" | ||
| 179 | "long\\|name\\|real\\|short\\|text\\|value\\|ref\\)\\>") | ||
| 180 | 'font-lock-type-face) | ||
| 181 | )) | ||
| 182 | "Medium level highlighting for Simula mode.") | ||
| 183 | |||
| 184 | (defconst simula-font-lock-keywords-3 | ||
| 185 | (append simula-font-lock-keywords-2 | ||
| 186 | (list | ||
| 187 | ;; | ||
| 188 | ;; Super-class names and super-slow. | ||
| 189 | '("\\<\\(\\sw+\\)[ \t]+class\\>" 1 font-lock-function-name-face) | ||
| 190 | ;; | ||
| 191 | ;; Types and their declarations. | ||
| 192 | (list (concat "\\<\\(array\\|boolean\\|character\\|integer\\|" | ||
| 193 | "long\\|name\\|real\\|short\\|text\\|value\\)\\>" | ||
| 194 | "\\([ \t]+\\sw+\\>\\)*") | ||
| 195 | '(font-lock-match-c++-style-declaration-item-and-skip-to-next | ||
| 196 | ;; Start with point after all type specifiers. | ||
| 197 | (goto-char (or (match-beginning 2) (match-end 1))) | ||
| 198 | ;; Finish with point after first type specifier. | ||
| 199 | (goto-char (match-end 1)) | ||
| 200 | ;; Fontify as a variable name. | ||
| 201 | (1 font-lock-variable-name-face))) | ||
| 202 | ;; | ||
| 203 | ;; Object references and their declarations. | ||
| 204 | '("\\<\\(ref\\)\\>[ \t]*\\((\\(\\sw+\\))\\)?" | ||
| 205 | (3 font-lock-function-name-face nil t) | ||
| 206 | (font-lock-match-c++-style-declaration-item-and-skip-to-next nil nil | ||
| 207 | (1 font-lock-variable-name-face))) | ||
| 208 | )) | ||
| 209 | "Gaudy level highlighting for Simula mode.") | ||
| 210 | |||
| 211 | (defvar simula-font-lock-keywords simula-font-lock-keywords-1 | ||
| 212 | "Default expressions to highlight in Simula mode.") | ||
| 213 | |||
| 135 | ; The following function is taken from cc-mode.el, | 214 | ; The following function is taken from cc-mode.el, |
| 136 | ; it determines the flavor of the Emacs running | 215 | ; it determines the flavor of the Emacs running |
| 137 | (defconst simula-emacs-features | 216 | (defconst simula-emacs-features |
| @@ -194,7 +273,7 @@ supported list, along with the values for this variable: | |||
| 194 | (modify-syntax-entry ?\[ "." simula-mode-syntax-table) | 273 | (modify-syntax-entry ?\[ "." simula-mode-syntax-table) |
| 195 | (modify-syntax-entry ?\\ "." simula-mode-syntax-table) | 274 | (modify-syntax-entry ?\\ "." simula-mode-syntax-table) |
| 196 | (modify-syntax-entry ?\] "." simula-mode-syntax-table) | 275 | (modify-syntax-entry ?\] "." simula-mode-syntax-table) |
| 197 | (modify-syntax-entry ?_ "w" simula-mode-syntax-table) | 276 | (modify-syntax-entry ?_ "_" simula-mode-syntax-table) |
| 198 | (modify-syntax-entry ?\| "." simula-mode-syntax-table) | 277 | (modify-syntax-entry ?\| "." simula-mode-syntax-table) |
| 199 | (modify-syntax-entry ?\{ "." simula-mode-syntax-table) | 278 | (modify-syntax-entry ?\{ "." simula-mode-syntax-table) |
| 200 | (modify-syntax-entry ?\} "." simula-mode-syntax-table)) | 279 | (modify-syntax-entry ?\} "." simula-mode-syntax-table)) |
| @@ -277,6 +356,7 @@ supported list, along with the values for this variable: | |||
| 277 | "Abbrev table in SIMULA mode buffers") | 356 | "Abbrev table in SIMULA mode buffers") |
| 278 | 357 | ||
| 279 | 358 | ||
| 359 | ;;;###autoload | ||
| 280 | (defun simula-mode () | 360 | (defun simula-mode () |
| 281 | "Major mode for editing SIMULA code. | 361 | "Major mode for editing SIMULA code. |
| 282 | \\{simula-mode-map} | 362 | \\{simula-mode-map} |
| @@ -349,6 +429,11 @@ at all." | |||
| 349 | (setq parse-sexp-ignore-comments nil) | 429 | (setq parse-sexp-ignore-comments nil) |
| 350 | (make-local-variable 'comment-multi-line) | 430 | (make-local-variable 'comment-multi-line) |
| 351 | (setq comment-multi-line t) | 431 | (setq comment-multi-line t) |
| 432 | (make-local-variable 'font-lock-defaults) | ||
| 433 | (setq font-lock-defaults | ||
| 434 | '((simula-font-lock-keywords simula-font-lock-keywords-1 | ||
| 435 | simula-font-lock-keywords-2 simula-font-lock-keywords-3) | ||
| 436 | t t ((?_ . "w")))) | ||
| 352 | (if simula-mode-abbrev-table | 437 | (if simula-mode-abbrev-table |
| 353 | () | 438 | () |
| 354 | (if simula-abbrev-file | 439 | (if simula-abbrev-file |
| @@ -1566,6 +1651,37 @@ If not nil and not t, move to limit of search and return nil." | |||
| 1566 | ("when" "WHEN" simula-electric-keyword) | 1651 | ("when" "WHEN" simula-electric-keyword) |
| 1567 | ("while" "WHILE" simula-expand-keyword)))) | 1652 | ("while" "WHILE" simula-expand-keyword)))) |
| 1568 | 1653 | ||
| 1654 | ;;; Font Lock mode support. | ||
| 1655 | (eval-when-compile | ||
| 1656 | (require 'cl)) | ||
| 1657 | |||
| 1658 | ;; SIMULA comments and strings are a mess. If we rely on the syntax table, | ||
| 1659 | ;; then %-comments may be shown incorrectly (and prematurely) ended by a | ||
| 1660 | ;; semicolon, !-comments by a newline and '-strings may screw up the rest of | ||
| 1661 | ;; the buffer. And of course we can't do comment- or end-comments using the | ||
| 1662 | ;; syntax table. We can do everything except end-comments in one fast regexp, | ||
| 1663 | ;; but we aught to do end-comments too, so we need a function. simon@gnu. | ||
| 1664 | (defun simula-match-string-or-comment (limit) | ||
| 1665 | ;; Return t if there is a string or comment before LIMIT. | ||
| 1666 | ;; Matches buffer text so that if (match-string 1) is non-nil, it is the | ||
| 1667 | ;; string. Otherwise, (match-string 0) is non-nil, and is the comment. | ||
| 1668 | (when (re-search-forward | ||
| 1669 | (eval-when-compile | ||
| 1670 | (concat "\\(\"[^\"\n]*\"\\|'\\(.\\|![0-9]+!\\)'\\)\\|" | ||
| 1671 | "\\(\\<end[ \t\n]+\\)\\|" | ||
| 1672 | "^%[ \t].*\\|\\(!\\|\\<comment\\>\\)[^;]*;?")) | ||
| 1673 | limit t) | ||
| 1674 | (when (match-beginning 3) | ||
| 1675 | ;; We've matched an end-comment. Yuck. Find the extent of it. | ||
| 1676 | (store-match-data | ||
| 1677 | (list (point) | ||
| 1678 | (if (re-search-forward "\\<\\(end\\|else\\|when\\|otherwise\\)\\>\\|;" | ||
| 1679 | limit 'move) | ||
| 1680 | (match-beginning 0) | ||
| 1681 | (point))))) | ||
| 1682 | t)) | ||
| 1683 | |||
| 1684 | ;;; Hilit mode support. | ||
| 1569 | (if (and (fboundp 'hilit-set-mode-patterns) | 1685 | (if (and (fboundp 'hilit-set-mode-patterns) |
| 1570 | (boundp 'hilit-patterns-alist) | 1686 | (boundp 'hilit-patterns-alist) |
| 1571 | (not (assoc 'simula-mode hilit-patterns-alist))) | 1687 | (not (assoc 'simula-mode hilit-patterns-alist))) |
| @@ -1579,65 +1695,60 @@ If not nil and not t, move to limit of search and return nil." | |||
| 1579 | ("!\\|\\<COMMENT\\>" ";" comment)) | 1695 | ("!\\|\\<COMMENT\\>" ";" comment)) |
| 1580 | nil 'case-insensitive)) | 1696 | nil 'case-insensitive)) |
| 1581 | 1697 | ||
| 1582 | (setq simula-find-comment-point -1 | 1698 | ;; None of this seems to be used by anything, including hilit19.el. simon@gnu. |
| 1583 | simula-find-comment-context nil) | 1699 | ;(setq simula-find-comment-point -1 |
| 1584 | 1700 | ; simula-find-comment-context nil) | |
| 1585 | ;; function used by hilit19 | 1701 | ; |
| 1586 | (defun simula-find-next-comment-region (param) | 1702 | ;;; function used by hilit19 |
| 1587 | "Return region (start end) cons of comment after point, or NIL" | 1703 | ;(defun simula-find-next-comment-region (param) |
| 1588 | (let (start end) | 1704 | ; "Return region (start end) cons of comment after point, or NIL" |
| 1589 | ;; This function is called repeatedly, check if point is | 1705 | ; (let (start end) |
| 1590 | ;; where we left it in the last call | 1706 | ; ;; This function is called repeatedly, check if point is |
| 1591 | (if (not (eq simula-find-comment-point (point))) | 1707 | ; ;; where we left it in the last call |
| 1592 | (setq simula-find-comment-point (point) | 1708 | ; (if (not (eq simula-find-comment-point (point))) |
| 1593 | simula-find-comment-context (simula-context))) | 1709 | ; (setq simula-find-comment-point (point) |
| 1594 | ;; loop as long as we haven't found the end of a comment | 1710 | ; simula-find-comment-context (simula-context))) |
| 1595 | (if (memq simula-find-comment-context '(0 1 2)) | 1711 | ; ;; loop as long as we haven't found the end of a comment |
| 1596 | (setq start (point)) | 1712 | ; (if (memq simula-find-comment-context '(0 1 2)) |
| 1597 | (if (re-search-forward "\\<end\\>\\|!\\|\"\\|'\\|^%\\|\\<comment\\>" | 1713 | ; (setq start (point)) |
| 1598 | nil 'move) | 1714 | ; (if (re-search-forward "\\<end\\>\\|!\\|\"\\|'\\|^%\\|\\<comment\\>" |
| 1599 | (let ((previous-char (preceding-char))) | 1715 | ; nil 'move) |
| 1600 | (cond | 1716 | ; (let ((previous-char (preceding-char))) |
| 1601 | ((memq previous-char '(?d ?D)) | 1717 | ; (cond |
| 1602 | (setq start (point) | 1718 | ; ((memq previous-char '(?d ?D)) |
| 1603 | simula-find-comment-context 2)) | 1719 | ; (setq start (point) |
| 1604 | ((memq previous-char '(?t ?T ?\!)) | 1720 | ; simula-find-comment-context 2)) |
| 1605 | (setq start (point) | 1721 | ; ((memq previous-char '(?t ?T ?\!)) |
| 1606 | simula-find-comment-context 0)) | 1722 | ; (setq start (point) |
| 1607 | ((eq previous-char ?%) | 1723 | ; simula-find-comment-context 0)) |
| 1608 | (setq start (point) | 1724 | ; ((eq previous-char ?%) |
| 1609 | simula-find-comment-context 0)))))) | 1725 | ; (setq start (point) |
| 1610 | ;; BUG: the following (0 2) branches don't take into account intermixing | 1726 | ; simula-find-comment-context 0)))))) |
| 1611 | ;; directive lines | 1727 | ; ;; BUG: the following (0 2) branches don't take into account intermixing |
| 1612 | (cond | 1728 | ; ;; directive lines |
| 1613 | ((eq simula-find-comment-context 0) | 1729 | ; (cond |
| 1614 | (search-forward ";" nil 'move)) | 1730 | ; ((eq simula-find-comment-context 0) |
| 1615 | ((eq simula-find-comment-context 1) | 1731 | ; (search-forward ";" nil 'move)) |
| 1616 | (beginning-of-line 2)) | 1732 | ; ((eq simula-find-comment-context 1) |
| 1617 | ((eq simula-find-comment-context 2) | 1733 | ; (beginning-of-line 2)) |
| 1618 | (re-search-forward ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\" (point-max) 'move))) | 1734 | ; ((eq simula-find-comment-context 2) |
| 1619 | (if start | 1735 | ; (re-search-forward ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\" (point-max) 'move))) |
| 1620 | (setq end (point))) | 1736 | ; (if start |
| 1621 | ;; save point for later calls to this function | 1737 | ; (setq end (point))) |
| 1622 | (setq simula-find-comment-point (if end (point) -1)) | 1738 | ; ;; save point for later calls to this function |
| 1623 | (and end (cons start end)))) | 1739 | ; (setq simula-find-comment-point (if end (point) -1)) |
| 1740 | ; (and end (cons start end)))) | ||
| 1624 | 1741 | ||
| 1625 | ;; defuns for submitting bug reports | 1742 | ;; defuns for submitting bug reports |
| 1626 | 1743 | ||
| 1627 | (defconst simula-mode-help-address "simula-mode@ifi.uio.no" | 1744 | (defconst simula-mode-help-address "simula-mode@ifi.uio.no" |
| 1628 | "Address accepting submission of simula-mode bug reports.") | 1745 | "Address accepting submission of simula-mode bug reports.") |
| 1629 | 1746 | ||
| 1630 | ;; get reporter-submit-bug-report when byte-compiling | ||
| 1631 | (and (fboundp 'eval-when-compile) | ||
| 1632 | (eval-when-compile | ||
| 1633 | (require 'reporter))) | ||
| 1634 | |||
| 1635 | (defun simula-submit-bug-report () | 1747 | (defun simula-submit-bug-report () |
| 1636 | "Submit via mail a bug report on simula-mode." | 1748 | "Submit via mail a bug report on simula-mode." |
| 1637 | (interactive) | 1749 | (interactive) |
| 1638 | (and | 1750 | (and |
| 1639 | (y-or-n-p "Do you want to submit a report on simula-mode? ") | 1751 | (y-or-n-p "Do you want to submit a report on simula-mode? ") |
| 1640 | (require 'reporter) | ||
| 1641 | (reporter-submit-bug-report | 1752 | (reporter-submit-bug-report |
| 1642 | simula-mode-help-address | 1753 | simula-mode-help-address |
| 1643 | (concat "simula-mode from Emacs " emacs-version) | 1754 | (concat "simula-mode from Emacs " emacs-version) |