diff options
| author | Tom Tromey | 2013-06-03 12:25:05 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-06-03 12:25:05 -0600 |
| commit | 68359abba96d7ec4db8aab3d3dd9cf1105c3bab5 (patch) | |
| tree | 862703e7e1a1888170136a8296a5750d6b2ae2eb /lisp/progmodes | |
| parent | cbcba8ce7f980b01c18c0fd561ef6687b1361507 (diff) | |
| parent | e2d8a6f0a229b4ebe26484b892ec4f14888f58b6 (diff) | |
| download | emacs-68359abba96d7ec4db8aab3d3dd9cf1105c3bab5.tar.gz emacs-68359abba96d7ec4db8aab3d3dd9cf1105c3bab5.zip | |
merge from trunk; clean up some issues
Diffstat (limited to 'lisp/progmodes')
45 files changed, 4428 insertions, 3203 deletions
diff --git a/lisp/progmodes/ada-mode.el b/lisp/progmodes/ada-mode.el index 3709aa26bbe..805444d08b9 100644 --- a/lisp/progmodes/ada-mode.el +++ b/lisp/progmodes/ada-mode.el | |||
| @@ -457,15 +457,8 @@ The extensions should include a `.' if needed.") | |||
| 457 | (defvar ada-mode-extra-prefix "\C-c\C-q" | 457 | (defvar ada-mode-extra-prefix "\C-c\C-q" |
| 458 | "Prefix key to access `ada-mode-extra-map' functions.") | 458 | "Prefix key to access `ada-mode-extra-map' functions.") |
| 459 | 459 | ||
| 460 | (defvar ada-mode-abbrev-table nil | 460 | (define-abbrev-table 'ada-mode-abbrev-table () |
| 461 | "Local abbrev table for Ada mode.") | 461 | "Local abbrev table for Ada mode.") |
| 462 | (define-abbrev-table 'ada-mode-abbrev-table ()) | ||
| 463 | |||
| 464 | (defvar ada-mode-syntax-table nil | ||
| 465 | "Syntax table to be used for editing Ada source code.") | ||
| 466 | |||
| 467 | (defvar ada-mode-symbol-syntax-table nil | ||
| 468 | "Syntax table for Ada, where `_' is a word constituent.") | ||
| 469 | 462 | ||
| 470 | (eval-when-compile | 463 | (eval-when-compile |
| 471 | ;; These values are used in eval-when-compile expressions. | 464 | ;; These values are used in eval-when-compile expressions. |
| @@ -845,61 +838,58 @@ the 4 file locations can be clicked on and jumped to." | |||
| 845 | ;; better is available on XEmacs. | 838 | ;; better is available on XEmacs. |
| 846 | ;;------------------------------------------------------------------------- | 839 | ;;------------------------------------------------------------------------- |
| 847 | 840 | ||
| 848 | (defun ada-create-syntax-table () | 841 | (defvar ada-mode-syntax-table |
| 849 | "Create the two syntax tables use in the Ada mode. | 842 | (let ((st (make-syntax-table))) |
| 850 | The standard table declares `_' as a symbol constituent, the second one | 843 | ;; Define string brackets (`%' is alternative string bracket, but |
| 851 | declares it as a word constituent." | 844 | ;; almost never used as such and throws font-lock and indentation |
| 852 | (interactive) | 845 | ;; off the track.) |
| 853 | (setq ada-mode-syntax-table (make-syntax-table)) | 846 | (modify-syntax-entry ?% "$" st) |
| 854 | 847 | (modify-syntax-entry ?\" "\"" st) | |
| 855 | ;; define string brackets (`%' is alternative string bracket, but | 848 | |
| 856 | ;; almost never used as such and throws font-lock and indentation | 849 | (modify-syntax-entry ?: "." st) |
| 857 | ;; off the track.) | 850 | (modify-syntax-entry ?\; "." st) |
| 858 | (modify-syntax-entry ?% "$" ada-mode-syntax-table) | 851 | (modify-syntax-entry ?& "." st) |
| 859 | (modify-syntax-entry ?\" "\"" ada-mode-syntax-table) | 852 | (modify-syntax-entry ?\| "." st) |
| 860 | 853 | (modify-syntax-entry ?+ "." st) | |
| 861 | (modify-syntax-entry ?: "." ada-mode-syntax-table) | 854 | (modify-syntax-entry ?* "." st) |
| 862 | (modify-syntax-entry ?\; "." ada-mode-syntax-table) | 855 | (modify-syntax-entry ?/ "." st) |
| 863 | (modify-syntax-entry ?& "." ada-mode-syntax-table) | 856 | (modify-syntax-entry ?= "." st) |
| 864 | (modify-syntax-entry ?\| "." ada-mode-syntax-table) | 857 | (modify-syntax-entry ?< "." st) |
| 865 | (modify-syntax-entry ?+ "." ada-mode-syntax-table) | 858 | (modify-syntax-entry ?> "." st) |
| 866 | (modify-syntax-entry ?* "." ada-mode-syntax-table) | 859 | (modify-syntax-entry ?$ "." st) |
| 867 | (modify-syntax-entry ?/ "." ada-mode-syntax-table) | 860 | (modify-syntax-entry ?\[ "." st) |
| 868 | (modify-syntax-entry ?= "." ada-mode-syntax-table) | 861 | (modify-syntax-entry ?\] "." st) |
| 869 | (modify-syntax-entry ?< "." ada-mode-syntax-table) | 862 | (modify-syntax-entry ?\{ "." st) |
| 870 | (modify-syntax-entry ?> "." ada-mode-syntax-table) | 863 | (modify-syntax-entry ?\} "." st) |
| 871 | (modify-syntax-entry ?$ "." ada-mode-syntax-table) | 864 | (modify-syntax-entry ?. "." st) |
| 872 | (modify-syntax-entry ?\[ "." ada-mode-syntax-table) | 865 | (modify-syntax-entry ?\\ "." st) |
| 873 | (modify-syntax-entry ?\] "." ada-mode-syntax-table) | 866 | (modify-syntax-entry ?\' "." st) |
| 874 | (modify-syntax-entry ?\{ "." ada-mode-syntax-table) | 867 | |
| 875 | (modify-syntax-entry ?\} "." ada-mode-syntax-table) | 868 | ;; A single hyphen is punctuation, but a double hyphen starts a comment. |
| 876 | (modify-syntax-entry ?. "." ada-mode-syntax-table) | 869 | (modify-syntax-entry ?- ". 12" st) |
| 877 | (modify-syntax-entry ?\\ "." ada-mode-syntax-table) | 870 | |
| 878 | (modify-syntax-entry ?\' "." ada-mode-syntax-table) | 871 | ;; See the comment above on grammar related function for the special |
| 879 | 872 | ;; setup for '#'. | |
| 880 | ;; a single hyphen is punctuation, but a double hyphen starts a comment | 873 | (modify-syntax-entry ?# (if (featurep 'xemacs) "<" "$") st) |
| 881 | (modify-syntax-entry ?- ". 12" ada-mode-syntax-table) | 874 | |
| 882 | 875 | ;; And \f and \n end a comment. | |
| 883 | ;; See the comment above on grammar related function for the special | 876 | (modify-syntax-entry ?\f "> " st) |
| 884 | ;; setup for '#'. | 877 | (modify-syntax-entry ?\n "> " st) |
| 885 | (if (featurep 'xemacs) | 878 | |
| 886 | (modify-syntax-entry ?# "<" ada-mode-syntax-table) | 879 | ;; Define what belongs in Ada symbols. |
| 887 | (modify-syntax-entry ?# "$" ada-mode-syntax-table)) | 880 | (modify-syntax-entry ?_ "_" st) |
| 888 | 881 | ||
| 889 | ;; and \f and \n end a comment | 882 | ;; Define parentheses to match. |
| 890 | (modify-syntax-entry ?\f "> " ada-mode-syntax-table) | 883 | (modify-syntax-entry ?\( "()" st) |
| 891 | (modify-syntax-entry ?\n "> " ada-mode-syntax-table) | 884 | (modify-syntax-entry ?\) ")(" st) |
| 892 | 885 | st) | |
| 893 | ;; define what belongs in Ada symbols | 886 | "Syntax table to be used for editing Ada source code.") |
| 894 | (modify-syntax-entry ?_ "_" ada-mode-syntax-table) | 887 | |
| 895 | 888 | (defvar ada-mode-symbol-syntax-table | |
| 896 | ;; define parentheses to match | 889 | (let ((st (make-syntax-table ada-mode-syntax-table))) |
| 897 | (modify-syntax-entry ?\( "()" ada-mode-syntax-table) | 890 | (modify-syntax-entry ?_ "w" st) |
| 898 | (modify-syntax-entry ?\) ")(" ada-mode-syntax-table) | 891 | st) |
| 899 | 892 | "Syntax table for Ada, where `_' is a word constituent.") | |
| 900 | (setq ada-mode-symbol-syntax-table (copy-syntax-table ada-mode-syntax-table)) | ||
| 901 | (modify-syntax-entry ?_ "w" ada-mode-symbol-syntax-table) | ||
| 902 | ) | ||
| 903 | 893 | ||
| 904 | ;; Support of special characters in XEmacs (see the comments at the beginning | 894 | ;; Support of special characters in XEmacs (see the comments at the beginning |
| 905 | ;; of the section on Grammar related functions). | 895 | ;; of the section on Grammar related functions). |
| @@ -1293,7 +1283,7 @@ the file name." | |||
| 1293 | (if ada-popup-key | 1283 | (if ada-popup-key |
| 1294 | (define-key ada-mode-map ada-popup-key 'ada-popup-menu)) | 1284 | (define-key ada-mode-map ada-popup-key 'ada-popup-menu)) |
| 1295 | 1285 | ||
| 1296 | ;; Support for Abbreviations (the user still need to "M-x abbrev-mode" | 1286 | ;; Support for Abbreviations (the user still needs to "M-x abbrev-mode"). |
| 1297 | (setq local-abbrev-table ada-mode-abbrev-table) | 1287 | (setq local-abbrev-table ada-mode-abbrev-table) |
| 1298 | 1288 | ||
| 1299 | ;; Support for which-function mode | 1289 | ;; Support for which-function mode |
| @@ -1625,9 +1615,8 @@ ARG is the prefix the user entered with \\[universal-argument]." | |||
| 1625 | (let ((lastk last-command-event)) | 1615 | (let ((lastk last-command-event)) |
| 1626 | 1616 | ||
| 1627 | (with-syntax-table ada-mode-symbol-syntax-table | 1617 | (with-syntax-table ada-mode-symbol-syntax-table |
| 1628 | (cond ((or (eq lastk ?\n) | 1618 | (cond ((memq lastk '(?\n ?\r)) |
| 1629 | (eq lastk ?\r)) | 1619 | ;; Horrible kludge. |
| 1630 | ;; horrible kludge | ||
| 1631 | (insert " ") | 1620 | (insert " ") |
| 1632 | (ada-adjust-case) | 1621 | (ada-adjust-case) |
| 1633 | ;; horrible dekludge | 1622 | ;; horrible dekludge |
| @@ -1706,9 +1695,7 @@ ARG is ignored, and is there for compatibility with `capitalize-word' only." | |||
| 1706 | (interactive) | 1695 | (interactive) |
| 1707 | (let ((end (save-excursion (skip-syntax-forward "w") (point))) | 1696 | (let ((end (save-excursion (skip-syntax-forward "w") (point))) |
| 1708 | (begin (save-excursion (skip-syntax-backward "w") (point)))) | 1697 | (begin (save-excursion (skip-syntax-backward "w") (point)))) |
| 1709 | (modify-syntax-entry ?_ "_") | 1698 | (capitalize-region begin end))) |
| 1710 | (capitalize-region begin end) | ||
| 1711 | (modify-syntax-entry ?_ "w"))) | ||
| 1712 | 1699 | ||
| 1713 | (defun ada-adjust-case-region (from to) | 1700 | (defun ada-adjust-case-region (from to) |
| 1714 | "Adjust the case of all words in the region between FROM and TO. | 1701 | "Adjust the case of all words in the region between FROM and TO. |
| @@ -2165,7 +2152,7 @@ and the offset." | |||
| 2165 | (unwind-protect | 2152 | (unwind-protect |
| 2166 | (with-syntax-table ada-mode-symbol-syntax-table | 2153 | (with-syntax-table ada-mode-symbol-syntax-table |
| 2167 | 2154 | ||
| 2168 | ;; This need to be done here so that the advice is not always | 2155 | ;; This needs to be done here so that the advice is not always |
| 2169 | ;; activated (this might interact badly with other modes) | 2156 | ;; activated (this might interact badly with other modes) |
| 2170 | (if (featurep 'xemacs) | 2157 | (if (featurep 'xemacs) |
| 2171 | (ad-activate 'parse-partial-sexp t)) | 2158 | (ad-activate 'parse-partial-sexp t)) |
| @@ -3419,27 +3406,23 @@ Stop the search at LIMIT." | |||
| 3419 | If BACKWARD is non-nil, jump to the beginning of the previous word. | 3406 | If BACKWARD is non-nil, jump to the beginning of the previous word. |
| 3420 | Return the new position of point or nil if not found." | 3407 | Return the new position of point or nil if not found." |
| 3421 | (let ((match-cons nil) | 3408 | (let ((match-cons nil) |
| 3422 | (orgpoint (point)) | 3409 | (orgpoint (point))) |
| 3423 | (old-syntax (char-to-string (char-syntax ?_)))) | ||
| 3424 | (modify-syntax-entry ?_ "w") | ||
| 3425 | (unless backward | 3410 | (unless backward |
| 3426 | (skip-syntax-forward "w")) | 3411 | (skip-syntax-forward "w_")) |
| 3427 | (if (setq match-cons | 3412 | (if (setq match-cons |
| 3428 | (ada-search-ignore-string-comment "\\w" backward nil t)) | 3413 | (ada-search-ignore-string-comment "\\sw\\|\\s_" backward nil t)) |
| 3429 | ;; | 3414 | ;; |
| 3430 | ;; move to the beginning of the word found | 3415 | ;; move to the beginning of the word found |
| 3431 | ;; | 3416 | ;; |
| 3432 | (progn | 3417 | (progn |
| 3433 | (goto-char (car match-cons)) | 3418 | (goto-char (car match-cons)) |
| 3434 | (skip-syntax-backward "w") | 3419 | (skip-syntax-backward "w_") |
| 3435 | (point)) | 3420 | (point)) |
| 3436 | ;; | 3421 | ;; |
| 3437 | ;; if not found, restore old position of point | 3422 | ;; if not found, restore old position of point |
| 3438 | ;; | 3423 | ;; |
| 3439 | (goto-char orgpoint) | 3424 | (goto-char orgpoint) |
| 3440 | 'nil) | 3425 | 'nil))) |
| 3441 | (modify-syntax-entry ?_ old-syntax)) | ||
| 3442 | ) | ||
| 3443 | 3426 | ||
| 3444 | 3427 | ||
| 3445 | (defun ada-check-matching-start (keyword) | 3428 | (defun ada-check-matching-start (keyword) |
| @@ -5431,9 +5414,6 @@ This function typically is to be hooked into `ff-file-created-hook'." | |||
| 5431 | (ada-create-keymap) | 5414 | (ada-create-keymap) |
| 5432 | (ada-create-menu) | 5415 | (ada-create-menu) |
| 5433 | 5416 | ||
| 5434 | ;; Create the syntax tables, but do not activate them | ||
| 5435 | (ada-create-syntax-table) | ||
| 5436 | |||
| 5437 | ;; Add the default extensions (and set up speedbar) | 5417 | ;; Add the default extensions (and set up speedbar) |
| 5438 | (ada-add-extensions ".ads" ".adb") | 5418 | (ada-add-extensions ".ads" ".adb") |
| 5439 | ;; This two files are generated by GNAT when running with -gnatD | 5419 | ;; This two files are generated by GNAT when running with -gnatD |
diff --git a/lisp/progmodes/autoconf.el b/lisp/progmodes/autoconf.el index 8a99ad6e1b3..e6eaea985af 100644 --- a/lisp/progmodes/autoconf.el +++ b/lisp/progmodes/autoconf.el | |||
| @@ -41,10 +41,10 @@ | |||
| 41 | "Hook run by `autoconf-mode'.") | 41 | "Hook run by `autoconf-mode'.") |
| 42 | 42 | ||
| 43 | (defconst autoconf-definition-regexp | 43 | (defconst autoconf-definition-regexp |
| 44 | "A\\(?:H_TEMPLATE\\|C_\\(?:SUBST\\|DEFINE\\(?:_UNQUOTED\\)?\\)\\)(\\[*\\(\\sw+\\)\\]*") | 44 | "A\\(?:H_TEMPLATE\\|C_\\(?:SUBST\\|DEFINE\\(?:_UNQUOTED\\)?\\)\\)(\\[*\\(\\(?:\\sw\\|\\s_\\)+\\)\\]*") |
| 45 | 45 | ||
| 46 | (defvar autoconf-font-lock-keywords | 46 | (defvar autoconf-font-lock-keywords |
| 47 | `(("\\_<A[CHMS]_\\sw+" . font-lock-keyword-face) | 47 | `(("\\_<A[CHMS]_\\(?:\\sw\\|\\s_\\)+" . font-lock-keyword-face) |
| 48 | (,autoconf-definition-regexp | 48 | (,autoconf-definition-regexp |
| 49 | 1 font-lock-function-name-face) | 49 | 1 font-lock-function-name-face) |
| 50 | ;; Are any other M4 keywords really appropriate for configure.ac, | 50 | ;; Are any other M4 keywords really appropriate for configure.ac, |
| @@ -67,13 +67,11 @@ | |||
| 67 | This version looks back for an AC_DEFINE or AC_SUBST. It will stop | 67 | This version looks back for an AC_DEFINE or AC_SUBST. It will stop |
| 68 | searching backwards at another AC_... command." | 68 | searching backwards at another AC_... command." |
| 69 | (save-excursion | 69 | (save-excursion |
| 70 | (with-syntax-table (copy-syntax-table autoconf-mode-syntax-table) | 70 | (skip-syntax-forward "w_" (line-end-position)) |
| 71 | (modify-syntax-entry ?_ "w") | 71 | (if (re-search-backward autoconf-definition-regexp |
| 72 | (skip-syntax-forward "w" (line-end-position)) | 72 | (save-excursion (beginning-of-defun) (point)) |
| 73 | (if (re-search-backward autoconf-definition-regexp | 73 | t) |
| 74 | (save-excursion (beginning-of-defun) (point)) | 74 | (match-string-no-properties 1)))) |
| 75 | t) | ||
| 76 | (match-string-no-properties 1))))) | ||
| 77 | 75 | ||
| 78 | ;;;###autoload | 76 | ;;;###autoload |
| 79 | (define-derived-mode autoconf-mode prog-mode "Autoconf" | 77 | (define-derived-mode autoconf-mode prog-mode "Autoconf" |
| @@ -85,9 +83,8 @@ searching backwards at another AC_... command." | |||
| 85 | (setq-local syntax-propertize-function | 83 | (setq-local syntax-propertize-function |
| 86 | (syntax-propertize-rules ("\\<dnl\\>" (0 "<")))) | 84 | (syntax-propertize-rules ("\\<dnl\\>" (0 "<")))) |
| 87 | (setq-local font-lock-defaults | 85 | (setq-local font-lock-defaults |
| 88 | `(autoconf-font-lock-keywords nil nil (("_" . "w")))) | 86 | `(autoconf-font-lock-keywords nil nil)) |
| 89 | (setq-local imenu-generic-expression autoconf-imenu-generic-expression) | 87 | (setq-local imenu-generic-expression autoconf-imenu-generic-expression) |
| 90 | (setq-local imenu-syntax-alist '(("_" . "w"))) | ||
| 91 | (setq-local indent-line-function #'indent-relative) | 88 | (setq-local indent-line-function #'indent-relative) |
| 92 | (setq-local add-log-current-defun-function | 89 | (setq-local add-log-current-defun-function |
| 93 | #'autoconf-current-defun-function)) | 90 | #'autoconf-current-defun-function)) |
diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el index e41455f7883..337a5292417 100644 --- a/lisp/progmodes/cc-bytecomp.el +++ b/lisp/progmodes/cc-bytecomp.el | |||
| @@ -232,6 +232,9 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere")) | |||
| 232 | (cc-bytecomp-setup-environment) | 232 | (cc-bytecomp-setup-environment) |
| 233 | t)))) | 233 | t)))) |
| 234 | 234 | ||
| 235 | (defvar cc-bytecomp-noruntime-functions nil | ||
| 236 | "Saved value of `byte-compile-noruntime-functions'.") | ||
| 237 | |||
| 235 | (defmacro cc-require (cc-part) | 238 | (defmacro cc-require (cc-part) |
| 236 | "Force loading of the corresponding .el file in the current directory | 239 | "Force loading of the corresponding .el file in the current directory |
| 237 | during compilation, but compile in a `require'. Don't use within | 240 | during compilation, but compile in a `require'. Don't use within |
| @@ -240,7 +243,16 @@ during compilation, but compile in a `require'. Don't use within | |||
| 240 | Having cyclic cc-require's will result in infinite recursion. That's | 243 | Having cyclic cc-require's will result in infinite recursion. That's |
| 241 | somewhat intentional." | 244 | somewhat intentional." |
| 242 | `(progn | 245 | `(progn |
| 243 | (eval-when-compile (cc-bytecomp-load (symbol-name ,cc-part))) | 246 | (eval-when-compile |
| 247 | (setq cc-bytecomp-noruntime-functions byte-compile-noruntime-functions) | ||
| 248 | (cc-bytecomp-load (symbol-name ,cc-part))) | ||
| 249 | ;; Hack to suppress spurious "might not be defined at runtime" warnings. | ||
| 250 | ;; The basic issue is that | ||
| 251 | ;; (eval-when-compile (require 'foo)) | ||
| 252 | ;; (require 'foo) | ||
| 253 | ;; produces bogus noruntime warnings about functions from foo. | ||
| 254 | (eval-when-compile | ||
| 255 | (setq byte-compile-noruntime-functions cc-bytecomp-noruntime-functions)) | ||
| 244 | (require ,cc-part))) | 256 | (require ,cc-part))) |
| 245 | 257 | ||
| 246 | (defmacro cc-provide (feature) | 258 | (defmacro cc-provide (feature) |
| @@ -266,7 +278,7 @@ somewhat intentional." | |||
| 266 | during compilation, but do a compile time `require' otherwise. Don't | 278 | during compilation, but do a compile time `require' otherwise. Don't |
| 267 | use within `eval-when-compile'." | 279 | use within `eval-when-compile'." |
| 268 | `(eval-when-compile | 280 | `(eval-when-compile |
| 269 | (if (and (featurep 'cc-bytecomp) | 281 | (if (and (fboundp 'cc-bytecomp-is-compiling) |
| 270 | (cc-bytecomp-is-compiling)) | 282 | (cc-bytecomp-is-compiling)) |
| 271 | (if (or (not load-in-progress) | 283 | (if (or (not load-in-progress) |
| 272 | (not (featurep ,cc-part))) | 284 | (not (featurep ,cc-part))) |
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 0bb804799dc..dc6ed1348d1 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | (cc-require 'cc-engine) | 45 | (cc-require 'cc-engine) |
| 46 | 46 | ||
| 47 | ;; Silence the compiler. | 47 | ;; Silence the compiler. |
| 48 | (cc-bytecomp-defun delete-forward-p) ; XEmacs | ||
| 49 | (cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge | 48 | (cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge |
| 50 | ; which looks at this. | 49 | ; which looks at this. |
| 51 | 50 | ||
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 48236c2dca2..b90a01dcb3b 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el | |||
| @@ -48,16 +48,12 @@ | |||
| 48 | 48 | ||
| 49 | ;; Silence the compiler. | 49 | ;; Silence the compiler. |
| 50 | (cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el | 50 | (cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el |
| 51 | (cc-bytecomp-defun buffer-syntactic-context-depth) ; XEmacs | ||
| 52 | (cc-bytecomp-defun region-active-p) ; XEmacs | 51 | (cc-bytecomp-defun region-active-p) ; XEmacs |
| 53 | (cc-bytecomp-defvar zmacs-region-stays) ; XEmacs | ||
| 54 | (cc-bytecomp-defvar zmacs-regions) ; XEmacs | ||
| 55 | (cc-bytecomp-defvar mark-active) ; Emacs | 52 | (cc-bytecomp-defvar mark-active) ; Emacs |
| 56 | (cc-bytecomp-defvar deactivate-mark) ; Emacs | 53 | (cc-bytecomp-defvar deactivate-mark) ; Emacs |
| 57 | (cc-bytecomp-defvar inhibit-point-motion-hooks) ; Emacs | 54 | (cc-bytecomp-defvar inhibit-point-motion-hooks) ; Emacs |
| 58 | (cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs | 55 | (cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs |
| 59 | (cc-bytecomp-defvar text-property-default-nonsticky) ; Emacs 21 | 56 | (cc-bytecomp-defvar text-property-default-nonsticky) ; Emacs 21 |
| 60 | (cc-bytecomp-defvar lookup-syntax-properties) ; XEmacs | ||
| 61 | (cc-bytecomp-defun string-to-syntax) ; Emacs 21 | 57 | (cc-bytecomp-defun string-to-syntax) ; Emacs 21 |
| 62 | 58 | ||
| 63 | 59 | ||
| @@ -93,7 +89,7 @@ | |||
| 93 | 89 | ||
| 94 | ;;; Variables also used at compile time. | 90 | ;;; Variables also used at compile time. |
| 95 | 91 | ||
| 96 | (defconst c-version "5.32.4" | 92 | (defconst c-version "5.32.5" |
| 97 | "CC Mode version number.") | 93 | "CC Mode version number.") |
| 98 | 94 | ||
| 99 | (defconst c-version-sym (intern c-version)) | 95 | (defconst c-version-sym (intern c-version)) |
| @@ -334,6 +330,8 @@ to it is returned. This function does not modify the point or the mark." | |||
| 334 | (defmacro c-region-is-active-p () | 330 | (defmacro c-region-is-active-p () |
| 335 | ;; Return t when the region is active. The determination of region | 331 | ;; Return t when the region is active. The determination of region |
| 336 | ;; activeness is different in both Emacs and XEmacs. | 332 | ;; activeness is different in both Emacs and XEmacs. |
| 333 | ;; FIXME? Emacs has region-active-p since 23.1, so maybe this test | ||
| 334 | ;; should be updated. | ||
| 337 | (if (cc-bytecomp-boundp 'mark-active) | 335 | (if (cc-bytecomp-boundp 'mark-active) |
| 338 | ;; Emacs. | 336 | ;; Emacs. |
| 339 | 'mark-active | 337 | 'mark-active |
| @@ -343,7 +341,7 @@ to it is returned. This function does not modify the point or the mark." | |||
| 343 | (defmacro c-set-region-active (activate) | 341 | (defmacro c-set-region-active (activate) |
| 344 | ;; Activate the region if ACTIVE is non-nil, deactivate it | 342 | ;; Activate the region if ACTIVE is non-nil, deactivate it |
| 345 | ;; otherwise. Covers the differences between Emacs and XEmacs. | 343 | ;; otherwise. Covers the differences between Emacs and XEmacs. |
| 346 | (if (cc-bytecomp-fboundp 'zmacs-activate-region) | 344 | (if (fboundp 'zmacs-activate-region) |
| 347 | ;; XEmacs. | 345 | ;; XEmacs. |
| 348 | `(if ,activate | 346 | `(if ,activate |
| 349 | (zmacs-activate-region) | 347 | (zmacs-activate-region) |
| @@ -707,9 +705,9 @@ be after it." | |||
| 707 | ;; `c-parse-state'. | 705 | ;; `c-parse-state'. |
| 708 | 706 | ||
| 709 | `(progn | 707 | `(progn |
| 710 | (if (and ,(cc-bytecomp-fboundp 'buffer-syntactic-context-depth) | 708 | (if (and ,(fboundp 'buffer-syntactic-context-depth) |
| 711 | c-enable-xemacs-performance-kludge-p) | 709 | c-enable-xemacs-performance-kludge-p) |
| 712 | ,(when (cc-bytecomp-fboundp 'buffer-syntactic-context-depth) | 710 | ,(when (fboundp 'buffer-syntactic-context-depth) |
| 713 | ;; XEmacs only. This can improve the performance of | 711 | ;; XEmacs only. This can improve the performance of |
| 714 | ;; c-parse-state to between 3 and 60 times faster when | 712 | ;; c-parse-state to between 3 and 60 times faster when |
| 715 | ;; braces are hung. It can also degrade performance by | 713 | ;; braces are hung. It can also degrade performance by |
| @@ -1606,7 +1604,7 @@ non-nil, a caret is prepended to invert the set." | |||
| 1606 | (let ((buf (generate-new-buffer " test")) | 1604 | (let ((buf (generate-new-buffer " test")) |
| 1607 | parse-sexp-lookup-properties | 1605 | parse-sexp-lookup-properties |
| 1608 | parse-sexp-ignore-comments | 1606 | parse-sexp-ignore-comments |
| 1609 | lookup-syntax-properties) | 1607 | lookup-syntax-properties) ; XEmacs |
| 1610 | (with-current-buffer buf | 1608 | (with-current-buffer buf |
| 1611 | (set-syntax-table (make-syntax-table)) | 1609 | (set-syntax-table (make-syntax-table)) |
| 1612 | 1610 | ||
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 368b1fc50dc..b0c0bfd7bde 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -147,9 +147,6 @@ | |||
| 147 | (cc-require-when-compile 'cc-langs) | 147 | (cc-require-when-compile 'cc-langs) |
| 148 | (cc-require 'cc-vars) | 148 | (cc-require 'cc-vars) |
| 149 | 149 | ||
| 150 | ;; Silence the compiler. | ||
| 151 | (cc-bytecomp-defun buffer-syntactic-context) ; XEmacs | ||
| 152 | |||
| 153 | 150 | ||
| 154 | ;; Make declarations for all the `c-lang-defvar' variables in cc-langs. | 151 | ;; Make declarations for all the `c-lang-defvar' variables in cc-langs. |
| 155 | 152 | ||
| @@ -2180,32 +2177,45 @@ comment at the start of cc-engine.el for more info." | |||
| 2180 | ;; reduced by buffer changes, and increased by invocations of | 2177 | ;; reduced by buffer changes, and increased by invocations of |
| 2181 | ;; `c-state-literal-at'. FIXME!!! | 2178 | ;; `c-state-literal-at'. FIXME!!! |
| 2182 | 2179 | ||
| 2183 | (defsubst c-state-pp-to-literal (from to) | 2180 | (defsubst c-state-pp-to-literal (from to &optional not-in-delimiter) |
| 2184 | ;; Do a parse-partial-sexp from FROM to TO, returning either | 2181 | ;; Do a parse-partial-sexp from FROM to TO, returning either |
| 2185 | ;; (STATE TYPE (BEG . END)) if TO is in a literal; or | 2182 | ;; (STATE TYPE (BEG . END)) if TO is in a literal; or |
| 2186 | ;; (STATE) otherwise, | 2183 | ;; (STATE) otherwise, |
| 2187 | ;; where STATE is the parsing state at TO, TYPE is the type of the literal | 2184 | ;; where STATE is the parsing state at TO, TYPE is the type of the literal |
| 2188 | ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal. | 2185 | ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal. |
| 2189 | ;; | 2186 | ;; |
| 2187 | ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character | ||
| 2188 | ;; comment opener, this is recognized as being in a comment literal. | ||
| 2189 | ;; | ||
| 2190 | ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote), | 2190 | ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote), |
| 2191 | ;; 7 (comment type) and 8 (start of comment/string) (and possibly 9) of | 2191 | ;; 7 (comment type) and 8 (start of comment/string) (and possibly 9) of |
| 2192 | ;; STATE are valid. | 2192 | ;; STATE are valid. |
| 2193 | (save-excursion | 2193 | (save-excursion |
| 2194 | (let ((s (parse-partial-sexp from to)) | 2194 | (let ((s (parse-partial-sexp from to)) |
| 2195 | ty) | 2195 | ty co-st) |
| 2196 | (when (or (nth 3 s) (nth 4 s)) ; in a string or comment | 2196 | (cond |
| 2197 | ((or (nth 3 s) (nth 4 s)) ; in a string or comment | ||
| 2197 | (setq ty (cond | 2198 | (setq ty (cond |
| 2198 | ((nth 3 s) 'string) | 2199 | ((nth 3 s) 'string) |
| 2199 | ((eq (nth 7 s) t) 'c++) | 2200 | ((nth 7 s) 'c++) |
| 2200 | (t 'c))) | 2201 | (t 'c))) |
| 2201 | (parse-partial-sexp (point) (point-max) | 2202 | (parse-partial-sexp (point) (point-max) |
| 2202 | nil ; TARGETDEPTH | 2203 | nil ; TARGETDEPTH |
| 2203 | nil ; STOPBEFORE | 2204 | nil ; STOPBEFORE |
| 2204 | s ; OLDSTATE | 2205 | s ; OLDSTATE |
| 2205 | 'syntax-table)) ; stop at end of literal | 2206 | 'syntax-table) ; stop at end of literal |
| 2206 | (if ty | 2207 | `(,s ,ty (,(nth 8 s) . ,(point)))) |
| 2207 | `(,s ,ty (,(nth 8 s) . ,(point))) | 2208 | |
| 2208 | `(,s))))) | 2209 | ((and (not not-in-delimiter) ; inside a comment starter |
| 2210 | (not (bobp)) | ||
| 2211 | (progn (backward-char) | ||
| 2212 | (looking-at c-comment-start-regexp))) | ||
| 2213 | (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++) | ||
| 2214 | co-st (point)) | ||
| 2215 | (forward-comment 1) | ||
| 2216 | `(,s ,ty (,co-st . ,(point)))) | ||
| 2217 | |||
| 2218 | (t `(,s)))))) | ||
| 2209 | 2219 | ||
| 2210 | (defun c-state-safe-place (here) | 2220 | (defun c-state-safe-place (here) |
| 2211 | ;; Return a buffer position before HERE which is "safe", i.e. outside any | 2221 | ;; Return a buffer position before HERE which is "safe", i.e. outside any |
| @@ -3143,10 +3153,13 @@ comment at the start of cc-engine.el for more info." | |||
| 3143 | ;; This function is called from c-after-change. | 3153 | ;; This function is called from c-after-change. |
| 3144 | 3154 | ||
| 3145 | ;; The caches of non-literals: | 3155 | ;; The caches of non-literals: |
| 3146 | (if (< here c-state-nonlit-pos-cache-limit) | 3156 | ;; Note that we use "<=" for the possibility of the second char of a two-char |
| 3147 | (setq c-state-nonlit-pos-cache-limit here)) | 3157 | ;; comment opener being typed; this would invalidate any cache position at |
| 3148 | (if (< here c-state-semi-nonlit-pos-cache-limit) | 3158 | ;; HERE. |
| 3149 | (setq c-state-semi-nonlit-pos-cache-limit here)) | 3159 | (if (<= here c-state-nonlit-pos-cache-limit) |
| 3160 | (setq c-state-nonlit-pos-cache-limit (1- here))) | ||
| 3161 | (if (<= here c-state-semi-nonlit-pos-cache-limit) | ||
| 3162 | (setq c-state-semi-nonlit-pos-cache-limit (1- here))) | ||
| 3150 | 3163 | ||
| 3151 | ;; `c-state-cache': | 3164 | ;; `c-state-cache': |
| 3152 | ;; Case 1: if `here' is in a literal containing point-min, everything | 3165 | ;; Case 1: if `here' is in a literal containing point-min, everything |
| @@ -4444,19 +4457,12 @@ comment at the start of cc-engine.el for more info." | |||
| 4444 | (lim (or lim (c-state-semi-safe-place pos))) | 4457 | (lim (or lim (c-state-semi-safe-place pos))) |
| 4445 | (pp-to-lit (save-restriction | 4458 | (pp-to-lit (save-restriction |
| 4446 | (widen) | 4459 | (widen) |
| 4447 | (c-state-pp-to-literal lim pos))) | 4460 | (c-state-pp-to-literal lim pos not-in-delimiter))) |
| 4448 | (state (car pp-to-lit)) | 4461 | (state (car pp-to-lit)) |
| 4449 | (lit-limits (car (cddr pp-to-lit)))) | 4462 | (lit-limits (car (cddr pp-to-lit)))) |
| 4450 | 4463 | ||
| 4451 | (cond | 4464 | (cond |
| 4452 | (lit-limits) | 4465 | (lit-limits) |
| 4453 | ((and (not not-in-delimiter) | ||
| 4454 | (not (elt state 5)) | ||
| 4455 | (eq (char-before) ?/) | ||
| 4456 | (looking-at "[/*]")) ; FIXME!!! use c-line/block-comment-starter. 2008-09-28. | ||
| 4457 | ;; We're standing in a comment starter. | ||
| 4458 | (backward-char 1) | ||
| 4459 | (cons (point) (progn (c-forward-single-comment) (point)))) | ||
| 4460 | 4466 | ||
| 4461 | (near | 4467 | (near |
| 4462 | (goto-char pos) | 4468 | (goto-char pos) |
| @@ -6466,6 +6472,52 @@ comment at the start of cc-engine.el for more info." | |||
| 6466 | (c-go-list-forward) | 6472 | (c-go-list-forward) |
| 6467 | t))) | 6473 | t))) |
| 6468 | 6474 | ||
| 6475 | (defun c-back-over-member-initializers () | ||
| 6476 | ;; Test whether we are in a C++ member initializer list, and if so, go back | ||
| 6477 | ;; to the introducing ":", returning the position of the opening paren of | ||
| 6478 | ;; the function's arglist. Otherwise return nil, leaving point unchanged. | ||
| 6479 | (let ((here (point)) | ||
| 6480 | (paren-state (c-parse-state)) | ||
| 6481 | res) | ||
| 6482 | |||
| 6483 | (setq res | ||
| 6484 | (catch 'done | ||
| 6485 | (if (not (c-at-toplevel-p)) | ||
| 6486 | (progn | ||
| 6487 | (while (not (c-at-toplevel-p)) | ||
| 6488 | (goto-char (c-pull-open-brace paren-state))) | ||
| 6489 | (c-backward-syntactic-ws) | ||
| 6490 | (when (not (c-simple-skip-symbol-backward)) | ||
| 6491 | (throw 'done nil)) | ||
| 6492 | (c-backward-syntactic-ws)) | ||
| 6493 | (c-backward-syntactic-ws) | ||
| 6494 | (when (memq (char-before) '(?\) ?})) | ||
| 6495 | (when (not (c-go-list-backward)) | ||
| 6496 | (throw 'done nil)) | ||
| 6497 | (c-backward-syntactic-ws)) | ||
| 6498 | (when (c-simple-skip-symbol-backward) | ||
| 6499 | (c-backward-syntactic-ws))) | ||
| 6500 | |||
| 6501 | (while (eq (char-before) ?,) | ||
| 6502 | (backward-char) | ||
| 6503 | (c-backward-syntactic-ws) | ||
| 6504 | |||
| 6505 | (when (not (memq (char-before) '(?\) ?}))) | ||
| 6506 | (throw 'done nil)) | ||
| 6507 | (when (not (c-go-list-backward)) | ||
| 6508 | (throw 'done nil)) | ||
| 6509 | (c-backward-syntactic-ws) | ||
| 6510 | (when (not (c-simple-skip-symbol-backward)) | ||
| 6511 | (throw 'done nil)) | ||
| 6512 | (c-backward-syntactic-ws)) | ||
| 6513 | |||
| 6514 | (and | ||
| 6515 | (eq (char-before) ?:) | ||
| 6516 | (c-just-after-func-arglist-p)))) | ||
| 6517 | |||
| 6518 | (or res (goto-char here)) | ||
| 6519 | res)) | ||
| 6520 | |||
| 6469 | 6521 | ||
| 6470 | ;; Handling of large scale constructs like statements and declarations. | 6522 | ;; Handling of large scale constructs like statements and declarations. |
| 6471 | 6523 | ||
| @@ -9668,18 +9720,13 @@ comment at the start of cc-engine.el for more info." | |||
| 9668 | ;; 2007-11-09) | 9720 | ;; 2007-11-09) |
| 9669 | )))) | 9721 | )))) |
| 9670 | 9722 | ||
| 9671 | ;; CASE 5B: After a function header but before the body (or | 9723 | ;; CASE 5R: Member init list. (Used to be part of CASE 5B.1) |
| 9672 | ;; the ending semicolon if there's no body). | 9724 | ;; Note there is no limit on the backward search here, since member |
| 9725 | ;; init lists can, in practice, be very large. | ||
| 9673 | ((save-excursion | 9726 | ((save-excursion |
| 9674 | (when (setq placeholder (c-just-after-func-arglist-p | 9727 | (when (setq placeholder (c-back-over-member-initializers)) |
| 9675 | (max lim (c-determine-limit 500)))) | ||
| 9676 | (setq tmp-pos (point)))) | 9728 | (setq tmp-pos (point)))) |
| 9677 | (cond | 9729 | (if (= (c-point 'bosws) (1+ tmp-pos)) |
| 9678 | |||
| 9679 | ;; CASE 5B.1: Member init list. | ||
| 9680 | ((eq (char-after tmp-pos) ?:) | ||
| 9681 | (if (or (>= tmp-pos indent-point) | ||
| 9682 | (= (c-point 'bosws) (1+ tmp-pos))) | ||
| 9683 | (progn | 9730 | (progn |
| 9684 | ;; There is no preceding member init clause. | 9731 | ;; There is no preceding member init clause. |
| 9685 | ;; Indent relative to the beginning of indentation | 9732 | ;; Indent relative to the beginning of indentation |
| @@ -9692,6 +9739,23 @@ comment at the start of cc-engine.el for more info." | |||
| 9692 | (c-forward-syntactic-ws) | 9739 | (c-forward-syntactic-ws) |
| 9693 | (c-add-syntax 'member-init-cont (point)))) | 9740 | (c-add-syntax 'member-init-cont (point)))) |
| 9694 | 9741 | ||
| 9742 | ;; CASE 5B: After a function header but before the body (or | ||
| 9743 | ;; the ending semicolon if there's no body). | ||
| 9744 | ((save-excursion | ||
| 9745 | (when (setq placeholder (c-just-after-func-arglist-p | ||
| 9746 | (max lim (c-determine-limit 500)))) | ||
| 9747 | (setq tmp-pos (point)))) | ||
| 9748 | (cond | ||
| 9749 | |||
| 9750 | ;; CASE 5B.1: Member init list. | ||
| 9751 | ((eq (char-after tmp-pos) ?:) | ||
| 9752 | ;; There is no preceding member init clause. | ||
| 9753 | ;; Indent relative to the beginning of indentation | ||
| 9754 | ;; for the topmost-intro line that contains the | ||
| 9755 | ;; prototype's open paren. | ||
| 9756 | (goto-char placeholder) | ||
| 9757 | (c-add-syntax 'member-init-intro (c-point 'boi))) | ||
| 9758 | |||
| 9695 | ;; CASE 5B.2: K&R arg decl intro | 9759 | ;; CASE 5B.2: K&R arg decl intro |
| 9696 | ((and c-recognize-knr-p | 9760 | ((and c-recognize-knr-p |
| 9697 | (c-in-knr-argdecl lim)) | 9761 | (c-in-knr-argdecl lim)) |
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index f6c47f5bb4d..6a4bfd9e875 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el | |||
| @@ -176,7 +176,6 @@ | |||
| 176 | 'font-lock-negation-char-face)) | 176 | 'font-lock-negation-char-face)) |
| 177 | 177 | ||
| 178 | (cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs. | 178 | (cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs. |
| 179 | (cc-bytecomp-defun face-property-instance) ; Only in XEmacs. | ||
| 180 | 179 | ||
| 181 | (defun c-make-inverse-face (oldface newface) | 180 | (defun c-make-inverse-face (oldface newface) |
| 182 | ;; Emacs and XEmacs have completely different face manipulation | 181 | ;; Emacs and XEmacs have completely different face manipulation |
| @@ -2486,7 +2485,7 @@ need for `pike-font-lock-extra-types'.") | |||
| 2486 | (setq comment-beg nil)) | 2485 | (setq comment-beg nil)) |
| 2487 | (setq region-beg comment-beg)) | 2486 | (setq region-beg comment-beg)) |
| 2488 | 2487 | ||
| 2489 | (if (eq (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) t) | 2488 | (if (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) |
| 2490 | ;; Collect a sequence of doc style line comments. | 2489 | ;; Collect a sequence of doc style line comments. |
| 2491 | (progn | 2490 | (progn |
| 2492 | (goto-char comment-beg) | 2491 | (goto-char comment-beg) |
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index ba9c42e4c89..af52ad53aad 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el | |||
| @@ -812,8 +812,8 @@ Assumed to not contain any submatches or \\| operators." | |||
| 812 | (c-lang-defconst c-anchored-cpp-prefix | 812 | (c-lang-defconst c-anchored-cpp-prefix |
| 813 | "Regexp matching the prefix of a cpp directive anchored to BOL, | 813 | "Regexp matching the prefix of a cpp directive anchored to BOL, |
| 814 | in the languages that have a macro preprocessor." | 814 | in the languages that have a macro preprocessor." |
| 815 | t (if (c-lang-const c-opt-cpp-prefix) | 815 | t "^\\s *\\(#\\)\\s *" |
| 816 | (concat "^" (c-lang-const c-opt-cpp-prefix)))) | 816 | (java awk) nil) |
| 817 | (c-lang-defvar c-anchored-cpp-prefix (c-lang-const c-anchored-cpp-prefix)) | 817 | (c-lang-defvar c-anchored-cpp-prefix (c-lang-const c-anchored-cpp-prefix)) |
| 818 | 818 | ||
| 819 | (c-lang-defconst c-opt-cpp-start | 819 | (c-lang-defconst c-opt-cpp-start |
diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el index a06eaf566d8..067a4df13dd 100644 --- a/lisp/progmodes/cc-menus.el +++ b/lisp/progmodes/cc-menus.el | |||
| @@ -161,49 +161,132 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.") | |||
| 161 | cc-imenu-c++-generic-expression | 161 | cc-imenu-c++-generic-expression |
| 162 | "Imenu generic expression for C mode. See `imenu-generic-expression'.") | 162 | "Imenu generic expression for C mode. See `imenu-generic-expression'.") |
| 163 | 163 | ||
| 164 | (defvar cc-imenu-java-generic-expression | 164 | |
| 165 | ;; Auxiliary regexps for Java try to match their trailing whitespace where | ||
| 166 | ;; appropriate, but _not_ starting whitespace. | ||
| 167 | |||
| 168 | (defconst cc-imenu-java-ellipsis-regexp | ||
| 169 | (concat | ||
| 170 | "\\.\\{3\\}" | ||
| 171 | "[ \t\n\r]*")) | ||
| 172 | |||
| 173 | (defun cc-imenu-java-build-type-args-regex (depth) | ||
| 174 | "Builds regexp for type arguments list with DEPTH allowed | ||
| 175 | nested angle brackets constructs." | ||
| 176 | (if (> depth 0) | ||
| 177 | (concat "<" | ||
| 178 | "[][.," c-alnum "_? \t\n\r]+" | ||
| 179 | (if (> depth 1) | ||
| 180 | "\\(") | ||
| 181 | (cc-imenu-java-build-type-args-regex (1- depth)) | ||
| 182 | (if (> depth 1) | ||
| 183 | (concat "[][.," c-alnum "_? \t\n\r]*" | ||
| 184 | "\\)*")) | ||
| 185 | ">"))) | ||
| 186 | |||
| 187 | (defconst cc-imenu-java-type-spec-regexp | ||
| 188 | (concat | ||
| 189 | ;; zero or more identifiers followed by a dot | ||
| 190 | "\\(" | ||
| 191 | "[" c-alpha "_][" c-alnum "_]*\\." | ||
| 192 | "\\)*" | ||
| 193 | ;; a single mandatory identifier without a dot | ||
| 194 | "[" c-alpha "_][" c-alnum "_]*" | ||
| 195 | ;; then choice: | ||
| 196 | "\\(" | ||
| 197 | ;; (option 1) type arguments list which _may_ be followed with brackets | ||
| 198 | ;; and/or spaces, then optional variable arity | ||
| 199 | "[ \t\n\r]*" | ||
| 200 | (cc-imenu-java-build-type-args-regex 3) | ||
| 201 | "[][ \t\n\r]*" | ||
| 202 | "\\(" cc-imenu-java-ellipsis-regexp "\\)?" | ||
| 203 | "\\|" | ||
| 204 | ;; (option 2) just brackets and/or spaces (there should be at least one), | ||
| 205 | ;; then optional variable arity | ||
| 206 | "[][ \t\n\r]+" | ||
| 207 | "\\(" cc-imenu-java-ellipsis-regexp "\\)?" | ||
| 208 | "\\|" | ||
| 209 | ;; (option 3) just variable arity | ||
| 210 | cc-imenu-java-ellipsis-regexp | ||
| 211 | "\\)")) | ||
| 212 | |||
| 213 | (defconst cc-imenu-java-comment-regexp | ||
| 214 | (concat | ||
| 215 | "/" | ||
| 216 | "\\(" | ||
| 217 | ;; a traditional comment | ||
| 218 | "\\*" | ||
| 219 | "\\(" | ||
| 220 | "[^*]" | ||
| 221 | "\\|" | ||
| 222 | "\\*+[^/*]" | ||
| 223 | "\\)*" | ||
| 224 | "\\*+/" | ||
| 225 | "\\|" | ||
| 226 | ;; an end-of-line comment | ||
| 227 | "/[^\n\r]*[\n\r]" | ||
| 228 | "\\)" | ||
| 229 | "[ \t\n\r]*" | ||
| 230 | )) | ||
| 231 | |||
| 232 | ;; Comments are allowed before the argument, after any of the | ||
| 233 | ;; modifiers and after the identifier. | ||
| 234 | (defconst cc-imenu-java-method-arg-regexp | ||
| 235 | (concat | ||
| 236 | "\\(" cc-imenu-java-comment-regexp "\\)*" | ||
| 237 | ;; optional modifiers | ||
| 238 | "\\(" | ||
| 239 | ;; a modifier is either an annotation or "final" | ||
| 240 | "\\(" | ||
| 241 | "@[" c-alpha "_]" | ||
| 242 | "[" c-alnum "._]*" | ||
| 243 | ;; TODO support element-value pairs! | ||
| 244 | "\\|" | ||
| 245 | "final" | ||
| 246 | "\\)" | ||
| 247 | ;; a modifier ends with comments and/or ws | ||
| 248 | "\\(" | ||
| 249 | "\\(" cc-imenu-java-comment-regexp "\\)+" | ||
| 250 | "\\|" | ||
| 251 | "[ \t\n\r]+" | ||
| 252 | "\\(" cc-imenu-java-comment-regexp "\\)*" | ||
| 253 | "\\)" | ||
| 254 | "\\)*" | ||
| 255 | ;; type spec | ||
| 256 | cc-imenu-java-type-spec-regexp | ||
| 257 | ;; identifier | ||
| 258 | "[" c-alpha "_]" | ||
| 259 | "[" c-alnum "_]*" | ||
| 260 | ;; optional comments and/or ws | ||
| 261 | "[ \t\n\r]*" | ||
| 262 | "\\(" cc-imenu-java-comment-regexp "\\)*" | ||
| 263 | )) | ||
| 264 | |||
| 265 | (defconst cc-imenu-java-generic-expression | ||
| 165 | `((nil | 266 | `((nil |
| 166 | ,(concat | 267 | ,(concat |
| 167 | "[" c-alpha "_][\]\[." c-alnum "_<> ]+[ \t\n\r]+" ; type spec | 268 | cc-imenu-java-type-spec-regexp |
| 168 | "\\([" c-alpha "_][" c-alnum "_]*\\)" ; method name | 269 | "\\(" ; method name which gets captured |
| 270 | ; into index | ||
| 271 | "[" c-alpha "_]" | ||
| 272 | "[" c-alnum "_]*" | ||
| 273 | "\\)" | ||
| 169 | "[ \t\n\r]*" | 274 | "[ \t\n\r]*" |
| 170 | ;; An argument list htat is either empty or contains any number | 275 | ;; An argument list that contains zero or more arguments. |
| 171 | ;; of arguments. An argument is any number of annotations | 276 | (concat |
| 172 | ;; followed by a type spec followed by a word. A word is an | 277 | "(" |
| 173 | ;; identifier. A type spec is an identifier, possibly followed | 278 | "[ \t\n\r]*" |
| 174 | ;; by < typespec > possibly followed by []. | 279 | "\\(" |
| 175 | (concat "(" | 280 | "\\(" cc-imenu-java-method-arg-regexp ",[ \t\n\r]*\\)*" |
| 176 | "\\(" | 281 | cc-imenu-java-method-arg-regexp |
| 177 | "[ \t\n\r]*" | 282 | "\\)?" |
| 178 | "\\(" | 283 | ")" |
| 179 | "@" | 284 | "[.,_" c-alnum " \t\n\r]*" ; throws etc. |
| 180 | "[" c-alpha "_]" | 285 | "{" |
| 181 | "[" c-alnum "._]""*" | 286 | )) 7)) |
| 182 | "[ \t\n\r]+" | ||
| 183 | "\\)*" | ||
| 184 | "\\(" | ||
| 185 | "[" c-alpha "_]" | ||
| 186 | "[\]\[" c-alnum "_.]*" | ||
| 187 | "\\(" | ||
| 188 | |||
| 189 | "<" | ||
| 190 | "[ \t\n\r]*" | ||
| 191 | "[\]\[.," c-alnum "_<> \t\n\r]*" | ||
| 192 | ">" | ||
| 193 | "\\)?" | ||
| 194 | "\\(\\[\\]\\)?" | ||
| 195 | "[ \t\n\r]+" | ||
| 196 | "\\)" | ||
| 197 | "[" c-alpha "_]" | ||
| 198 | "[" c-alnum "_]*" | ||
| 199 | "[ \t\n\r,]*" | ||
| 200 | "\\)*" | ||
| 201 | ")" | ||
| 202 | "[.," c-alnum " \t\n\r]*" | ||
| 203 | "{" | ||
| 204 | )) 1)) | ||
| 205 | "Imenu generic expression for Java mode. See `imenu-generic-expression'.") | 287 | "Imenu generic expression for Java mode. See `imenu-generic-expression'.") |
| 206 | 288 | ||
| 289 | |||
| 207 | ;; Internal variables | 290 | ;; Internal variables |
| 208 | (defvar cc-imenu-objc-generic-expression-noreturn-index nil) | 291 | (defvar cc-imenu-objc-generic-expression-noreturn-index nil) |
| 209 | (defvar cc-imenu-objc-generic-expression-general-func-index nil) | 292 | (defvar cc-imenu-objc-generic-expression-general-func-index nil) |
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 3c3a5766582..36c9f72fa18 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -86,8 +86,8 @@ | |||
| 86 | (load "cc-bytecomp" nil t))) | 86 | (load "cc-bytecomp" nil t))) |
| 87 | 87 | ||
| 88 | (cc-require 'cc-defs) | 88 | (cc-require 'cc-defs) |
| 89 | (cc-require-when-compile 'cc-langs) | ||
| 90 | (cc-require 'cc-vars) | 89 | (cc-require 'cc-vars) |
| 90 | (cc-require-when-compile 'cc-langs) | ||
| 91 | (cc-require 'cc-engine) | 91 | (cc-require 'cc-engine) |
| 92 | (cc-require 'cc-styles) | 92 | (cc-require 'cc-styles) |
| 93 | (cc-require 'cc-cmds) | 93 | (cc-require 'cc-cmds) |
| @@ -97,7 +97,6 @@ | |||
| 97 | 97 | ||
| 98 | ;; Silence the compiler. | 98 | ;; Silence the compiler. |
| 99 | (cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs | 99 | (cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs |
| 100 | (cc-bytecomp-defun set-keymap-parents) ; XEmacs | ||
| 101 | (cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1 | 100 | (cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1 |
| 102 | 101 | ||
| 103 | ;; We set these variables during mode init, yet we don't require | 102 | ;; We set these variables during mode init, yet we don't require |
| @@ -212,7 +211,7 @@ control). See \"cc-mode.el\" for more info." | |||
| 212 | ((cc-bytecomp-fboundp 'set-keymap-parent) | 211 | ((cc-bytecomp-fboundp 'set-keymap-parent) |
| 213 | (set-keymap-parent map c-mode-base-map)) | 212 | (set-keymap-parent map c-mode-base-map)) |
| 214 | ;; XEmacs | 213 | ;; XEmacs |
| 215 | ((cc-bytecomp-fboundp 'set-keymap-parents) | 214 | ((fboundp 'set-keymap-parents) |
| 216 | (set-keymap-parents map c-mode-base-map)) | 215 | (set-keymap-parents map c-mode-base-map)) |
| 217 | ;; incompatible | 216 | ;; incompatible |
| 218 | (t (error "CC Mode is incompatible with this version of Emacs"))) | 217 | (t (error "CC Mode is incompatible with this version of Emacs"))) |
| @@ -936,7 +935,8 @@ Note that the style variables are always made local to the buffer." | |||
| 936 | 935 | ||
| 937 | ;; Add needed properties to each CPP construct in the region. | 936 | ;; Add needed properties to each CPP construct in the region. |
| 938 | (goto-char c-new-BEG) | 937 | (goto-char c-new-BEG) |
| 939 | (let ((pps-position c-new-BEG) pps-state mbeg) | 938 | (skip-chars-backward " \t") |
| 939 | (let ((pps-position (point)) pps-state mbeg) | ||
| 940 | (while (and (< (point) c-new-END) | 940 | (while (and (< (point) c-new-END) |
| 941 | (search-forward-regexp c-anchored-cpp-prefix c-new-END t)) | 941 | (search-forward-regexp c-anchored-cpp-prefix c-new-END t)) |
| 942 | ;; If we've found a "#" inside a string/comment, ignore it. | 942 | ;; If we've found a "#" inside a string/comment, ignore it. |
| @@ -945,14 +945,12 @@ Note that the style variables are always made local to the buffer." | |||
| 945 | pps-position (point)) | 945 | pps-position (point)) |
| 946 | (unless (or (nth 3 pps-state) ; in a string? | 946 | (unless (or (nth 3 pps-state) ; in a string? |
| 947 | (nth 4 pps-state)) ; in a comment? | 947 | (nth 4 pps-state)) ; in a comment? |
| 948 | (goto-char (match-beginning 0)) | 948 | (goto-char (match-beginning 1)) |
| 949 | (setq mbeg (point)) | 949 | (setq mbeg (point)) |
| 950 | (if (> (c-syntactic-end-of-macro) mbeg) | 950 | (if (> (c-syntactic-end-of-macro) mbeg) |
| 951 | (progn | 951 | (progn |
| 952 | (c-neutralize-CPP-line mbeg (point)) | 952 | (c-neutralize-CPP-line mbeg (point)) |
| 953 | (c-set-cpp-delimiters mbeg (point)) | 953 | (c-set-cpp-delimiters mbeg (point))) |
| 954 | ;(setq pps-position (point)) | ||
| 955 | ) | ||
| 956 | (forward-line)) ; no infinite loop with, e.g., "#//" | 954 | (forward-line)) ; no infinite loop with, e.g., "#//" |
| 957 | ))))) | 955 | ))))) |
| 958 | 956 | ||
| @@ -1060,7 +1058,7 @@ Note that the style variables are always made local to the buffer." | |||
| 1060 | ;; This calls the language variable c-before-font-lock-functions, if non nil. | 1058 | ;; This calls the language variable c-before-font-lock-functions, if non nil. |
| 1061 | ;; This typically sets `syntax-table' properties. | 1059 | ;; This typically sets `syntax-table' properties. |
| 1062 | 1060 | ||
| 1063 | (c-save-buffer-state () | 1061 | (c-save-buffer-state (case-fold-search) |
| 1064 | ;; When `combine-after-change-calls' is used we might get calls | 1062 | ;; When `combine-after-change-calls' is used we might get calls |
| 1065 | ;; with regions outside the current narrowing. This has been | 1063 | ;; with regions outside the current narrowing. This has been |
| 1066 | ;; observed in Emacs 20.7. | 1064 | ;; observed in Emacs 20.7. |
| @@ -1078,12 +1076,13 @@ Note that the style variables are always made local to the buffer." | |||
| 1078 | (setq beg end))) | 1076 | (setq beg end))) |
| 1079 | 1077 | ||
| 1080 | ;; C-y is capable of spuriously converting category properties | 1078 | ;; C-y is capable of spuriously converting category properties |
| 1081 | ;; c-</>-as-paren-syntax into hard syntax-table properties. Remove | 1079 | ;; c-</>-as-paren-syntax and c-cpp-delimiter into hard syntax-table |
| 1082 | ;; these when it happens. | 1080 | ;; properties. Remove these when it happens. |
| 1083 | (c-clear-char-property-with-value beg end 'syntax-table | 1081 | (c-clear-char-property-with-value beg end 'syntax-table |
| 1084 | c-<-as-paren-syntax) | 1082 | c-<-as-paren-syntax) |
| 1085 | (c-clear-char-property-with-value beg end 'syntax-table | 1083 | (c-clear-char-property-with-value beg end 'syntax-table |
| 1086 | c->-as-paren-syntax) | 1084 | c->-as-paren-syntax) |
| 1085 | (c-clear-char-property-with-value beg end 'syntax-table nil) | ||
| 1087 | 1086 | ||
| 1088 | (c-trim-found-types beg end old-len) ; maybe we don't need all of these. | 1087 | (c-trim-found-types beg end old-len) ; maybe we don't need all of these. |
| 1089 | (c-invalidate-sws-region-after beg end) | 1088 | (c-invalidate-sws-region-after beg end) |
| @@ -1161,9 +1160,6 @@ Note that the style variables are always made local to the buffer." | |||
| 1161 | ;; `c-set-fl-decl-start' for the detailed functionality. | 1160 | ;; `c-set-fl-decl-start' for the detailed functionality. |
| 1162 | (cons (c-set-fl-decl-start beg) end)) | 1161 | (cons (c-set-fl-decl-start beg) end)) |
| 1163 | 1162 | ||
| 1164 | (defvar c-standard-font-lock-fontify-region-function nil | ||
| 1165 | "Standard value of `font-lock-fontify-region-function'") | ||
| 1166 | |||
| 1167 | (defun c-font-lock-fontify-region (beg end &optional verbose) | 1163 | (defun c-font-lock-fontify-region (beg end &optional verbose) |
| 1168 | ;; Effectively advice around `font-lock-fontify-region' which extends the | 1164 | ;; Effectively advice around `font-lock-fontify-region' which extends the |
| 1169 | ;; region (BEG END), for example, to avoid context fontification chopping | 1165 | ;; region (BEG END), for example, to avoid context fontification chopping |
| @@ -1188,17 +1184,14 @@ Note that the style variables are always made local to the buffer." | |||
| 1188 | (setq new-region (funcall fn new-beg new-end)) | 1184 | (setq new-region (funcall fn new-beg new-end)) |
| 1189 | (setq new-beg (car new-region) new-end (cdr new-region))) | 1185 | (setq new-beg (car new-region) new-end (cdr new-region))) |
| 1190 | c-before-context-fontification-functions)))) | 1186 | c-before-context-fontification-functions)))) |
| 1191 | (funcall c-standard-font-lock-fontify-region-function | 1187 | (funcall (default-value 'font-lock-fontify-region-function) |
| 1192 | new-beg new-end verbose))) | 1188 | new-beg new-end verbose))) |
| 1193 | 1189 | ||
| 1194 | (defun c-after-font-lock-init () | 1190 | (defun c-after-font-lock-init () |
| 1195 | ;; Put on `font-lock-mode-hook'. This function ensures our after-change | 1191 | ;; Put on `font-lock-mode-hook'. This function ensures our after-change |
| 1196 | ;; function will get executed before the font-lock one. Amongst other | 1192 | ;; function will get executed before the font-lock one. |
| 1197 | ;; things. | ||
| 1198 | (remove-hook 'after-change-functions 'c-after-change t) | 1193 | (remove-hook 'after-change-functions 'c-after-change t) |
| 1199 | (add-hook 'after-change-functions 'c-after-change nil t) | 1194 | (add-hook 'after-change-functions 'c-after-change nil t)) |
| 1200 | (setq c-standard-font-lock-fontify-region-function | ||
| 1201 | (default-value 'font-lock-fontify-region-function))) | ||
| 1202 | 1195 | ||
| 1203 | (defun c-font-lock-init () | 1196 | (defun c-font-lock-init () |
| 1204 | "Set up the font-lock variables for using the font-lock support in CC Mode. | 1197 | "Set up the font-lock variables for using the font-lock support in CC Mode. |
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el index 66ff217c73e..c89402c63a3 100644 --- a/lisp/progmodes/cc-vars.el +++ b/lisp/progmodes/cc-vars.el | |||
| @@ -42,23 +42,25 @@ | |||
| 42 | 42 | ||
| 43 | (cc-require 'cc-defs) | 43 | (cc-require 'cc-defs) |
| 44 | 44 | ||
| 45 | ;; Silence the compiler. | ||
| 46 | (cc-bytecomp-defun get-char-table) ; XEmacs | ||
| 47 | |||
| 48 | (cc-eval-when-compile | 45 | (cc-eval-when-compile |
| 49 | (require 'custom) | 46 | (require 'custom) |
| 50 | (require 'widget)) | 47 | (require 'widget)) |
| 51 | 48 | ||
| 52 | ;;; Helpers | 49 | ;;; Helpers |
| 53 | 50 | ||
| 54 | ;; This widget exists in newer versions of the Custom library | 51 | |
| 55 | (or (get 'other 'widget-type) | 52 | ;; Emacs has 'other since at least version 21.1. |
| 56 | (define-widget 'other 'sexp | 53 | ;; FIXME this is probably broken, since the widget is defined |
| 57 | "Matches everything, but doesn't let the user edit the value. | 54 | ;; in wid-edit, which this file does not load. So we will always |
| 55 | ;; define the widget, even when we don't need to. | ||
| 56 | (when (featurep 'xemacs) | ||
| 57 | (or (get 'other 'widget-type) | ||
| 58 | (define-widget 'other 'sexp | ||
| 59 | "Matches everything, but doesn't let the user edit the value. | ||
| 58 | Useful as last item in a `choice' widget." | 60 | Useful as last item in a `choice' widget." |
| 59 | :tag "Other" | 61 | :tag "Other" |
| 60 | :format "%t%n" | 62 | :format "%t%n" |
| 61 | :value 'other)) | 63 | :value 'other))) |
| 62 | 64 | ||
| 63 | ;; The next defun will supersede c-const-symbol. | 65 | ;; The next defun will supersede c-const-symbol. |
| 64 | (eval-and-compile | 66 | (eval-and-compile |
| @@ -1622,11 +1624,30 @@ names).")) | |||
| 1622 | ) | 1624 | ) |
| 1623 | (make-variable-buffer-local 'c-macro-with-semi-re) | 1625 | (make-variable-buffer-local 'c-macro-with-semi-re) |
| 1624 | 1626 | ||
| 1627 | (defvar c-macro-names-with-semicolon | ||
| 1628 | '("Q_OBJECT" "Q_PROPERTY" "Q_DECLARE" "Q_ENUMS") | ||
| 1629 | "List of #defined symbols whose expansion ends with a semicolon. | ||
| 1630 | Alternatively it can be a string, a regular expression which | ||
| 1631 | matches all such symbols. | ||
| 1632 | |||
| 1633 | The \"symbols\" must be syntactically valid identifiers in the | ||
| 1634 | target language \(C, C++, Objective C), or \(as the case may be) | ||
| 1635 | the regular expression must match only valid identifiers. | ||
| 1636 | |||
| 1637 | If you change this variable's value, call the function | ||
| 1638 | `c-make-macros-with-semi-re' to set the necessary internal | ||
| 1639 | variables. | ||
| 1640 | |||
| 1641 | Note that currently \(2008-11-04) this variable is a prototype, | ||
| 1642 | and is likely to disappear or change its form soon.") | ||
| 1643 | (make-variable-buffer-local 'c-macro-names-with-semicolon) | ||
| 1644 | |||
| 1625 | (defun c-make-macro-with-semi-re () | 1645 | (defun c-make-macro-with-semi-re () |
| 1626 | ;; Convert `c-macro-names-with-semicolon' into the regexp | 1646 | ;; Convert `c-macro-names-with-semicolon' into the regexp |
| 1627 | ;; `c-macro-with-semi-re' (or just copy it if it's already a re). | 1647 | ;; `c-macro-with-semi-re' (or just copy it if it's already a re). |
| 1628 | (setq c-macro-with-semi-re | 1648 | (setq c-macro-with-semi-re |
| 1629 | (and | 1649 | (and |
| 1650 | (boundp 'c-opt-cpp-macro-define) | ||
| 1630 | c-opt-cpp-macro-define | 1651 | c-opt-cpp-macro-define |
| 1631 | (cond | 1652 | (cond |
| 1632 | ((stringp c-macro-names-with-semicolon) | 1653 | ((stringp c-macro-names-with-semicolon) |
| @@ -1643,24 +1664,6 @@ names).")) | |||
| 1643 | c-macro-names-with-semicolon: %s" | 1664 | c-macro-names-with-semicolon: %s" |
| 1644 | c-macro-names-with-semicolon)))))) | 1665 | c-macro-names-with-semicolon)))))) |
| 1645 | 1666 | ||
| 1646 | (defvar c-macro-names-with-semicolon | ||
| 1647 | '("Q_OBJECT" "Q_PROPERTY" "Q_DECLARE" "Q_ENUMS") | ||
| 1648 | "List of #defined symbols whose expansion ends with a semicolon. | ||
| 1649 | Alternatively it can be a string, a regular expression which | ||
| 1650 | matches all such symbols. | ||
| 1651 | |||
| 1652 | The \"symbols\" must be syntactically valid identifiers in the | ||
| 1653 | target language \(C, C++, Objective C), or \(as the case may be) | ||
| 1654 | the regular expression must match only valid identifiers. | ||
| 1655 | |||
| 1656 | If you change this variable's value, call the function | ||
| 1657 | `c-make-macros-with-semi-re' to set the necessary internal | ||
| 1658 | variables. | ||
| 1659 | |||
| 1660 | Note that currently \(2008-11-04) this variable is a prototype, | ||
| 1661 | and is likely to disappear or change its form soon.") | ||
| 1662 | (make-variable-buffer-local 'c-macro-names-with-semicolon) | ||
| 1663 | |||
| 1664 | (defvar c-file-style nil | 1667 | (defvar c-file-style nil |
| 1665 | "Variable interface for setting style via File Local Variables. | 1668 | "Variable interface for setting style via File Local Variables. |
| 1666 | In a file's Local Variable section, you can set this variable to a | 1669 | In a file's Local Variable section, you can set this variable to a |
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index 74b81b0cd01..11eb0eeaf49 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el | |||
| @@ -30,11 +30,13 @@ | |||
| 30 | ;; The CFEngine 3.x support doesn't have Imenu support but patches are | 30 | ;; The CFEngine 3.x support doesn't have Imenu support but patches are |
| 31 | ;; welcome. | 31 | ;; welcome. |
| 32 | 32 | ||
| 33 | ;; By default, CFEngine 3.x syntax is used. | ||
| 34 | |||
| 33 | ;; You can set it up so either `cfengine2-mode' (2.x and earlier) or | 35 | ;; You can set it up so either `cfengine2-mode' (2.x and earlier) or |
| 34 | ;; `cfengine3-mode' (3.x) will be picked, depending on the buffer | 36 | ;; `cfengine3-mode' (3.x) will be picked, depending on the buffer |
| 35 | ;; contents: | 37 | ;; contents: |
| 36 | 38 | ||
| 37 | ;; (add-to-list 'auto-mode-alist '("\\.cf\\'" . cfengine-mode)) | 39 | ;; (add-to-list 'auto-mode-alist '("\\.cf\\'" . cfengine-auto-mode)) |
| 38 | 40 | ||
| 39 | ;; OR you can choose to always use a specific version, if you prefer | 41 | ;; OR you can choose to always use a specific version, if you prefer |
| 40 | ;; it: | 42 | ;; it: |
| @@ -181,7 +183,7 @@ This includes those for cfservd as well as cfagent.") | |||
| 181 | ("$(\\([[:alnum:]_]+\\))" 1 font-lock-variable-name-face) | 183 | ("$(\\([[:alnum:]_]+\\))" 1 font-lock-variable-name-face) |
| 182 | ("${\\([[:alnum:]_]+\\)}" 1 font-lock-variable-name-face) | 184 | ("${\\([[:alnum:]_]+\\)}" 1 font-lock-variable-name-face) |
| 183 | ;; Variable definitions. | 185 | ;; Variable definitions. |
| 184 | ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face) | 186 | ("\\_<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face) |
| 185 | ;; File, acl &c in group: { token ... } | 187 | ;; File, acl &c in group: { token ... } |
| 186 | ("{[ \t]*\\([^ \t\n]+\\)" 1 font-lock-constant-face))) | 188 | ("{[ \t]*\\([^ \t\n]+\\)" 1 font-lock-constant-face))) |
| 187 | 189 | ||
| @@ -189,9 +191,9 @@ This includes those for cfservd as well as cfagent.") | |||
| 189 | `( | 191 | `( |
| 190 | ;; Defuns. This happens early so they don't get caught by looser | 192 | ;; Defuns. This happens early so they don't get caught by looser |
| 191 | ;; patterns. | 193 | ;; patterns. |
| 192 | (,(concat "\\<" cfengine3-defuns-regex "\\>" | 194 | (,(concat "\\_<" cfengine3-defuns-regex "\\_>" |
| 193 | "[ \t]+\\<\\([[:alnum:]_.:]+\\)\\>" | 195 | "[ \t]+\\_<\\([[:alnum:]_.:]+\\)\\_>" |
| 194 | "[ \t]+\\<\\([[:alnum:]_.:]+\\)" | 196 | "[ \t]+\\_<\\([[:alnum:]_.:]+\\)" |
| 195 | ;; Optional parentheses with variable names inside. | 197 | ;; Optional parentheses with variable names inside. |
| 196 | "\\(?:(\\([^)]*\\))\\)?") | 198 | "\\(?:(\\([^)]*\\))\\)?") |
| 197 | (1 font-lock-builtin-face) | 199 | (1 font-lock-builtin-face) |
| @@ -212,10 +214,10 @@ This includes those for cfservd as well as cfagent.") | |||
| 212 | ("[@$]{\\([[:alnum:]_.:]+\\)}" 1 font-lock-variable-name-face) | 214 | ("[@$]{\\([[:alnum:]_.:]+\\)}" 1 font-lock-variable-name-face) |
| 213 | 215 | ||
| 214 | ;; Variable definitions. | 216 | ;; Variable definitions. |
| 215 | ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face) | 217 | ("\\_<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face) |
| 216 | 218 | ||
| 217 | ;; Variable types. | 219 | ;; Variable types. |
| 218 | (,(concat "\\<" (eval-when-compile (regexp-opt cfengine3-vartypes t)) "\\>") | 220 | (,(concat "\\_<" (eval-when-compile (regexp-opt cfengine3-vartypes t)) "\\_>") |
| 219 | 1 font-lock-type-face))) | 221 | 1 font-lock-type-face))) |
| 220 | 222 | ||
| 221 | (defvar cfengine2-imenu-expression | 223 | (defvar cfengine2-imenu-expression |
| @@ -223,9 +225,9 @@ This includes those for cfservd as well as cfagent.") | |||
| 223 | (regexp-opt cfengine2-actions t)) | 225 | (regexp-opt cfengine2-actions t)) |
| 224 | ":[^:]") | 226 | ":[^:]") |
| 225 | 1) | 227 | 1) |
| 226 | ("Variables/classes" "\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1) | 228 | ("Variables/classes" "\\_<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1) |
| 227 | ("Variables/classes" "\\<define=\\([[:alnum:]_]+\\)" 1) | 229 | ("Variables/classes" "\\_<define=\\([[:alnum:]_]+\\)" 1) |
| 228 | ("Variables/classes" "\\<DefineClass\\>[ \t]+\\([[:alnum:]_]+\\)" 1)) | 230 | ("Variables/classes" "\\_<DefineClass\\>[ \t]+\\([[:alnum:]_]+\\)" 1)) |
| 229 | "`imenu-generic-expression' for CFEngine mode.") | 231 | "`imenu-generic-expression' for CFEngine mode.") |
| 230 | 232 | ||
| 231 | (defun cfengine2-outline-level () | 233 | (defun cfengine2-outline-level () |
| @@ -338,7 +340,7 @@ Intended as the value of `indent-line-function'." | |||
| 338 | Treats body/bundle blocks as defuns." | 340 | Treats body/bundle blocks as defuns." |
| 339 | (unless (<= (current-column) (current-indentation)) | 341 | (unless (<= (current-column) (current-indentation)) |
| 340 | (end-of-line)) | 342 | (end-of-line)) |
| 341 | (if (re-search-backward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t) | 343 | (if (re-search-backward (concat "^[ \t]*" cfengine3-defuns-regex "\\_>") nil t) |
| 342 | (beginning-of-line) | 344 | (beginning-of-line) |
| 343 | (goto-char (point-min))) | 345 | (goto-char (point-min))) |
| 344 | t) | 346 | t) |
| @@ -347,7 +349,7 @@ Treats body/bundle blocks as defuns." | |||
| 347 | "`end-of-defun' function for Cfengine 3 mode. | 349 | "`end-of-defun' function for Cfengine 3 mode. |
| 348 | Treats body/bundle blocks as defuns." | 350 | Treats body/bundle blocks as defuns." |
| 349 | (end-of-line) | 351 | (end-of-line) |
| 350 | (if (re-search-forward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t) | 352 | (if (re-search-forward (concat "^[ \t]*" cfengine3-defuns-regex "\\_>") nil t) |
| 351 | (beginning-of-line) | 353 | (beginning-of-line) |
| 352 | (goto-char (point-max))) | 354 | (goto-char (point-max))) |
| 353 | t) | 355 | t) |
| @@ -366,7 +368,7 @@ Intended as the value of `indent-line-function'." | |||
| 366 | 368 | ||
| 367 | (cond | 369 | (cond |
| 368 | ;; Body/bundle blocks start at 0. | 370 | ;; Body/bundle blocks start at 0. |
| 369 | ((looking-at (concat cfengine3-defuns-regex "\\>")) | 371 | ((looking-at (concat cfengine3-defuns-regex "\\_>")) |
| 370 | (indent-line-to 0)) | 372 | (indent-line-to 0)) |
| 371 | ;; Categories are indented one step. | 373 | ;; Categories are indented one step. |
| 372 | ((looking-at (concat cfengine3-category-regex "[ \t]*\\(#.*\\)*$")) | 374 | ((looking-at (concat cfengine3-category-regex "[ \t]*\\(#.*\\)*$")) |
| @@ -583,7 +585,7 @@ on the buffer contents" | |||
| 583 | (save-restriction | 585 | (save-restriction |
| 584 | (goto-char (point-min)) | 586 | (goto-char (point-min)) |
| 585 | (while (not (or (eobp) v3)) | 587 | (while (not (or (eobp) v3)) |
| 586 | (setq v3 (looking-at (concat cfengine3-defuns-regex "\\>"))) | 588 | (setq v3 (looking-at (concat cfengine3-defuns-regex "\\_>"))) |
| 587 | (forward-line))) | 589 | (forward-line))) |
| 588 | (if v3 (cfengine3-mode) (cfengine2-mode)))) | 590 | (if v3 (cfengine3-mode) (cfengine2-mode)))) |
| 589 | 591 | ||
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 9e9e2f0b090..d6f136ec92d 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el | |||
| @@ -1814,6 +1814,7 @@ Returns the compilation buffer created." | |||
| 1814 | (define-key map [follow-link] 'mouse-face) | 1814 | (define-key map [follow-link] 'mouse-face) |
| 1815 | (define-key map "\C-c\C-c" 'compile-goto-error) | 1815 | (define-key map "\C-c\C-c" 'compile-goto-error) |
| 1816 | (define-key map "\C-m" 'compile-goto-error) | 1816 | (define-key map "\C-m" 'compile-goto-error) |
| 1817 | (define-key map "\C-o" 'compilation-display-error) | ||
| 1817 | (define-key map "\C-c\C-k" 'kill-compilation) | 1818 | (define-key map "\C-c\C-k" 'kill-compilation) |
| 1818 | (define-key map "\M-n" 'compilation-next-error) | 1819 | (define-key map "\M-n" 'compilation-next-error) |
| 1819 | (define-key map "\M-p" 'compilation-previous-error) | 1820 | (define-key map "\M-p" 'compilation-previous-error) |
| @@ -1858,6 +1859,7 @@ Returns the compilation buffer created." | |||
| 1858 | (define-key map [follow-link] 'mouse-face) | 1859 | (define-key map [follow-link] 'mouse-face) |
| 1859 | (define-key map "\C-c\C-c" 'compile-goto-error) | 1860 | (define-key map "\C-c\C-c" 'compile-goto-error) |
| 1860 | (define-key map "\C-m" 'compile-goto-error) | 1861 | (define-key map "\C-m" 'compile-goto-error) |
| 1862 | (define-key map "\C-o" 'compilation-display-error) | ||
| 1861 | (define-key map "\C-c\C-k" 'kill-compilation) | 1863 | (define-key map "\C-c\C-k" 'kill-compilation) |
| 1862 | (define-key map "\M-n" 'compilation-next-error) | 1864 | (define-key map "\M-n" 'compilation-next-error) |
| 1863 | (define-key map "\M-p" 'compilation-previous-error) | 1865 | (define-key map "\M-p" 'compilation-previous-error) |
| @@ -2299,6 +2301,12 @@ Prefix arg N says how many files to move backwards (or forwards, if negative)." | |||
| 2299 | (interactive "p") | 2301 | (interactive "p") |
| 2300 | (compilation-next-file (- n))) | 2302 | (compilation-next-file (- n))) |
| 2301 | 2303 | ||
| 2304 | (defun compilation-display-error () | ||
| 2305 | "Display the source for current error in another window." | ||
| 2306 | (interactive) | ||
| 2307 | (setq compilation-current-error (point)) | ||
| 2308 | (next-error-no-select 0)) | ||
| 2309 | |||
| 2302 | (defun kill-compilation () | 2310 | (defun kill-compilation () |
| 2303 | "Kill the process made by the \\[compile] or \\[grep] commands." | 2311 | "Kill the process made by the \\[compile] or \\[grep] commands." |
| 2304 | (interactive) | 2312 | (interactive) |
| @@ -2374,10 +2382,12 @@ This is the value of `next-error-function' in Compilation buffers." | |||
| 2374 | ;; (setq timestamp compilation-buffer-modtime))) | 2382 | ;; (setq timestamp compilation-buffer-modtime))) |
| 2375 | ) | 2383 | ) |
| 2376 | (with-current-buffer | 2384 | (with-current-buffer |
| 2377 | (compilation-find-file | 2385 | (apply #'compilation-find-file |
| 2378 | marker | 2386 | marker |
| 2379 | (caar (compilation--loc->file-struct loc)) | 2387 | (caar (compilation--loc->file-struct loc)) |
| 2380 | (cadr (car (compilation--loc->file-struct loc)))) | 2388 | (cadr (car (compilation--loc->file-struct loc))) |
| 2389 | (compilation--file-struct->formats | ||
| 2390 | (compilation--loc->file-struct loc))) | ||
| 2381 | (let ((screen-columns | 2391 | (let ((screen-columns |
| 2382 | ;; Obey the compilation-error-screen-columns of the target | 2392 | ;; Obey the compilation-error-screen-columns of the target |
| 2383 | ;; buffer if its major mode set it buffer-locally. | 2393 | ;; buffer if its major mode set it buffer-locally. |
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index e8678fe6281..910e7c49d2a 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el | |||
| @@ -565,6 +565,7 @@ If nil, the value of `cperl-indent-level' will be used." | |||
| 565 | "*Non-nil means that the _ (underline) should be treated as word char." | 565 | "*Non-nil means that the _ (underline) should be treated as word char." |
| 566 | :type 'boolean | 566 | :type 'boolean |
| 567 | :group 'cperl) | 567 | :group 'cperl) |
| 568 | (make-obsolete-variable 'cperl-under-as-char 'superword-mode "24.4") | ||
| 568 | 569 | ||
| 569 | (defcustom cperl-extra-perl-args "" | 570 | (defcustom cperl-extra-perl-args "" |
| 570 | "*Extra arguments to use when starting Perl. | 571 | "*Extra arguments to use when starting Perl. |
| @@ -1905,7 +1906,7 @@ or as help on variables `cperl-tips', `cperl-problems', | |||
| 1905 | (and (boundp 'msb-menu-cond) | 1906 | (and (boundp 'msb-menu-cond) |
| 1906 | (not cperl-msb-fixed) | 1907 | (not cperl-msb-fixed) |
| 1907 | (cperl-msb-fix)) | 1908 | (cperl-msb-fix)) |
| 1908 | (if (featurep 'easymenu) | 1909 | (if (fboundp 'easy-menu-add) |
| 1909 | (easy-menu-add cperl-menu)) ; A NOP in Emacs. | 1910 | (easy-menu-add cperl-menu)) ; A NOP in Emacs. |
| 1910 | (run-mode-hooks 'cperl-mode-hook) | 1911 | (run-mode-hooks 'cperl-mode-hook) |
| 1911 | (if cperl-hook-after-change | 1912 | (if cperl-hook-after-change |
| @@ -6529,6 +6530,9 @@ side-effect of memorizing only. Examples in `cperl-style-examples'." | |||
| 6529 | (let ((perl-dbg-flags (concat cperl-extra-perl-args " -wc"))) | 6530 | (let ((perl-dbg-flags (concat cperl-extra-perl-args " -wc"))) |
| 6530 | (eval '(mode-compile)))) ; Avoid a warning | 6531 | (eval '(mode-compile)))) ; Avoid a warning |
| 6531 | 6532 | ||
| 6533 | (declare-function Info-find-node "info" | ||
| 6534 | (filename nodename &optional no-going-back)) | ||
| 6535 | |||
| 6532 | (defun cperl-info-buffer (type) | 6536 | (defun cperl-info-buffer (type) |
| 6533 | ;; Returns buffer with documentation. Creates if missing. | 6537 | ;; Returns buffer with documentation. Creates if missing. |
| 6534 | ;; If TYPE, this vars buffer. | 6538 | ;; If TYPE, this vars buffer. |
| @@ -6667,10 +6671,13 @@ Customized by setting variables `cperl-shrink-wrap-info-frame', | |||
| 6667 | (buffer-substring | 6671 | (buffer-substring |
| 6668 | (match-beginning 1) (match-end 1))) | 6672 | (match-beginning 1) (match-end 1))) |
| 6669 | 6673 | ||
| 6674 | (declare-function imenu-choose-buffer-index "imenu" (&optional prompt alist)) | ||
| 6675 | |||
| 6670 | (defun cperl-imenu-on-info () | 6676 | (defun cperl-imenu-on-info () |
| 6671 | "Shows imenu for Perl Info Buffer. | 6677 | "Shows imenu for Perl Info Buffer. |
| 6672 | Opens Perl Info buffer if needed." | 6678 | Opens Perl Info buffer if needed." |
| 6673 | (interactive) | 6679 | (interactive) |
| 6680 | (require 'imenu) | ||
| 6674 | (let* ((buffer (current-buffer)) | 6681 | (let* ((buffer (current-buffer)) |
| 6675 | imenu-create-index-function | 6682 | imenu-create-index-function |
| 6676 | imenu-prev-index-position-function | 6683 | imenu-prev-index-position-function |
| @@ -7130,6 +7137,10 @@ Use as | |||
| 7130 | (defvar cperl-hierarchy '(() ()) | 7137 | (defvar cperl-hierarchy '(() ()) |
| 7131 | "Global hierarchy of classes.") | 7138 | "Global hierarchy of classes.") |
| 7132 | 7139 | ||
| 7140 | ;; Follows call to (autoloaded) visit-tags-table. | ||
| 7141 | (declare-function file-of-tag "etags" (&optional relative)) | ||
| 7142 | (declare-function etags-snarf-tag "etags" (&optional use-explicit)) | ||
| 7143 | |||
| 7133 | (defun cperl-tags-hier-fill () | 7144 | (defun cperl-tags-hier-fill () |
| 7134 | ;; Suppose we are in a tag table cooked by cperl. | 7145 | ;; Suppose we are in a tag table cooked by cperl. |
| 7135 | (goto-char 1) | 7146 | (goto-char 1) |
| @@ -7173,6 +7184,7 @@ Use as | |||
| 7173 | (end-of-line)))) | 7184 | (end-of-line)))) |
| 7174 | 7185 | ||
| 7175 | (declare-function x-popup-menu "menu.c" (position menu)) | 7186 | (declare-function x-popup-menu "menu.c" (position menu)) |
| 7187 | (declare-function etags-goto-tag-location "etags" (tag-info)) | ||
| 7176 | 7188 | ||
| 7177 | (defun cperl-tags-hier-init (&optional update) | 7189 | (defun cperl-tags-hier-init (&optional update) |
| 7178 | "Show hierarchical menu of classes and methods. | 7190 | "Show hierarchical menu of classes and methods. |
| @@ -8516,6 +8528,8 @@ the appropriate statement modifier." | |||
| 8516 | ;;(error "Not at `if', `unless', `while', `until', `for' or `foreach'") | 8528 | ;;(error "Not at `if', `unless', `while', `until', `for' or `foreach'") |
| 8517 | (cperl-invert-if-unless-modifiers))) | 8529 | (cperl-invert-if-unless-modifiers))) |
| 8518 | 8530 | ||
| 8531 | (declare-function Man-getpage-in-background "man" (topic)) | ||
| 8532 | |||
| 8519 | ;;; By Anthony Foiani <afoiani@uswest.com> | 8533 | ;;; By Anthony Foiani <afoiani@uswest.com> |
| 8520 | ;;; Getting help on modules in C-h f ? | 8534 | ;;; Getting help on modules in C-h f ? |
| 8521 | ;;; This is a modified version of `man'. | 8535 | ;;; This is a modified version of `man'. |
diff --git a/lisp/progmodes/cpp.el b/lisp/progmodes/cpp.el index 674d98b8dc3..d332d8bff31 100644 --- a/lisp/progmodes/cpp.el +++ b/lisp/progmodes/cpp.el | |||
| @@ -136,13 +136,18 @@ Each entry is a list with the following elements: | |||
| 136 | ("true" . t) | 136 | ("true" . t) |
| 137 | ("both" . both))) | 137 | ("both" . both))) |
| 138 | 138 | ||
| 139 | ;; FIXME Gets clobbered by cpp-choose-face, so why is even it a defcustom? | ||
| 139 | (defcustom cpp-face-default-list nil | 140 | (defcustom cpp-face-default-list nil |
| 140 | "Alist of faces you can choose from for cpp conditionals. | 141 | "Alist of faces you can choose from for cpp conditionals. |
| 141 | Each element has the form (STRING . FACE), where STRING | 142 | Each element has the form (STRING . FACE), where STRING |
| 142 | serves as a name (for `cpp-highlight-buffer' only) | 143 | serves as a name (for `cpp-highlight-buffer' only) |
| 143 | and FACE is either a face (a symbol) | 144 | and FACE is either a face (a symbol) |
| 144 | or a cons cell (background-color . COLOR)." | 145 | or a cons cell (background-color . COLOR)." |
| 145 | :type '(repeat (cons string (choice face (cons (const background-color) string)))) | 146 | :type '(alist :key-type (string :tag "Name") |
| 147 | :value-type (choice face | ||
| 148 | (const invisible) | ||
| 149 | (cons (const background-color) | ||
| 150 | (string :tag "Color")))) | ||
| 146 | :group 'cpp) | 151 | :group 'cpp) |
| 147 | 152 | ||
| 148 | (defcustom cpp-face-light-name-list | 153 | (defcustom cpp-face-light-name-list |
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el index dba1d6a2f9b..9bde2900a67 100644 --- a/lisp/progmodes/f90.el +++ b/lisp/progmodes/f90.el | |||
| @@ -247,15 +247,36 @@ | |||
| 247 | 247 | ||
| 248 | (defcustom f90-smart-end 'blink | 248 | (defcustom f90-smart-end 'blink |
| 249 | "Qualification of END statements according to the matching block start. | 249 | "Qualification of END statements according to the matching block start. |
| 250 | For example, the END that closes an IF block is changed to END | 250 | For example, change the END that closes an IF block to END IF. |
| 251 | IF. If the block has a label, this is added as well. Allowed | 251 | If the block has a label, add it as well (unless `f90-smart-end-names' |
| 252 | values are 'blink, 'no-blink, and nil. If nil, nothing is done. | 252 | says not to). Allowed values are `blink', `no-blink', and nil. If nil, |
| 253 | The other two settings have the same effect, but 'blink | 253 | nothing is done. The other two settings have the same effect, but `blink' |
| 254 | additionally blinks the cursor to the start of the block." | 254 | additionally blinks the cursor to the start of the block." |
| 255 | :type '(choice (const blink) (const no-blink) (const nil)) | 255 | :type '(choice (const blink) (const no-blink) (const nil)) |
| 256 | :safe (lambda (value) (memq value '(blink no-blink nil))) | 256 | :safe (lambda (value) (memq value '(blink no-blink nil))) |
| 257 | :group 'f90) | 257 | :group 'f90) |
| 258 | 258 | ||
| 259 | ;; Optional: program, module, type, function, subroutine | ||
| 260 | ;; Not optional: block data?, forall, if, select case/type, associate, do, | ||
| 261 | ;; where, interface, critical | ||
| 262 | ;; No labels: enum | ||
| 263 | (defcustom f90-smart-end-names t | ||
| 264 | "Whether completion of END statements should insert optional block names. | ||
| 265 | For example, when closing a \"PROGRAM PROGNAME\" block, \"PROGNAME\" is | ||
| 266 | optional in the \"END PROGRAM\" statement. The same is true for modules, | ||
| 267 | functions, subroutines, and types. Some people prefer to omit the name | ||
| 268 | from the END statement, since it makes it easier to change the name. | ||
| 269 | |||
| 270 | This does not apply to named DO, IF, etc. blocks. If such blocks | ||
| 271 | start with a label, they must end with one. | ||
| 272 | |||
| 273 | If an end statement has a name that does not match the start, it is always | ||
| 274 | corrected, regardless of the value of this variable." | ||
| 275 | :type 'boolean | ||
| 276 | :safe 'booleanp | ||
| 277 | :group 'f90 | ||
| 278 | :version "24.4") | ||
| 279 | |||
| 259 | (defcustom f90-break-delimiters "[-+\\*/><=,% \t]" | 280 | (defcustom f90-break-delimiters "[-+\\*/><=,% \t]" |
| 260 | "Regexp matching delimiter characters at which lines may be broken. | 281 | "Regexp matching delimiter characters at which lines may be broken. |
| 261 | There are some common two-character tokens where one or more of | 282 | There are some common two-character tokens where one or more of |
| @@ -298,55 +319,61 @@ The options are 'downcase-word, 'upcase-word, 'capitalize-word and nil." | |||
| 298 | ;; User options end here. | 319 | ;; User options end here. |
| 299 | 320 | ||
| 300 | (defconst f90-keywords-re | 321 | (defconst f90-keywords-re |
| 301 | (regexp-opt '("allocatable" "allocate" "assign" "assignment" "backspace" | 322 | (concat |
| 302 | "block" "call" "case" "character" "close" "common" "complex" | 323 | "\\_<" |
| 303 | "contains" "continue" "cycle" "data" "deallocate" | 324 | (regexp-opt '("allocatable" "allocate" "assign" "assignment" "backspace" |
| 304 | "dimension" "do" "double" "else" "elseif" "elsewhere" "end" | 325 | "block" "call" "case" "character" "close" "common" "complex" |
| 305 | "enddo" "endfile" "endif" "entry" "equivalence" "exit" | 326 | "contains" "continue" "cycle" "data" "deallocate" |
| 306 | "external" "forall" "format" "function" "goto" "if" | 327 | "dimension" "do" "double" "else" "elseif" "elsewhere" "end" |
| 307 | "implicit" "include" "inquire" "integer" "intent" | 328 | "enddo" "endfile" "endif" "entry" "equivalence" "exit" |
| 308 | "interface" "intrinsic" "logical" "module" "namelist" "none" | 329 | "external" "forall" "format" "function" "goto" "if" |
| 309 | "nullify" "only" "open" "operator" "optional" "parameter" | 330 | "implicit" "include" "inquire" "integer" "intent" |
| 310 | "pause" "pointer" "precision" "print" "private" "procedure" | 331 | "interface" "intrinsic" "logical" "module" "namelist" "none" |
| 311 | "program" "public" "read" "real" "recursive" "result" "return" | 332 | "nullify" "only" "open" "operator" "optional" "parameter" |
| 312 | "rewind" "save" "select" "sequence" "stop" "subroutine" | 333 | "pause" "pointer" "precision" "print" "private" "procedure" |
| 313 | "target" "then" "type" "use" "where" "while" "write" | 334 | "program" "public" "read" "real" "recursive" "result" "return" |
| 314 | ;; F95 keywords. | 335 | "rewind" "save" "select" "sequence" "stop" "subroutine" |
| 315 | "elemental" "pure" | 336 | "target" "then" "type" "use" "where" "while" "write" |
| 316 | ;; F2003 | 337 | ;; F95 keywords. |
| 317 | "abstract" "associate" "asynchronous" "bind" "class" | 338 | "elemental" "pure" |
| 318 | "deferred" "enum" "enumerator" "extends" "extends_type_of" | 339 | ;; F2003 |
| 319 | "final" "generic" "import" "non_intrinsic" "non_overridable" | 340 | "abstract" "associate" "asynchronous" "bind" "class" |
| 320 | "nopass" "pass" "protected" "same_type_as" "value" "volatile" | 341 | "deferred" "enum" "enumerator" "extends" "extends_type_of" |
| 321 | ;; F2008. | 342 | "final" "generic" "import" "non_intrinsic" "non_overridable" |
| 322 | "contiguous" "submodule" "concurrent" "codimension" | 343 | "nopass" "pass" "protected" "same_type_as" "value" "volatile" |
| 323 | "sync all" "sync memory" "critical" "image_index" | 344 | ;; F2008. |
| 324 | ) 'words) | 345 | "contiguous" "submodule" "concurrent" "codimension" |
| 346 | "sync all" "sync memory" "critical" "image_index" | ||
| 347 | )) | ||
| 348 | "\\_>") | ||
| 325 | "Regexp used by the function `f90-change-keywords'.") | 349 | "Regexp used by the function `f90-change-keywords'.") |
| 326 | 350 | ||
| 327 | (defconst f90-keywords-level-3-re | 351 | (defconst f90-keywords-level-3-re |
| 328 | (regexp-opt | 352 | (concat |
| 329 | '("allocatable" "allocate" "assign" "assignment" "backspace" | 353 | "\\_<" |
| 330 | "close" "deallocate" "dimension" "endfile" "entry" "equivalence" | 354 | (regexp-opt |
| 331 | "external" "inquire" "intent" "intrinsic" "nullify" "only" "open" | 355 | '("allocatable" "allocate" "assign" "assignment" "backspace" |
| 332 | ;; FIXME operator and assignment should be F2003 procedures? | 356 | "close" "deallocate" "dimension" "endfile" "entry" "equivalence" |
| 333 | "operator" "optional" "parameter" "pause" "pointer" "print" "private" | 357 | "external" "inquire" "intent" "intrinsic" "nullify" "only" "open" |
| 334 | "public" "read" "recursive" "result" "rewind" "save" "select" | 358 | ;; FIXME operator and assignment should be F2003 procedures? |
| 335 | "sequence" "target" "write" | 359 | "operator" "optional" "parameter" "pause" "pointer" "print" "private" |
| 336 | ;; F95 keywords. | 360 | "public" "read" "recursive" "result" "rewind" "save" "select" |
| 337 | "elemental" "pure" | 361 | "sequence" "target" "write" |
| 338 | ;; F2003. asynchronous separate. | 362 | ;; F95 keywords. |
| 339 | "abstract" "deferred" "import" "final" "non_intrinsic" "non_overridable" | 363 | "elemental" "pure" |
| 340 | "nopass" "pass" "protected" "value" "volatile" | 364 | ;; F2003. asynchronous separate. |
| 341 | ;; F2008. | 365 | "abstract" "deferred" "import" "final" "non_intrinsic" "non_overridable" |
| 342 | ;; "concurrent" is only in the sense of "do [,] concurrent", but given | 366 | "nopass" "pass" "protected" "value" "volatile" |
| 343 | ;; the [,] it's simpler to just do every instance (cf "do while"). | 367 | ;; F2008. |
| 344 | "contiguous" "concurrent" "codimension" "sync all" "sync memory" | 368 | ;; "concurrent" is only in the sense of "do [,] concurrent", but given |
| 345 | ) 'words) | 369 | ;; the [,] it's simpler to just do every instance (cf "do while"). |
| 370 | "contiguous" "concurrent" "codimension" "sync all" "sync memory" | ||
| 371 | )) | ||
| 372 | "\\_>") | ||
| 346 | "Keyword-regexp for font-lock level >= 3.") | 373 | "Keyword-regexp for font-lock level >= 3.") |
| 347 | 374 | ||
| 348 | (defconst f90-procedures-re | 375 | (defconst f90-procedures-re |
| 349 | (concat "\\<" | 376 | (concat "\\_<" |
| 350 | (regexp-opt | 377 | (regexp-opt |
| 351 | '("abs" "achar" "acos" "adjustl" "adjustr" "aimag" "aint" | 378 | '("abs" "achar" "acos" "adjustl" "adjustr" "aimag" "aint" |
| 352 | "all" "allocated" "anint" "any" "asin" "associated" | 379 | "all" "allocated" "anint" "any" "asin" "associated" |
| @@ -407,61 +434,67 @@ The options are 'downcase-word, 'upcase-word, 'capitalize-word and nil." | |||
| 407 | "Regexp matching intrinsic operators.") | 434 | "Regexp matching intrinsic operators.") |
| 408 | 435 | ||
| 409 | (defconst f90-hpf-keywords-re | 436 | (defconst f90-hpf-keywords-re |
| 410 | (regexp-opt | 437 | (concat |
| 411 | ;; Intrinsic procedures. | 438 | "\\_<" |
| 412 | '("all_prefix" "all_scatter" "all_suffix" "any_prefix" | 439 | (regexp-opt |
| 413 | "any_scatter" "any_suffix" "copy_prefix" "copy_scatter" | 440 | ;; Intrinsic procedures. |
| 414 | "copy_suffix" "count_prefix" "count_scatter" "count_suffix" | 441 | '("all_prefix" "all_scatter" "all_suffix" "any_prefix" |
| 415 | "grade_down" "grade_up" | 442 | "any_scatter" "any_suffix" "copy_prefix" "copy_scatter" |
| 416 | "hpf_alignment" "hpf_distribution" "hpf_template" "iall" "iall_prefix" | 443 | "copy_suffix" "count_prefix" "count_scatter" "count_suffix" |
| 417 | "iall_scatter" "iall_suffix" "iany" "iany_prefix" "iany_scatter" | 444 | "grade_down" "grade_up" |
| 418 | "iany_suffix" "ilen" "iparity" "iparity_prefix" | 445 | "hpf_alignment" "hpf_distribution" "hpf_template" "iall" "iall_prefix" |
| 419 | "iparity_scatter" "iparity_suffix" "leadz" "maxval_prefix" | 446 | "iall_scatter" "iall_suffix" "iany" "iany_prefix" "iany_scatter" |
| 420 | "maxval_scatter" "maxval_suffix" "minval_prefix" "minval_scatter" | 447 | "iany_suffix" "ilen" "iparity" "iparity_prefix" |
| 421 | "minval_suffix" "number_of_processors" "parity" | 448 | "iparity_scatter" "iparity_suffix" "leadz" "maxval_prefix" |
| 422 | "parity_prefix" "parity_scatter" "parity_suffix" "popcnt" "poppar" | 449 | "maxval_scatter" "maxval_suffix" "minval_prefix" "minval_scatter" |
| 423 | "processors_shape" "product_prefix" "product_scatter" | 450 | "minval_suffix" "number_of_processors" "parity" |
| 424 | "product_suffix" "sum_prefix" "sum_scatter" "sum_suffix" | 451 | "parity_prefix" "parity_scatter" "parity_suffix" "popcnt" "poppar" |
| 425 | ;; Directives. | 452 | "processors_shape" "product_prefix" "product_scatter" |
| 426 | "align" "distribute" "dynamic" "independent" "inherit" "processors" | 453 | "product_suffix" "sum_prefix" "sum_scatter" "sum_suffix" |
| 427 | "realign" "redistribute" "template" | 454 | ;; Directives. |
| 428 | ;; Keywords. | 455 | "align" "distribute" "dynamic" "independent" "inherit" "processors" |
| 429 | "block" "cyclic" "extrinsic" "new" "onto" "pure" "with") 'words) | 456 | "realign" "redistribute" "template" |
| 457 | ;; Keywords. | ||
| 458 | "block" "cyclic" "extrinsic" "new" "onto" "pure" "with")) | ||
| 459 | "\\_>") | ||
| 430 | "Regexp for all HPF keywords, procedures and directives.") | 460 | "Regexp for all HPF keywords, procedures and directives.") |
| 431 | 461 | ||
| 432 | (defconst f90-constants-re | 462 | (defconst f90-constants-re |
| 433 | (regexp-opt '( ;; F2003 iso_fortran_env constants. | 463 | (concat |
| 434 | "iso_fortran_env" | 464 | "\\_<" |
| 435 | "input_unit" "output_unit" "error_unit" | 465 | (regexp-opt '( ;; F2003 iso_fortran_env constants. |
| 436 | "iostat_end" "iostat_eor" | 466 | "iso_fortran_env" |
| 437 | "numeric_storage_size" "character_storage_size" | 467 | "input_unit" "output_unit" "error_unit" |
| 438 | "file_storage_size" | 468 | "iostat_end" "iostat_eor" |
| 439 | ;; F2003 iso_c_binding constants. | 469 | "numeric_storage_size" "character_storage_size" |
| 440 | "iso_c_binding" | 470 | "file_storage_size" |
| 441 | "c_int" "c_short" "c_long" "c_long_long" "c_signed_char" | 471 | ;; F2003 iso_c_binding constants. |
| 442 | "c_size_t" | 472 | "iso_c_binding" |
| 443 | "c_int8_t" "c_int16_t" "c_int32_t" "c_int64_t" | 473 | "c_int" "c_short" "c_long" "c_long_long" "c_signed_char" |
| 444 | "c_int_least8_t" "c_int_least16_t" "c_int_least32_t" | 474 | "c_size_t" |
| 445 | "c_int_least64_t" | 475 | "c_int8_t" "c_int16_t" "c_int32_t" "c_int64_t" |
| 446 | "c_int_fast8_t" "c_int_fast16_t" "c_int_fast32_t" | 476 | "c_int_least8_t" "c_int_least16_t" "c_int_least32_t" |
| 447 | "c_int_fast64_t" | 477 | "c_int_least64_t" |
| 448 | "c_intmax_t" "c_intptr_t" | 478 | "c_int_fast8_t" "c_int_fast16_t" "c_int_fast32_t" |
| 449 | "c_float" "c_double" "c_long_double" | 479 | "c_int_fast64_t" |
| 450 | "c_float_complex" "c_double_complex" "c_long_double_complex" | 480 | "c_intmax_t" "c_intptr_t" |
| 451 | "c_bool" "c_char" | 481 | "c_float" "c_double" "c_long_double" |
| 452 | "c_null_char" "c_alert" "c_backspace" "c_form_feed" | 482 | "c_float_complex" "c_double_complex" "c_long_double_complex" |
| 453 | "c_new_line" "c_carriage_return" "c_horizontal_tab" | 483 | "c_bool" "c_char" |
| 454 | "c_vertical_tab" | 484 | "c_null_char" "c_alert" "c_backspace" "c_form_feed" |
| 455 | "c_ptr" "c_funptr" "c_null_ptr" "c_null_funptr" | 485 | "c_new_line" "c_carriage_return" "c_horizontal_tab" |
| 456 | "ieee_exceptions" | 486 | "c_vertical_tab" |
| 457 | "ieee_arithmetic" | 487 | "c_ptr" "c_funptr" "c_null_ptr" "c_null_funptr" |
| 458 | "ieee_features" | 488 | "ieee_exceptions" |
| 459 | ;; F2008 iso_fortran_env constants. | 489 | "ieee_arithmetic" |
| 460 | "character_kinds" "int8" "int16" "int32" "int64" | 490 | "ieee_features" |
| 461 | "integer_kinds" "iostat_inquire_internal_unit" | 491 | ;; F2008 iso_fortran_env constants. |
| 462 | "logical_kinds" "real_kinds" "real32" "real64" "real128" | 492 | "character_kinds" "int8" "int16" "int32" "int64" |
| 463 | "lock_type" "atomic_int_kind" "atomic_logical_kind" | 493 | "integer_kinds" "iostat_inquire_internal_unit" |
| 464 | ) 'words) | 494 | "logical_kinds" "real_kinds" "real32" "real64" "real128" |
| 495 | "lock_type" "atomic_int_kind" "atomic_logical_kind" | ||
| 496 | )) | ||
| 497 | "\\_>") | ||
| 465 | "Regexp for Fortran intrinsic constants.") | 498 | "Regexp for Fortran intrinsic constants.") |
| 466 | 499 | ||
| 467 | ;; cf f90-looking-at-type-like. | 500 | ;; cf f90-looking-at-type-like. |
| @@ -470,16 +503,16 @@ The options are 'downcase-word, 'upcase-word, 'capitalize-word and nil." | |||
| 470 | Set the match data so that subexpression 1,2 are the TYPE, and | 503 | Set the match data so that subexpression 1,2 are the TYPE, and |
| 471 | type-name parts, respectively." | 504 | type-name parts, respectively." |
| 472 | (let (found l) | 505 | (let (found l) |
| 473 | (while (and (re-search-forward "\\<\\(\\(?:end[ \t]*\\)?type\\)\\>[ \t]*" | 506 | (while (and (re-search-forward "\\_<\\(\\(?:end[ \t]*\\)?type\\)\\_>[ \t]*" |
| 474 | limit t) | 507 | limit t) |
| 475 | (not (setq found | 508 | (not (setq found |
| 476 | (progn | 509 | (progn |
| 477 | (setq l (match-data)) | 510 | (setq l (match-data)) |
| 478 | (unless (looking-at "\\(is\\>\\|(\\)") | 511 | (unless (looking-at "\\(is\\_>\\|(\\)") |
| 479 | (when (if (looking-at "\\(\\sw+\\)") | 512 | (when (if (looking-at "\\(\\(?:\\sw\\|\\s_\\)+\\)") |
| 480 | (goto-char (match-end 0)) | 513 | (goto-char (match-end 0)) |
| 481 | (re-search-forward | 514 | (re-search-forward |
| 482 | "[ \t]*::[ \t]*\\(\\sw+\\)" | 515 | "[ \t]*::[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)" |
| 483 | (line-end-position) t)) | 516 | (line-end-position) t)) |
| 484 | ;; 0 is wrong, but we don't use it. | 517 | ;; 0 is wrong, but we don't use it. |
| 485 | (set-match-data | 518 | (set-match-data |
| @@ -491,33 +524,33 @@ type-name parts, respectively." | |||
| 491 | (defvar f90-font-lock-keywords-1 | 524 | (defvar f90-font-lock-keywords-1 |
| 492 | (list | 525 | (list |
| 493 | ;; Special highlighting of "module procedure". | 526 | ;; Special highlighting of "module procedure". |
| 494 | '("\\<\\(module[ \t]*procedure\\)\\>\\([^()\n]*::\\)?[ \t]*\\([^&!\n]*\\)" | 527 | '("\\_<\\(module[ \t]*procedure\\)\\_>\\([^()\n]*::\\)?[ \t]*\\([^&!\n]*\\)" |
| 495 | (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) | 528 | (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) |
| 496 | ;; Highlight definition of derived type. | 529 | ;; Highlight definition of derived type. |
| 497 | ;;; '("\\<\\(\\(?:end[ \t]*\\)?type\\)\\>\\([^()\n]*::\\)?[ \t]*\\(\\sw+\\)" | 530 | ;;; '("\\_<\\(\\(?:end[ \t]*\\)?type\\)\\_>\\([^()\n]*::\\)?[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)" |
| 498 | ;;; (1 font-lock-keyword-face) (3 font-lock-function-name-face)) | 531 | ;;; (1 font-lock-keyword-face) (3 font-lock-function-name-face)) |
| 499 | '(f90-typedef-matcher | 532 | '(f90-typedef-matcher |
| 500 | (1 font-lock-keyword-face) (2 font-lock-function-name-face)) | 533 | (1 font-lock-keyword-face) (2 font-lock-function-name-face)) |
| 501 | ;; F2003. Prevent operators being highlighted as functions. | 534 | ;; F2003. Prevent operators being highlighted as functions. |
| 502 | '("\\<\\(\\(?:end[ \t]*\\)?interface[ \t]*\\(?:assignment\\|operator\\|\ | 535 | '("\\_<\\(\\(?:end[ \t]*\\)?interface[ \t]*\\(?:assignment\\|operator\\|\ |
| 503 | read\\|write\\)\\)[ \t]*(" (1 font-lock-keyword-face t)) | 536 | read\\|write\\)\\)[ \t]*(" (1 font-lock-keyword-face t)) |
| 504 | ;; Other functions and declarations. Named interfaces = F2003. | 537 | ;; Other functions and declarations. Named interfaces = F2003. |
| 505 | ;; F2008: end submodule submodule_name. | 538 | ;; F2008: end submodule submodule_name. |
| 506 | '("\\<\\(\\(?:end[ \t]*\\)?\\(program\\|\\(?:sub\\)?module\\|\ | 539 | '("\\_<\\(\\(?:end[ \t]*\\)?\\(program\\|\\(?:sub\\)?module\\|\ |
| 507 | function\\|associate\\|subroutine\\|interface\\)\\|use\\|call\\)\ | 540 | function\\|associate\\|subroutine\\|interface\\)\\|use\\|call\\)\ |
| 508 | \\>[ \t]*\\(\\sw+\\)?" | 541 | \\_>[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?" |
| 509 | (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) | 542 | (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) |
| 510 | ;; F2008: submodule (parent_name) submodule_name. | 543 | ;; F2008: submodule (parent_name) submodule_name. |
| 511 | '("\\<\\(submodule\\)\\>[ \t]*([^)\n]+)[ \t]*\\(\\sw+\\)?" | 544 | '("\\_<\\(submodule\\)\\_>[ \t]*([^)\n]+)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?" |
| 512 | (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) | 545 | (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) |
| 513 | ;; F2003. | 546 | ;; F2003. |
| 514 | '("\\<\\(use\\)[ \t]*,[ \t]*\\(\\(?:non_\\)?intrinsic\\)[ \t]*::[ \t]*\ | 547 | '("\\_<\\(use\\)[ \t]*,[ \t]*\\(\\(?:non_\\)?intrinsic\\)[ \t]*::[ \t]*\ |
| 515 | \\(\\sw+\\)" | 548 | \\(\\(?:\\sw\\|\\s_\\)+\\)" |
| 516 | (1 font-lock-keyword-face) (2 font-lock-keyword-face) | 549 | (1 font-lock-keyword-face) (2 font-lock-keyword-face) |
| 517 | (3 font-lock-function-name-face)) | 550 | (3 font-lock-function-name-face)) |
| 518 | "\\<\\(\\(end[ \t]*\\)?block[ \t]*data\\|contains\\)\\>" | 551 | "\\_<\\(\\(end[ \t]*\\)?block[ \t]*data\\|contains\\)\\_>" |
| 519 | ;; "abstract interface" is F2003. | 552 | ;; "abstract interface" is F2003. |
| 520 | '("\\<abstract[ \t]*interface\\>" (0 font-lock-keyword-face t))) | 553 | '("\\_<abstract[ \t]*interface\\_>" (0 font-lock-keyword-face t))) |
| 521 | "This does fairly subdued highlighting of comments and function calls.") | 554 | "This does fairly subdued highlighting of comments and function calls.") |
| 522 | 555 | ||
| 523 | ;; NB not explicitly handling this, yet it seems to work. | 556 | ;; NB not explicitly handling this, yet it seems to work. |
| @@ -529,7 +562,7 @@ and variable-name parts, respectively." | |||
| 529 | ;; Matcher functions must return nil only when there are no more | 562 | ;; Matcher functions must return nil only when there are no more |
| 530 | ;; matches within the search range. | 563 | ;; matches within the search range. |
| 531 | (let (found l) | 564 | (let (found l) |
| 532 | (while (and (re-search-forward "\\<\\(type\\|class\\)[ \t]*(" limit t) | 565 | (while (and (re-search-forward "\\_<\\(type\\|class\\)[ \t]*(" limit t) |
| 533 | (not | 566 | (not |
| 534 | (setq found | 567 | (setq found |
| 535 | (condition-case nil | 568 | (condition-case nil |
| @@ -544,7 +577,7 @@ and variable-name parts, respectively." | |||
| 544 | (when | 577 | (when |
| 545 | (re-search-forward | 578 | (re-search-forward |
| 546 | ;; type (foo) bar, qux | 579 | ;; type (foo) bar, qux |
| 547 | (if (looking-at "\\sw+") | 580 | (if (looking-at "\\(?:\\sw\\|\\s_\\)+") |
| 548 | "\\([^&!\n]+\\)" | 581 | "\\([^&!\n]+\\)" |
| 549 | ;; type (foo), stuff :: bar, qux | 582 | ;; type (foo), stuff :: bar, qux |
| 550 | "::[ \t]*\\([^&!\n]+\\)") | 583 | "::[ \t]*\\([^&!\n]+\\)") |
| @@ -587,53 +620,53 @@ enumerator\\|generic\\|procedure\\|logical\\|double[ \t]*precision\\)\ | |||
| 587 | ;; integer( kind=1 ) function foo() | 620 | ;; integer( kind=1 ) function foo() |
| 588 | ;; thanks to the happy accident described above. | 621 | ;; thanks to the happy accident described above. |
| 589 | ;; Not anchored, so don't need to worry about "pure" etc. | 622 | ;; Not anchored, so don't need to worry about "pure" etc. |
| 590 | '("\\<\\(\\(real\\|integer\\|c\\(haracter\\|omplex\\)\\|\ | 623 | '("\\_<\\(\\(real\\|integer\\|c\\(haracter\\|omplex\\)\\|\ |
| 591 | logical\\|double[ \t]*precision\\|\ | 624 | logical\\|double[ \t]*precision\\|\ |
| 592 | \\(?:type\\|class\\)[ \t]*([ \t]*\\sw+[ \t]*)\\)[ \t]*\\)\ | 625 | \\(?:type\\|class\\)[ \t]*([ \t]*\\(?:\\sw\\|\\s_\\)+[ \t]*)\\)[ \t]*\\)\ |
| 593 | \\(function\\)\\>[ \t]*\\(\\sw+\\)[ \t]*\\(([^&!\n]*)\\)" | 626 | \\(function\\)\\_>[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*\\(([^&!\n]*)\\)" |
| 594 | (1 font-lock-type-face t) (4 font-lock-keyword-face t) | 627 | (1 font-lock-type-face t) (4 font-lock-keyword-face t) |
| 595 | (5 font-lock-function-name-face t) (6 'default t)) | 628 | (5 font-lock-function-name-face t) (6 'default t)) |
| 596 | ;; enum (F2003; must be followed by ", bind(C)"). | 629 | ;; enum (F2003; must be followed by ", bind(C)"). |
| 597 | '("\\<\\(enum\\)[ \t]*," (1 font-lock-keyword-face)) | 630 | '("\\_<\\(enum\\)[ \t]*," (1 font-lock-keyword-face)) |
| 598 | ;; end do, enum (F2003), if, select, where, and forall constructs. | 631 | ;; end do, enum (F2003), if, select, where, and forall constructs. |
| 599 | ;; block, critical (F2008). | 632 | ;; block, critical (F2008). |
| 600 | ;; Note that "block data" may get somewhat mixed up with F2008 blocks, | 633 | ;; Note that "block data" may get somewhat mixed up with F2008 blocks, |
| 601 | ;; but since the former is obsolete I'm not going to worry about it. | 634 | ;; but since the former is obsolete I'm not going to worry about it. |
| 602 | '("\\<\\(end[ \t]*\\(do\\|if\\|enum\\|select\\|forall\\|where\\|\ | 635 | '("\\_<\\(end[ \t]*\\(do\\|if\\|enum\\|select\\|forall\\|where\\|\ |
| 603 | block\\|critical\\)\\)\\>\ | 636 | block\\|critical\\)\\)\\_>\ |
| 604 | \\([ \t]+\\(\\sw+\\)\\)?" | 637 | \\([ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\)?" |
| 605 | (1 font-lock-keyword-face) (3 font-lock-constant-face nil t)) | 638 | (1 font-lock-keyword-face) (3 font-lock-constant-face nil t)) |
| 606 | '("^[ \t0-9]*\\(\\(\\sw+\\)[ \t]*:[ \t]*\\)?\\(\\(if\\|\ | 639 | '("^[ \t0-9]*\\(\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:[ \t]*\\)?\\(\\(if\\|\ |
| 607 | do\\([ \t]*while\\)?\\|select[ \t]*\\(?:case\\|type\\)\\|where\\|\ | 640 | do\\([ \t]*while\\)?\\|select[ \t]*\\(?:case\\|type\\)\\|where\\|\ |
| 608 | forall\\|block\\|critical\\)\\)\\>" | 641 | forall\\|block\\|critical\\)\\)\\_>" |
| 609 | (2 font-lock-constant-face nil t) (3 font-lock-keyword-face)) | 642 | (2 font-lock-constant-face nil t) (3 font-lock-keyword-face)) |
| 610 | ;; Implicit declaration. | 643 | ;; Implicit declaration. |
| 611 | '("\\<\\(implicit\\)[ \t]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\ | 644 | '("\\_<\\(implicit\\)[ \t]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\ |
| 612 | \\|enumerator\\|procedure\\|\ | 645 | \\|enumerator\\|procedure\\|\ |
| 613 | logical\\|double[ \t]*precision\\|type[ \t]*(\\sw+)\\|none\\)[ \t]*" | 646 | logical\\|double[ \t]*precision\\|type[ \t]*(\\(?:\\sw\\|\\s_\\)+)\\|none\\)[ \t]*" |
| 614 | (1 font-lock-keyword-face) (2 font-lock-type-face)) | 647 | (1 font-lock-keyword-face) (2 font-lock-type-face)) |
| 615 | '("\\<\\(namelist\\|common\\)[ \t]*\/\\(\\sw+\\)?\/" | 648 | '("\\_<\\(namelist\\|common\\)[ \t]*\/\\(\\(?:\\sw\\|\\s_\\)+\\)?\/" |
| 616 | (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) | 649 | (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) |
| 617 | "\\<else\\([ \t]*if\\|where\\)?\\>" | 650 | "\\_<else\\([ \t]*if\\|where\\)?\\_>" |
| 618 | '("\\(&\\)[ \t]*\\(!\\|$\\)" (1 font-lock-keyword-face)) | 651 | '("\\(&\\)[ \t]*\\(!\\|$\\)" (1 font-lock-keyword-face)) |
| 619 | "\\<\\(then\\|continue\\|format\\|include\\|stop\\|return\\)\\>" | 652 | "\\_<\\(then\\|continue\\|format\\|include\\|stop\\|return\\)\\_>" |
| 620 | '("\\<\\(exit\\|cycle\\)[ \t]*\\(\\sw+\\)?\\>" | 653 | '("\\_<\\(exit\\|cycle\\)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?\\_>" |
| 621 | (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) | 654 | (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) |
| 622 | '("\\<\\(case\\)[ \t]*\\(default\\|(\\)" . 1) | 655 | '("\\_<\\(case\\)[ \t]*\\(default\\|(\\)" . 1) |
| 623 | ;; F2003 "class default". | 656 | ;; F2003 "class default". |
| 624 | '("\\<\\(class\\)[ \t]*default" . 1) | 657 | '("\\_<\\(class\\)[ \t]*default" . 1) |
| 625 | ;; F2003 "type is" in a "select type" block. | 658 | ;; F2003 "type is" in a "select type" block. |
| 626 | '("\\<\\(\\(type\\|class\\)[ \t]*is\\)[ \t]*(" (1 font-lock-keyword-face t)) | 659 | '("\\_<\\(\\(type\\|class\\)[ \t]*is\\)[ \t]*(" (1 font-lock-keyword-face t)) |
| 627 | '("\\<\\(do\\|go[ \t]*to\\)\\>[ \t]*\\([0-9]+\\)" | 660 | '("\\_<\\(do\\|go[ \t]*to\\)\\_>[ \t]*\\([0-9]+\\)" |
| 628 | (1 font-lock-keyword-face) (2 font-lock-constant-face)) | 661 | (1 font-lock-keyword-face) (2 font-lock-constant-face)) |
| 629 | ;; Line numbers (lines whose first character after number is letter). | 662 | ;; Line numbers (lines whose first character after number is letter). |
| 630 | '("^[ \t]*\\([0-9]+\\)[ \t]*[a-z]+" (1 font-lock-constant-face t)) | 663 | '("^[ \t]*\\([0-9]+\\)[ \t]*[a-z]+" (1 font-lock-constant-face t)) |
| 631 | ;; Override eg for "#include". | 664 | ;; Override eg for "#include". |
| 632 | '("^#[ \t]*\\w+" (0 font-lock-preprocessor-face t) | 665 | '("^#[ \t]*\\(?:\\sw\\|\\s_\\)+" (0 font-lock-preprocessor-face t) |
| 633 | ("\\<defined\\>" nil nil (0 font-lock-preprocessor-face))) | 666 | ("\\_<defined\\_>" nil nil (0 font-lock-preprocessor-face))) |
| 634 | '("^#" ("\\(&&\\|||\\)" nil nil (0 font-lock-constant-face t))) | 667 | '("^#" ("\\(&&\\|||\\)" nil nil (0 font-lock-constant-face t))) |
| 635 | '("^#[ \t]*define[ \t]+\\(\\w+\\)(" (1 font-lock-function-name-face)) | 668 | '("^#[ \t]*define[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)(" (1 font-lock-function-name-face)) |
| 636 | '("^#[ \t]*define[ \t]+\\(\\w+\\)" (1 font-lock-variable-name-face)) | 669 | '("^#[ \t]*define[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face)) |
| 637 | '("^#[ \t]*include[ \t]+\\(<.+>\\)" (1 font-lock-string-face)))) | 670 | '("^#[ \t]*include[ \t]+\\(<.+>\\)" (1 font-lock-string-face)))) |
| 638 | "Highlights declarations, do-loops and other constructs.") | 671 | "Highlights declarations, do-loops and other constructs.") |
| 639 | 672 | ||
| @@ -645,9 +678,9 @@ logical\\|double[ \t]*precision\\|type[ \t]*(\\sw+)\\|none\\)[ \t]*" | |||
| 645 | ;; FIXME why isn't this font-lock-builtin-face, which | 678 | ;; FIXME why isn't this font-lock-builtin-face, which |
| 646 | ;; otherwise we hardly use, as in fortran.el? | 679 | ;; otherwise we hardly use, as in fortran.el? |
| 647 | (list f90-procedures-re '(1 font-lock-keyword-face keep)) | 680 | (list f90-procedures-re '(1 font-lock-keyword-face keep)) |
| 648 | "\\<real\\>" ; avoid overwriting real defs | 681 | "\\_<real\\_>" ; avoid overwriting real defs |
| 649 | ;; As an attribute, but not as an optional argument. | 682 | ;; As an attribute, but not as an optional argument. |
| 650 | '("\\<\\(asynchronous\\)[ \t]*[^=]" . 1))) | 683 | '("\\_<\\(asynchronous\\)[ \t]*[^=]" . 1))) |
| 651 | "Highlights all F90 keywords and intrinsic procedures.") | 684 | "Highlights all F90 keywords and intrinsic procedures.") |
| 652 | 685 | ||
| 653 | (defvar f90-font-lock-keywords-4 | 686 | (defvar f90-font-lock-keywords-4 |
| @@ -666,8 +699,7 @@ Can be overridden by the value of `font-lock-maximum-decoration'.") | |||
| 666 | (let ((table (make-syntax-table))) | 699 | (let ((table (make-syntax-table))) |
| 667 | (modify-syntax-entry ?\! "<" table) ; begin comment | 700 | (modify-syntax-entry ?\! "<" table) ; begin comment |
| 668 | (modify-syntax-entry ?\n ">" table) ; end comment | 701 | (modify-syntax-entry ?\n ">" table) ; end comment |
| 669 | ;; FIXME: This goes against the convention: it should be "_". | 702 | (modify-syntax-entry ?_ "_" table) ; underscore in names |
| 670 | (modify-syntax-entry ?_ "w" table) ; underscore in names | ||
| 671 | (modify-syntax-entry ?\' "\"" table) ; string quote | 703 | (modify-syntax-entry ?\' "\"" table) ; string quote |
| 672 | (modify-syntax-entry ?\" "\"" table) ; string quote | 704 | (modify-syntax-entry ?\" "\"" table) ; string quote |
| 673 | ;; FIXME: We used to set ` to word syntax for the benefit of abbrevs, but | 705 | ;; FIXME: We used to set ` to word syntax for the benefit of abbrevs, but |
| @@ -822,14 +854,14 @@ Can be overridden by the value of `font-lock-maximum-decoration'.") | |||
| 822 | 854 | ||
| 823 | ;; Regexps for finding program structures. | 855 | ;; Regexps for finding program structures. |
| 824 | (defconst f90-blocks-re | 856 | (defconst f90-blocks-re |
| 825 | (concat "\\(block[ \t]*data\\|" | 857 | (concat "\\(\\(?:block[ \t]*data\\|" |
| 826 | (regexp-opt '("do" "if" "interface" "function" "module" "program" | 858 | (regexp-opt '("do" "if" "interface" "function" "module" "program" |
| 827 | "select" "subroutine" "type" "where" "forall" | 859 | "select" "subroutine" "type" "where" "forall" |
| 828 | ;; F2003. | 860 | ;; F2003. |
| 829 | "enum" "associate" | 861 | "enum" "associate" |
| 830 | ;; F2008. | 862 | ;; F2008. |
| 831 | "submodule" "block" "critical")) | 863 | "submodule" "block" "critical")) |
| 832 | "\\)\\>") | 864 | "\\)\\_>\\)") |
| 833 | "Regexp potentially indicating a \"block\" of F90 code.") | 865 | "Regexp potentially indicating a \"block\" of F90 code.") |
| 834 | 866 | ||
| 835 | (defconst f90-program-block-re | 867 | (defconst f90-program-block-re |
| @@ -845,15 +877,15 @@ Can be overridden by the value of `font-lock-maximum-decoration'.") | |||
| 845 | (defconst f90-end-if-re | 877 | (defconst f90-end-if-re |
| 846 | (concat "end[ \t]*" | 878 | (concat "end[ \t]*" |
| 847 | (regexp-opt '("if" "select" "where" "forall") 'paren) | 879 | (regexp-opt '("if" "select" "where" "forall") 'paren) |
| 848 | "\\>") | 880 | "\\_>") |
| 849 | "Regexp matching the end of an IF, SELECT, WHERE, FORALL block.") | 881 | "Regexp matching the end of an IF, SELECT, WHERE, FORALL block.") |
| 850 | 882 | ||
| 851 | (defconst f90-end-type-re | 883 | (defconst f90-end-type-re |
| 852 | "end[ \t]*\\(type\\|enum\\|interface\\|block[ \t]*data\\)\\>" | 884 | "end[ \t]*\\(type\\|enum\\|interface\\|block[ \t]*data\\)\\_>" |
| 853 | "Regexp matching the end of a TYPE, ENUM, INTERFACE, BLOCK DATA section.") | 885 | "Regexp matching the end of a TYPE, ENUM, INTERFACE, BLOCK DATA section.") |
| 854 | 886 | ||
| 855 | (defconst f90-end-associate-re | 887 | (defconst f90-end-associate-re |
| 856 | "end[ \t]*associate\\>" | 888 | "end[ \t]*associate\\_>" |
| 857 | "Regexp matching the end of an ASSOCIATE block.") | 889 | "Regexp matching the end of an ASSOCIATE block.") |
| 858 | 890 | ||
| 859 | ;; This is for a TYPE block, not a variable of derived TYPE. | 891 | ;; This is for a TYPE block, not a variable of derived TYPE. |
| @@ -864,12 +896,12 @@ Can be overridden by the value of `font-lock-maximum-decoration'.") | |||
| 864 | ;; type, stuff :: word | 896 | ;; type, stuff :: word |
| 865 | ;; type, bind(c) :: word | 897 | ;; type, bind(c) :: word |
| 866 | ;; NOT "type (" | 898 | ;; NOT "type (" |
| 867 | "\\<\\(type\\)\\>\\(?:\\(?:[^()\n]*\\|\ | 899 | "\\_<\\(type\\)\\_>\\(?:\\(?:[^()\n]*\\|\ |
| 868 | .*,[ \t]*bind[ \t]*([ \t]*c[ \t]*)[ \t]*\\)::\\)?[ \t]*\\(\\sw+\\)" | 900 | .*,[ \t]*bind[ \t]*([ \t]*c[ \t]*)[ \t]*\\)::\\)?[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)" |
| 869 | "Regexp matching the definition of a derived type.") | 901 | "Regexp matching the definition of a derived type.") |
| 870 | 902 | ||
| 871 | (defconst f90-typeis-re | 903 | (defconst f90-typeis-re |
| 872 | "\\<\\(class\\|type\\)[ \t]*is[ \t]*(" | 904 | "\\_<\\(class\\|type\\)[ \t]*is[ \t]*(" |
| 873 | "Regexp matching a CLASS/TYPE IS statement.") | 905 | "Regexp matching a CLASS/TYPE IS statement.") |
| 874 | 906 | ||
| 875 | (defconst f90-no-break-re | 907 | (defconst f90-no-break-re |
| @@ -888,12 +920,12 @@ allowed. This minor issue currently only affects \"(/\" and \"/)\".") | |||
| 888 | 920 | ||
| 889 | ;; Hideshow support. | 921 | ;; Hideshow support. |
| 890 | (defconst f90-end-block-re | 922 | (defconst f90-end-block-re |
| 891 | (concat "^[ \t0-9]*\\<end[ \t]*" | 923 | (concat "^[ \t0-9]*\\_<end[ \t]*" |
| 892 | (regexp-opt '("do" "if" "forall" "function" "interface" | 924 | (regexp-opt '("do" "if" "forall" "function" "interface" |
| 893 | "module" "program" "select" "subroutine" | 925 | "module" "program" "select" "subroutine" |
| 894 | "type" "where" "enum" "associate" "submodule" | 926 | "type" "where" "enum" "associate" "submodule" |
| 895 | "block" "critical") t) | 927 | "block" "critical") t) |
| 896 | "\\>") | 928 | "\\_>") |
| 897 | "Regexp matching the end of an F90 \"block\", from the line start. | 929 | "Regexp matching the end of an F90 \"block\", from the line start. |
| 898 | Used in the F90 entry in `hs-special-modes-alist'.") | 930 | Used in the F90 entry in `hs-special-modes-alist'.") |
| 899 | 931 | ||
| @@ -903,11 +935,11 @@ Used in the F90 entry in `hs-special-modes-alist'.") | |||
| 903 | (concat | 935 | (concat |
| 904 | "^[ \t0-9]*" ; statement number | 936 | "^[ \t0-9]*" ; statement number |
| 905 | "\\(\\(" | 937 | "\\(\\(" |
| 906 | "\\(\\sw+[ \t]*:[ \t]*\\)?" ; structure label | 938 | "\\(\\(?:\\sw\\|\\s_\\)+[ \t]*:[ \t]*\\)?" ; structure label |
| 907 | "\\(do\\|select[ \t]*\\(case\\|type\\)\\|" | 939 | "\\(do\\|select[ \t]*\\(case\\|type\\)\\|" |
| 908 | ;; See comments in fortran-start-block-re for the problems of IF. | 940 | ;; See comments in fortran-start-block-re for the problems of IF. |
| 909 | "if[ \t]*(\\(.*\\|" | 941 | "if[ \t]*(\\(.*\\|" |
| 910 | ".*\n\\([^if]*\\([^i].\\|.[^f]\\|.\\>\\)\\)\\)\\<then\\|" | 942 | ".*\n\\([^if]*\\([^i].\\|.[^f]\\|.\\_>\\)\\)\\)\\_<then\\|" |
| 911 | ;; Distinguish WHERE block from isolated WHERE. | 943 | ;; Distinguish WHERE block from isolated WHERE. |
| 912 | "\\(where\\|forall\\)[ \t]*(.*)[ \t]*\\(!\\|$\\)\\)\\)" | 944 | "\\(where\\|forall\\)[ \t]*(.*)[ \t]*\\(!\\|$\\)\\)\\)" |
| 913 | "\\|" | 945 | "\\|" |
| @@ -917,7 +949,7 @@ Used in the F90 entry in `hs-special-modes-alist'.") | |||
| 917 | "type[ \t,]\\(" | 949 | "type[ \t,]\\(" |
| 918 | "[^i(!\n\"\& \t]\\|" ; not-i( | 950 | "[^i(!\n\"\& \t]\\|" ; not-i( |
| 919 | "i[^s!\n\"\& \t]\\|" ; i not-s | 951 | "i[^s!\n\"\& \t]\\|" ; i not-s |
| 920 | "is\\sw\\)\\|" | 952 | "is\\(?:\\sw\\|\\s_\\)\\)\\|" |
| 921 | ;; "abstract interface" is F2003; "submodule" is F2008. | 953 | ;; "abstract interface" is F2003; "submodule" is F2008. |
| 922 | "program\\|\\(?:abstract[ \t]*\\)?interface\\|\\(?:sub\\)?module\\|" | 954 | "program\\|\\(?:abstract[ \t]*\\)?interface\\|\\(?:sub\\)?module\\|" |
| 923 | ;; "enum", but not "enumerator". | 955 | ;; "enum", but not "enumerator". |
| @@ -945,10 +977,10 @@ Set subexpression 1 in the match-data to the name of the type." | |||
| 945 | (not (setq found | 977 | (not (setq found |
| 946 | (save-excursion | 978 | (save-excursion |
| 947 | (goto-char (match-end 0)) | 979 | (goto-char (match-end 0)) |
| 948 | (unless (looking-at "\\(is\\>\\|(\\)") | 980 | (unless (looking-at "\\(is\\_>\\|(\\)") |
| 949 | (or (looking-at "\\(\\sw+\\)") | 981 | (or (looking-at "\\(\\(?:\\sw\\|\\s_\\)+\\)") |
| 950 | (re-search-forward | 982 | (re-search-forward |
| 951 | "[ \t]*::[ \t]*\\(\\sw+\\)" | 983 | "[ \t]*::[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)" |
| 952 | (line-end-position) t)))))))) | 984 | (line-end-position) t)))))))) |
| 953 | found)) | 985 | found)) |
| 954 | 986 | ||
| @@ -957,36 +989,35 @@ Set subexpression 1 in the match-data to the name of the type." | |||
| 957 | (not-n "[^n!\n\"\& \t]") (not-d "[^d!\n\"\& \t]") | 989 | (not-n "[^n!\n\"\& \t]") (not-d "[^d!\n\"\& \t]") |
| 958 | ;; (not-ib "[^i(!\n\"\& \t]") (not-s "[^s!\n\"\& \t]") | 990 | ;; (not-ib "[^i(!\n\"\& \t]") (not-s "[^s!\n\"\& \t]") |
| 959 | ) | 991 | ) |
| 960 | (list | 992 | `((nil "^[ \t0-9]*program[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)" 1) |
| 961 | '(nil "^[ \t0-9]*program[ \t]+\\(\\sw+\\)" 1) | 993 | ("Submodules" "^[ \t0-9]*submodule[ \t]*([^)\n]+)[ \t]*\ |
| 962 | '("Submodules" "^[ \t0-9]*submodule[ \t]*([^)\n]+)[ \t]*\ | 994 | \\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*\\(!\\|$\\)" 1) |
| 963 | \\(\\sw+\\)[ \t]*\\(!\\|$\\)" 1) | 995 | ("Modules" "^[ \t0-9]*module[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*\\(!\\|$\\)" 1) |
| 964 | '("Modules" "^[ \t0-9]*module[ \t]+\\(\\sw+\\)[ \t]*\\(!\\|$\\)" 1) | 996 | ("Types" f90-imenu-type-matcher 1) |
| 965 | (list "Types" 'f90-imenu-type-matcher 1) | 997 | ;; Does not handle: "type[, stuff] :: foo". |
| 966 | ;; Does not handle: "type[, stuff] :: foo". | 998 | ;;(format "^[ \t0-9]*type[ \t]+\\(\\(%s\\|i%s\\|is\\(?:\\sw\\|\\s_\\)\\)\\(?:\\sw\\|\\s_\\)*\\)" |
| 967 | ;;; (format "^[ \t0-9]*type[ \t]+\\(\\(%s\\|i%s\\|is\\sw\\)\\sw*\\)" | 999 | ;; not-ib not-s) |
| 968 | ;;; not-ib not-s) | 1000 | ;;1) |
| 969 | ;;; 1) | 1001 | ;; Can't get the subexpression numbers to match in the two branches. |
| 970 | ;; Can't get the subexpression numbers to match in the two branches. | 1002 | ;; FIXME: Now with \(?N:..\) we can get the numbers to match! |
| 971 | ;;; (format "^[ \t0-9]*type\\([ \t]*,.*\\(::\\)[ \t]*\\(\\sw+\\)\\|[ \t]+\\(\\(%s\\|i%s\\|is\\sw\\)\\sw*\\)\\)" not-ib not-s) | 1003 | ;;(format "^[ \t0-9]*type\\([ \t]*,.*\\(::\\)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\|[ \t]+\\(\\(%s\\|i%s\\|is\\(?:\\sw\\|\\s_\\)\\)\\(?:\\sw\\|\\s_\\)*\\)\\)" not-ib not-s) |
| 972 | ;;; 3) | 1004 | ;;3) |
| 973 | (list | 1005 | ("Procedures" |
| 974 | "Procedures" | 1006 | ,(concat |
| 975 | (concat | 1007 | "^[ \t0-9]*" |
| 976 | "^[ \t0-9]*" | 1008 | "\\(" |
| 977 | "\\(" | 1009 | ;; At least three non-space characters before function/subroutine. |
| 978 | ;; At least three non-space characters before function/subroutine. | 1010 | ;; Check that the last three non-space characters do not spell E N D. |
| 979 | ;; Check that the last three non-space characters do not spell E N D. | 1011 | "[^!\"\&\n]*\\(" |
| 980 | "[^!\"\&\n]*\\(" | 1012 | not-e good-char good-char "\\|" |
| 981 | not-e good-char good-char "\\|" | 1013 | good-char not-n good-char "\\|" |
| 982 | good-char not-n good-char "\\|" | 1014 | good-char good-char not-d "\\)" |
| 983 | good-char good-char not-d "\\)" | 1015 | "\\|" |
| 984 | "\\|" | 1016 | ;; Less than three non-space characters before function/subroutine. |
| 985 | ;; Less than three non-space characters before function/subroutine. | 1017 | good-char "?" good-char "?" |
| 986 | good-char "?" good-char "?" | 1018 | "\\)" |
| 987 | "\\)" | 1019 | "[ \t]*\\(function\\|subroutine\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)") |
| 988 | "[ \t]*\\(function\\|subroutine\\)[ \t]+\\(\\sw+\\)") | 1020 | 4))) |
| 989 | 4))) | ||
| 990 | "Value for `imenu-generic-expression' in F90 mode.") | 1021 | "Value for `imenu-generic-expression' in F90 mode.") |
| 991 | 1022 | ||
| 992 | (defun f90-add-imenu-menu () | 1023 | (defun f90-add-imenu-menu () |
| @@ -1119,11 +1150,11 @@ Variables controlling indentation style and extra features: | |||
| 1119 | Automatic insertion of \& at beginning of continuation lines (default t). | 1150 | Automatic insertion of \& at beginning of continuation lines (default t). |
| 1120 | `f90-smart-end' | 1151 | `f90-smart-end' |
| 1121 | From an END statement, check and fill the end using matching block start. | 1152 | From an END statement, check and fill the end using matching block start. |
| 1122 | Allowed values are 'blink, 'no-blink, and nil, which determine | 1153 | Allowed values are `blink', `no-blink', and nil, which determine |
| 1123 | whether to blink the matching beginning (default 'blink). | 1154 | whether to blink the matching beginning (default `blink'). |
| 1124 | `f90-auto-keyword-case' | 1155 | `f90-auto-keyword-case' |
| 1125 | Automatic change of case of keywords (default nil). | 1156 | Automatic change of case of keywords (default nil). |
| 1126 | The possibilities are 'downcase-word, 'upcase-word, 'capitalize-word. | 1157 | The possibilities are `downcase-word', `upcase-word', `capitalize-word'. |
| 1127 | `f90-leave-line-no' | 1158 | `f90-leave-line-no' |
| 1128 | Do not left-justify line numbers (default nil). | 1159 | Do not left-justify line numbers (default nil). |
| 1129 | 1160 | ||
| @@ -1235,13 +1266,13 @@ whitespace, if any." | |||
| 1235 | (defsubst f90-looking-at-do () | 1266 | (defsubst f90-looking-at-do () |
| 1236 | "Return (\"do\" NAME) if a do statement starts after point. | 1267 | "Return (\"do\" NAME) if a do statement starts after point. |
| 1237 | NAME is nil if the statement has no label." | 1268 | NAME is nil if the statement has no label." |
| 1238 | (if (looking-at "\\(\\(\\sw+\\)[ \t]*:\\)?[ \t]*\\(do\\)\\>") | 1269 | (if (looking-at "\\(\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:\\)?[ \t]*\\(do\\)\\_>") |
| 1239 | (list (match-string 3) (match-string 2)))) | 1270 | (list (match-string 3) (match-string 2)))) |
| 1240 | 1271 | ||
| 1241 | (defsubst f90-looking-at-select-case () | 1272 | (defsubst f90-looking-at-select-case () |
| 1242 | "Return (\"select\" NAME) if a select statement starts after point. | 1273 | "Return (\"select\" NAME) if a select statement starts after point. |
| 1243 | NAME is nil if the statement has no label." | 1274 | NAME is nil if the statement has no label." |
| 1244 | (if (looking-at "\\(\\(\\sw+\\)[ \t]*:\\)?[ \t]*\ | 1275 | (if (looking-at "\\(\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:\\)?[ \t]*\ |
| 1245 | \\(select\\)[ \t]*\\(case\\|type\\)[ \t]*(") | 1276 | \\(select\\)[ \t]*\\(case\\|type\\)[ \t]*(") |
| 1246 | (list (match-string 3) (match-string 2)))) | 1277 | (list (match-string 3) (match-string 2)))) |
| 1247 | 1278 | ||
| @@ -1249,50 +1280,50 @@ NAME is nil if the statement has no label." | |||
| 1249 | "Return (\"if\" NAME) if an if () then statement starts after point. | 1280 | "Return (\"if\" NAME) if an if () then statement starts after point. |
| 1250 | NAME is nil if the statement has no label." | 1281 | NAME is nil if the statement has no label." |
| 1251 | (save-excursion | 1282 | (save-excursion |
| 1252 | (when (looking-at "\\(\\(\\sw+\\)[ \t]*:\\)?[ \t]*\\(if\\)\\>") | 1283 | (when (looking-at "\\(\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:\\)?[ \t]*\\(if\\)\\_>") |
| 1253 | (let ((struct (match-string 3)) | 1284 | (let ((struct (match-string 3)) |
| 1254 | (label (match-string 2)) | 1285 | (label (match-string 2)) |
| 1255 | (pos (scan-lists (point) 1 0))) | 1286 | (pos (scan-lists (point) 1 0))) |
| 1256 | (and pos (goto-char pos)) | 1287 | (and pos (goto-char pos)) |
| 1257 | (skip-chars-forward " \t") | 1288 | (skip-chars-forward " \t") |
| 1258 | (if (or (looking-at "then\\>") | 1289 | (if (or (looking-at "then\\_>") |
| 1259 | (when (f90-line-continued) | 1290 | (when (f90-line-continued) |
| 1260 | (f90-next-statement) | 1291 | (f90-next-statement) |
| 1261 | (skip-chars-forward " \t0-9&") | 1292 | (skip-chars-forward " \t0-9&") |
| 1262 | (looking-at "then\\>"))) | 1293 | (looking-at "then\\_>"))) |
| 1263 | (list struct label)))))) | 1294 | (list struct label)))))) |
| 1264 | 1295 | ||
| 1265 | ;; FIXME label? | 1296 | ;; FIXME label? |
| 1266 | (defsubst f90-looking-at-associate () | 1297 | (defsubst f90-looking-at-associate () |
| 1267 | "Return (\"associate\") if an associate block starts after point." | 1298 | "Return (\"associate\") if an associate block starts after point." |
| 1268 | (if (looking-at "\\<\\(associate\\)[ \t]*(") | 1299 | (if (looking-at "\\_<\\(associate\\)[ \t]*(") |
| 1269 | (list (match-string 1)))) | 1300 | (list (match-string 1)))) |
| 1270 | 1301 | ||
| 1271 | (defsubst f90-looking-at-critical () | 1302 | (defsubst f90-looking-at-critical () |
| 1272 | "Return (KIND NAME) if a critical or block block starts after point." | 1303 | "Return (KIND NAME) if a critical or block block starts after point." |
| 1273 | (if (looking-at "\\(\\(\\sw+\\)[ \t]*:\\)?[ \t]*\\(critical\\|block\\)\\>") | 1304 | (if (looking-at "\\(\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:\\)?[ \t]*\\(critical\\|block\\)\\_>") |
| 1274 | (let ((struct (match-string 3)) | 1305 | (let ((struct (match-string 3)) |
| 1275 | (label (match-string 2))) | 1306 | (label (match-string 2))) |
| 1276 | (if (or (not (string-equal "block" struct)) | 1307 | (if (or (not (string-equal "block" struct)) |
| 1277 | (save-excursion | 1308 | (save-excursion |
| 1278 | (skip-chars-forward " \t") | 1309 | (skip-chars-forward " \t") |
| 1279 | (not (looking-at "data\\>")))) | 1310 | (not (looking-at "data\\_>")))) |
| 1280 | (list struct label))))) | 1311 | (list struct label))))) |
| 1281 | 1312 | ||
| 1282 | (defsubst f90-looking-at-end-critical () | 1313 | (defsubst f90-looking-at-end-critical () |
| 1283 | "Return non-nil if a critical or block block ends after point." | 1314 | "Return non-nil if a critical or block block ends after point." |
| 1284 | (if (looking-at "end[ \t]*\\(critical\\|block\\)\\>") | 1315 | (if (looking-at "end[ \t]*\\(critical\\|block\\)\\_>") |
| 1285 | (or (not (string-equal "block" (match-string 1))) | 1316 | (or (not (string-equal "block" (match-string 1))) |
| 1286 | (save-excursion | 1317 | (save-excursion |
| 1287 | (skip-chars-forward " \t") | 1318 | (skip-chars-forward " \t") |
| 1288 | (not (looking-at "data\\>")))))) | 1319 | (not (looking-at "data\\_>")))))) |
| 1289 | 1320 | ||
| 1290 | (defsubst f90-looking-at-where-or-forall () | 1321 | (defsubst f90-looking-at-where-or-forall () |
| 1291 | "Return (KIND NAME) if a where or forall block starts after point. | 1322 | "Return (KIND NAME) if a where or forall block starts after point. |
| 1292 | NAME is nil if the statement has no label." | 1323 | NAME is nil if the statement has no label." |
| 1293 | (save-excursion | 1324 | (save-excursion |
| 1294 | (when (looking-at "\\(\\(\\sw+\\)[ \t]*:\\)?[ \t]*\ | 1325 | (when (looking-at "\\(\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:\\)?[ \t]*\ |
| 1295 | \\(where\\|forall\\)\\>") | 1326 | \\(where\\|forall\\)\\_>") |
| 1296 | (let ((struct (match-string 3)) | 1327 | (let ((struct (match-string 3)) |
| 1297 | (label (match-string 2)) | 1328 | (label (match-string 2)) |
| 1298 | (pos (scan-lists (point) 1 0))) | 1329 | (pos (scan-lists (point) 1 0))) |
| @@ -1305,43 +1336,43 @@ NAME is nil if the statement has no label." | |||
| 1305 | NAME is non-nil only for type and certain interfaces." | 1336 | NAME is non-nil only for type and certain interfaces." |
| 1306 | (cond | 1337 | (cond |
| 1307 | ((save-excursion | 1338 | ((save-excursion |
| 1308 | (and (looking-at "\\<type\\>[ \t]*") | 1339 | (and (looking-at "\\_<type\\_>[ \t]*") |
| 1309 | (goto-char (match-end 0)) | 1340 | (goto-char (match-end 0)) |
| 1310 | (not (looking-at "\\(is\\>\\|(\\)")) | 1341 | (not (looking-at "\\(is\\_>\\|(\\)")) |
| 1311 | (or (looking-at "\\(\\sw+\\)") | 1342 | (or (looking-at "\\(\\(?:\\sw\\|\\s_\\)+\\)") |
| 1312 | (re-search-forward "[ \t]*::[ \t]*\\(\\sw+\\)" | 1343 | (re-search-forward "[ \t]*::[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)" |
| 1313 | (line-end-position) t)))) | 1344 | (line-end-position) t)))) |
| 1314 | (list "type" (match-string 1))) | 1345 | (list "type" (match-string 1))) |
| 1315 | ;;; ((and (not (looking-at f90-typeis-re)) | 1346 | ;;; ((and (not (looking-at f90-typeis-re)) |
| 1316 | ;;; (looking-at f90-type-def-re)) | 1347 | ;;; (looking-at f90-type-def-re)) |
| 1317 | ;;; (list (match-string 1) (match-string 2))) | 1348 | ;;; (list (match-string 1) (match-string 2))) |
| 1318 | ((looking-at "\\<\\(interface\\)\\>[ \t]*") | 1349 | ((looking-at "\\_<\\(interface\\)\\_>[ \t]*") |
| 1319 | (list (match-string 1) | 1350 | (list (match-string 1) |
| 1320 | (save-excursion | 1351 | (save-excursion |
| 1321 | (goto-char (match-end 0)) | 1352 | (goto-char (match-end 0)) |
| 1322 | (if (or (looking-at "\\(operator\\|assignment\\|read\\|\ | 1353 | (if (or (looking-at "\\(operator\\|assignment\\|read\\|\ |
| 1323 | write\\)[ \t]*([^)\n]*)") | 1354 | write\\)[ \t]*([^)\n]*)") |
| 1324 | (looking-at "\\sw+")) | 1355 | (looking-at "\\(?:\\sw\\|\\s_\\)+")) |
| 1325 | (match-string 0))))) | 1356 | (match-string 0))))) |
| 1326 | ((looking-at "\\(enum\\|block[ \t]*data\\)\\>") | 1357 | ((looking-at "\\(enum\\|block[ \t]*data\\)\\_>") |
| 1327 | (list (match-string 1) nil)) | 1358 | (list (match-string 1) nil)) |
| 1328 | ((looking-at "abstract[ \t]*\\(interface\\)\\>") | 1359 | ((looking-at "abstract[ \t]*\\(interface\\)\\_>") |
| 1329 | (list (match-string 1) nil)))) | 1360 | (list (match-string 1) nil)))) |
| 1330 | 1361 | ||
| 1331 | (defsubst f90-looking-at-program-block-start () | 1362 | (defsubst f90-looking-at-program-block-start () |
| 1332 | "Return (KIND NAME) if a program block with name NAME starts after point." | 1363 | "Return (KIND NAME) if a program block with name NAME starts after point." |
| 1333 | ;;;NAME is nil for an un-named main PROGRAM block." | 1364 | ;;;NAME is nil for an un-named main PROGRAM block." |
| 1334 | (cond | 1365 | (cond |
| 1335 | ((looking-at "\\(program\\)[ \t]+\\(\\sw+\\)\\>") | 1366 | ((looking-at "\\(program\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>") |
| 1336 | (list (match-string 1) (match-string 2))) | 1367 | (list (match-string 1) (match-string 2))) |
| 1337 | ((and (not (looking-at "module[ \t]*procedure\\>")) | 1368 | ((and (not (looking-at "module[ \t]*procedure\\_>")) |
| 1338 | (looking-at "\\(module\\)[ \t]+\\(\\sw+\\)\\>")) | 1369 | (looking-at "\\(module\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")) |
| 1339 | (list (match-string 1) (match-string 2))) | 1370 | (list (match-string 1) (match-string 2))) |
| 1340 | ((looking-at "\\(submodule\\)[ \t]*([^)\n]+)[ \t]*\\(\\sw+\\)\\>") | 1371 | ((looking-at "\\(submodule\\)[ \t]*([^)\n]+)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>") |
| 1341 | (list (match-string 1) (match-string 2))) | 1372 | (list (match-string 1) (match-string 2))) |
| 1342 | ((and (not (looking-at "end[ \t]*\\(function\\|subroutine\\)")) | 1373 | ((and (not (looking-at "end[ \t]*\\(function\\|subroutine\\)")) |
| 1343 | (looking-at "[^!'\"\&\n]*\\(function\\|subroutine\\)[ \t]+\ | 1374 | (looking-at "[^!'\"\&\n]*\\(function\\|subroutine\\)[ \t]+\ |
| 1344 | \\(\\sw+\\)")) | 1375 | \\(\\(?:\\sw\\|\\s_\\)+\\)")) |
| 1345 | (list (match-string 1) (match-string 2))))) | 1376 | (list (match-string 1) (match-string 2))))) |
| 1346 | ;; Following will match an un-named main program block; however | 1377 | ;; Following will match an un-named main program block; however |
| 1347 | ;; one needs to check if there is an actual PROGRAM statement after | 1378 | ;; one needs to check if there is an actual PROGRAM statement after |
| @@ -1357,7 +1388,7 @@ write\\)[ \t]*([^)\n]*)") | |||
| 1357 | \\(?:assignment\\|operator\\|read\\|write\\)[ \t]*([^)\n]*)\\)") | 1388 | \\(?:assignment\\|operator\\|read\\|write\\)[ \t]*([^)\n]*)\\)") |
| 1358 | (list (match-string 1) (match-string 2))) | 1389 | (list (match-string 1) (match-string 2))) |
| 1359 | ((looking-at (concat "end[ \t]*" f90-blocks-re | 1390 | ((looking-at (concat "end[ \t]*" f90-blocks-re |
| 1360 | "?\\([ \t]+\\(\\sw+\\)\\)?\\>")) | 1391 | "?\\([ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\)?\\_>")) |
| 1361 | (list (match-string 1) (match-string 3))))) | 1392 | (list (match-string 1) (match-string 3))))) |
| 1362 | 1393 | ||
| 1363 | (defsubst f90-comment-indent () | 1394 | (defsubst f90-comment-indent () |
| @@ -1414,10 +1445,10 @@ if all else fails." | |||
| 1414 | (not (or (looking-at "end") | 1445 | (not (or (looking-at "end") |
| 1415 | (looking-at "\\(do\\|if\\|else\\(if\\|where\\)?\ | 1446 | (looking-at "\\(do\\|if\\|else\\(if\\|where\\)?\ |
| 1416 | \\|select[ \t]*\\(case\\|type\\)\\|case\\|where\\|forall\\|\ | 1447 | \\|select[ \t]*\\(case\\|type\\)\\|case\\|where\\|forall\\|\ |
| 1417 | block\\|critical\\)\\>") | 1448 | block\\|critical\\)\\_>") |
| 1418 | (looking-at "\\(program\\|\\(?:sub\\)?module\\|\ | 1449 | (looking-at "\\(program\\|\\(?:sub\\)?module\\|\ |
| 1419 | \\(?:abstract[ \t]*\\)?interface\\|block[ \t]*data\\)\\>") | 1450 | \\(?:abstract[ \t]*\\)?interface\\|block[ \t]*data\\)\\_>") |
| 1420 | (looking-at "\\(contains\\|\\sw+[ \t]*:\\)") | 1451 | (looking-at "\\(contains\\|\\(?:\\sw\\|\\s_\\)+[ \t]*:\\)") |
| 1421 | (looking-at f90-type-def-re) | 1452 | (looking-at f90-type-def-re) |
| 1422 | (re-search-forward "\\(function\\|subroutine\\)" | 1453 | (re-search-forward "\\(function\\|subroutine\\)" |
| 1423 | (line-end-position) t))))) | 1454 | (line-end-position) t))))) |
| @@ -1483,7 +1514,7 @@ Does not check type and subprogram indentation." | |||
| 1483 | (setq icol (- icol f90-associate-indent))) | 1514 | (setq icol (- icol f90-associate-indent))) |
| 1484 | ((f90-looking-at-end-critical) | 1515 | ((f90-looking-at-end-critical) |
| 1485 | (setq icol (- icol f90-critical-indent))) | 1516 | (setq icol (- icol f90-critical-indent))) |
| 1486 | ((looking-at "end[ \t]*do\\>") | 1517 | ((looking-at "end[ \t]*do\\_>") |
| 1487 | (setq icol (- icol f90-do-indent)))) | 1518 | (setq icol (- icol f90-do-indent)))) |
| 1488 | (end-of-line)) | 1519 | (end-of-line)) |
| 1489 | icol))) | 1520 | icol))) |
| @@ -1550,7 +1581,7 @@ Does not check type and subprogram indentation." | |||
| 1550 | (cond ((or (looking-at f90-else-like-re) | 1581 | (cond ((or (looking-at f90-else-like-re) |
| 1551 | (looking-at f90-end-if-re)) | 1582 | (looking-at f90-end-if-re)) |
| 1552 | (setq icol (- icol f90-if-indent))) | 1583 | (setq icol (- icol f90-if-indent))) |
| 1553 | ((looking-at "end[ \t]*do\\>") | 1584 | ((looking-at "end[ \t]*do\\_>") |
| 1554 | (setq icol (- icol f90-do-indent))) | 1585 | (setq icol (- icol f90-do-indent))) |
| 1555 | ((looking-at f90-end-type-re) | 1586 | ((looking-at f90-end-type-re) |
| 1556 | (setq icol (- icol f90-type-indent))) | 1587 | (setq icol (- icol f90-type-indent))) |
| @@ -1671,7 +1702,7 @@ Interactively, pushes mark before moving point." | |||
| 1671 | (setq start-list (cons start-this start-list) ; not add-to-list! | 1702 | (setq start-list (cons start-this start-list) ; not add-to-list! |
| 1672 | count (1+ count))) | 1703 | count (1+ count))) |
| 1673 | ((looking-at (concat "end[ \t]*" f90-blocks-re | 1704 | ((looking-at (concat "end[ \t]*" f90-blocks-re |
| 1674 | "[ \t]*\\(\\sw+\\)?")) | 1705 | "[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?")) |
| 1675 | (setq end-type (match-string 1) | 1706 | (setq end-type (match-string 1) |
| 1676 | end-label (match-string 2) | 1707 | end-label (match-string 2) |
| 1677 | count (1- count)) | 1708 | count (1- count)) |
| @@ -1716,7 +1747,7 @@ Interactively, pushes mark before moving point." | |||
| 1716 | (skip-chars-forward " \t0-9") | 1747 | (skip-chars-forward " \t0-9") |
| 1717 | (cond ((or (f90-in-string) (f90-in-comment))) | 1748 | (cond ((or (f90-in-string) (f90-in-comment))) |
| 1718 | ((looking-at (concat "end[ \t]*" f90-blocks-re | 1749 | ((looking-at (concat "end[ \t]*" f90-blocks-re |
| 1719 | "[ \t]*\\(\\sw+\\)?")) | 1750 | "[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?")) |
| 1720 | (setq end-list (cons (list (match-string 1) (match-string 2)) | 1751 | (setq end-list (cons (list (match-string 1) (match-string 2)) |
| 1721 | end-list) | 1752 | end-list) |
| 1722 | count (1+ count))) | 1753 | count (1+ count))) |
| @@ -1962,7 +1993,7 @@ If run in the middle of a line, the line is not broken." | |||
| 1962 | (car end-struct) (cadr end-struct)))) | 1993 | (car end-struct) (cadr end-struct)))) |
| 1963 | (setq ind-b | 1994 | (setq ind-b |
| 1964 | (cond ((looking-at f90-end-if-re) f90-if-indent) | 1995 | (cond ((looking-at f90-end-if-re) f90-if-indent) |
| 1965 | ((looking-at "end[ \t]*do\\>") f90-do-indent) | 1996 | ((looking-at "end[ \t]*do\\_>") f90-do-indent) |
| 1966 | ((looking-at f90-end-type-re) f90-type-indent) | 1997 | ((looking-at f90-end-type-re) f90-type-indent) |
| 1967 | ((looking-at f90-end-associate-re) | 1998 | ((looking-at f90-end-associate-re) |
| 1968 | f90-associate-indent) | 1999 | f90-associate-indent) |
| @@ -2108,12 +2139,19 @@ Like `join-line', but handles F90 syntax." | |||
| 2108 | (zmacs-deactivate-region) | 2139 | (zmacs-deactivate-region) |
| 2109 | (deactivate-mark)))) | 2140 | (deactivate-mark)))) |
| 2110 | 2141 | ||
| 2142 | (defconst f90-end-block-optional-name | ||
| 2143 | '("program" "module" "subroutine" "function" "type") | ||
| 2144 | "Block types where including the name in the end statement is optional.") | ||
| 2145 | |||
| 2111 | (defun f90-block-match (beg-block beg-name end-block end-name) | 2146 | (defun f90-block-match (beg-block beg-name end-block end-name) |
| 2112 | "Match end-struct with beg-struct and complete end-block if possible. | 2147 | "Match end-struct with beg-struct and complete end-block if possible. |
| 2113 | BEG-BLOCK is the type of block as indicated at the start (e.g., do). | 2148 | BEG-BLOCK is the type of block as indicated at the start (e.g., do). |
| 2114 | BEG-NAME is the block start name (may be nil). | 2149 | BEG-NAME is the block start name (may be nil). |
| 2115 | END-BLOCK is the type of block as indicated at the end (may be nil). | 2150 | END-BLOCK is the type of block as indicated at the end (may be nil). |
| 2116 | END-NAME is the block end name (may be nil). | 2151 | END-NAME is the block end name (may be nil). |
| 2152 | If the block type matches `f90-end-block-optional-name', do not add | ||
| 2153 | an end name if `f90-smart-end-names' is nil, but always update an | ||
| 2154 | incorrect end name if there already was one. | ||
| 2117 | Leave point at the end of line." | 2155 | Leave point at the end of line." |
| 2118 | ;; Hack to deal with the case when this is called from | 2156 | ;; Hack to deal with the case when this is called from |
| 2119 | ;; f90-indent-region on a program block without an explicit PROGRAM | 2157 | ;; f90-indent-region on a program block without an explicit PROGRAM |
| @@ -2133,8 +2171,11 @@ Leave point at the end of line." | |||
| 2133 | (if (f90-equal-symbols beg-name end-name) | 2171 | (if (f90-equal-symbols beg-name end-name) |
| 2134 | (and end-name (search-forward end-name)) | 2172 | (and end-name (search-forward end-name)) |
| 2135 | (cond ((and beg-name (not end-name)) | 2173 | (cond ((and beg-name (not end-name)) |
| 2136 | (message "Inserting %s." beg-name) | 2174 | (unless (and (not f90-smart-end-names) |
| 2137 | (insert (concat " " beg-name))) | 2175 | (member-ignore-case beg-block |
| 2176 | f90-end-block-optional-name)) | ||
| 2177 | (message "Inserting %s." beg-name) | ||
| 2178 | (insert (concat " " beg-name)))) | ||
| 2138 | ((and beg-name end-name) | 2179 | ((and beg-name end-name) |
| 2139 | (message "Replacing %s with %s." end-name beg-name) | 2180 | (message "Replacing %s with %s." end-name beg-name) |
| 2140 | (search-forward end-name) | 2181 | (search-forward end-name) |
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 0f92df95a9d..99b48e8d0db 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; flymake.el -- a universal on-the-fly syntax checker | 1 | ;;; flymake.el --- a universal on-the-fly syntax checker |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2003-2013 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2003-2013 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -68,6 +68,9 @@ | |||
| 68 | 68 | ||
| 69 | ;;;; [[ cross-emacs compatibility routines | 69 | ;;;; [[ cross-emacs compatibility routines |
| 70 | (defsubst flymake-makehash (&optional test) | 70 | (defsubst flymake-makehash (&optional test) |
| 71 | "Create and return a new hash table using TEST to compare keys. | ||
| 72 | It uses the function `make-hash-table' to make a hash-table if | ||
| 73 | you use GNU Emacs, otherwise it uses `makehash'." | ||
| 71 | (if (fboundp 'make-hash-table) | 74 | (if (fboundp 'make-hash-table) |
| 72 | (if test (make-hash-table :test test) (make-hash-table)) | 75 | (if test (make-hash-table :test test) (make-hash-table)) |
| 73 | (with-no-warnings | 76 | (with-no-warnings |
| @@ -106,10 +109,12 @@ Zero-length substrings at the beginning and end of the list are omitted." | |||
| 106 | (lambda () temporary-file-directory))) | 109 | (lambda () temporary-file-directory))) |
| 107 | 110 | ||
| 108 | (defun flymake-posn-at-point-as-event (&optional position window dx dy) | 111 | (defun flymake-posn-at-point-as-event (&optional position window dx dy) |
| 109 | "Return pixel position of top left corner of glyph at POSITION, | 112 | "Return pixel position of top left corner of glyph at POSITION. |
| 110 | relative to top left corner of WINDOW, as a mouse-1 click | 113 | |
| 111 | event (identical to the event that would be triggered by clicking | 114 | The position is relative to top left corner of WINDOW, as a |
| 112 | mouse button 1 at the top left corner of the glyph). | 115 | mouse-1 click event (identical to the event that would be |
| 116 | triggered by clicking mouse button 1 at the top left corner of | ||
| 117 | the glyph). | ||
| 113 | 118 | ||
| 114 | POSITION and WINDOW default to the position of point in the | 119 | POSITION and WINDOW default to the position of point in the |
| 115 | selected window. | 120 | selected window. |
| @@ -164,7 +169,9 @@ See `x-popup-menu' for the menu specifier format." | |||
| 164 | 169 | ||
| 165 | (if (featurep 'xemacs) (progn | 170 | (if (featurep 'xemacs) (progn |
| 166 | 171 | ||
| 167 | (defun flymake-nop ()) | 172 | (defun flymake-nop () |
| 173 | "Do nothing." | ||
| 174 | nil) | ||
| 168 | 175 | ||
| 169 | (defun flymake-make-xemacs-menu (menu-data) | 176 | (defun flymake-make-xemacs-menu (menu-data) |
| 170 | "Return a menu specifier using MENU-DATA." | 177 | "Return a menu specifier using MENU-DATA." |
| @@ -187,6 +194,7 @@ See `x-popup-menu' for the menu specifier format." | |||
| 187 | (count-lines (window-start) (point)))) | 194 | (count-lines (window-start) (point)))) |
| 188 | 195 | ||
| 189 | (defun flymake-selected-frame () | 196 | (defun flymake-selected-frame () |
| 197 | "Return the frame that is now selected." | ||
| 190 | (if (fboundp 'window-edges) | 198 | (if (fboundp 'window-edges) |
| 191 | (selected-frame) | 199 | (selected-frame) |
| 192 | (selected-window))) | 200 | (selected-window))) |
| @@ -217,31 +225,41 @@ See `x-popup-menu' for the menu specifier format." | |||
| 217 | :group 'flymake | 225 | :group 'flymake |
| 218 | :type 'integer) | 226 | :type 'integer) |
| 219 | 227 | ||
| 228 | |||
| 229 | ;; (defcustom flymake-log-file-name "~/flymake.log" | ||
| 230 | ;; "Where to put the flymake log if logging is enabled. | ||
| 231 | ;; | ||
| 232 | ;; See `flymake-log-level' if you want to control what is logged." | ||
| 233 | ;; :group 'flymake | ||
| 234 | ;; :type 'string) | ||
| 235 | |||
| 220 | (defun flymake-log (level text &rest args) | 236 | (defun flymake-log (level text &rest args) |
| 221 | "Log a message at level LEVEL. | 237 | "Log a message at level LEVEL. |
| 222 | If LEVEL is higher than `flymake-log-level', the message is | 238 | If LEVEL is higher than `flymake-log-level', the message is |
| 223 | ignored. Otherwise, it is printed using `message'. | 239 | ignored. Otherwise, it is printed using `message'. |
| 224 | TEXT is a format control string, and the remaining arguments ARGS | 240 | TEXT is a format control string, and the remaining arguments ARGS |
| 225 | are the string substitutions (see `format')." | 241 | are the string substitutions (see the function `format')." |
| 226 | (if (<= level flymake-log-level) | 242 | (if (<= level flymake-log-level) |
| 227 | (let* ((msg (apply 'format text args))) | 243 | (let* ((msg (apply 'format text args))) |
| 228 | (message "%s" msg) | 244 | (message "%s" msg) |
| 229 | ;;(with-temp-buffer | 245 | ;;(with-temp-buffer |
| 230 | ;; (insert msg) | 246 | ;; (insert msg) |
| 231 | ;; (insert "\n") | 247 | ;; (insert "\n") |
| 232 | ;; (flymake-save-buffer-in-file "d:/flymake.log" t) ; make log file name customizable | 248 | ;; (flymake-save-buffer-in-file "~/flymake.log") ; make log file name customizable |
| 233 | ;;) | 249 | ;;) |
| 234 | ))) | 250 | ))) |
| 235 | 251 | ||
| 236 | (defun flymake-ins-after (list pos val) | 252 | (defun flymake-ins-after (list pos val) |
| 237 | "Insert VAL into LIST after position POS." | 253 | "Insert VAL into LIST after position POS. |
| 238 | (let ((tmp (copy-sequence list))) ; (???) | 254 | POS counts from zero." |
| 255 | (let ((tmp (copy-sequence list))) | ||
| 239 | (setcdr (nthcdr pos tmp) (cons val (nthcdr (1+ pos) tmp))) | 256 | (setcdr (nthcdr pos tmp) (cons val (nthcdr (1+ pos) tmp))) |
| 240 | tmp)) | 257 | tmp)) |
| 241 | 258 | ||
| 242 | (defun flymake-set-at (list pos val) | 259 | (defun flymake-set-at (list pos val) |
| 243 | "Set VAL at position POS in LIST." | 260 | "Set VAL at position POS in LIST. |
| 244 | (let ((tmp (copy-sequence list))) ; (???) | 261 | POS counts from zero." |
| 262 | (let ((tmp (copy-sequence list))) | ||
| 245 | (setcar (nthcdr pos tmp) val) | 263 | (setcar (nthcdr pos tmp) val) |
| 246 | tmp)) | 264 | tmp)) |
| 247 | 265 | ||
| @@ -249,7 +267,6 @@ are the string substitutions (see `format')." | |||
| 249 | "List of currently active flymake processes.") | 267 | "List of currently active flymake processes.") |
| 250 | 268 | ||
| 251 | (defvar flymake-output-residual nil) | 269 | (defvar flymake-output-residual nil) |
| 252 | |||
| 253 | (make-variable-buffer-local 'flymake-output-residual) | 270 | (make-variable-buffer-local 'flymake-output-residual) |
| 254 | 271 | ||
| 255 | (defgroup flymake nil | 272 | (defgroup flymake nil |
| @@ -257,6 +274,13 @@ are the string substitutions (see `format')." | |||
| 257 | :version "23.1" | 274 | :version "23.1" |
| 258 | :group 'tools) | 275 | :group 'tools) |
| 259 | 276 | ||
| 277 | (defcustom flymake-xml-program | ||
| 278 | (if (executable-find "xmlstarlet") "xmlstarlet" "xml") | ||
| 279 | "Program to use for XML validation." | ||
| 280 | :type 'file | ||
| 281 | :group 'flymake | ||
| 282 | :version "24.4") | ||
| 283 | |||
| 260 | (defcustom flymake-allowed-file-name-masks | 284 | (defcustom flymake-allowed-file-name-masks |
| 261 | '(("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'" flymake-simple-make-init) | 285 | '(("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'" flymake-simple-make-init) |
| 262 | ("\\.xml\\'" flymake-xml-init) | 286 | ("\\.xml\\'" flymake-xml-init) |
| @@ -279,16 +303,31 @@ are the string substitutions (see `format')." | |||
| 279 | ;; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 )) | 303 | ;; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 )) |
| 280 | ;; ("\\.tex\\'" 1) | 304 | ;; ("\\.tex\\'" 1) |
| 281 | ) | 305 | ) |
| 282 | "Files syntax checking is allowed for." | 306 | "Files syntax checking is allowed for. |
| 307 | This is an alist with elements of the form: | ||
| 308 | REGEXP INIT [CLEANUP [NAME]] | ||
| 309 | REGEXP is a regular expression that matches a file name. | ||
| 310 | INIT is the init function to use. | ||
| 311 | CLEANUP is the cleanup function to use, default `flymake-simple-cleanup'. | ||
| 312 | NAME is the file name function to use, default `flymake-get-real-file-name'." | ||
| 283 | :group 'flymake | 313 | :group 'flymake |
| 284 | :type '(repeat (string symbol symbol symbol))) | 314 | :type '(alist :key-type (regexp :tag "File regexp") |
| 315 | :value-type | ||
| 316 | (list :tag "Handler functions" | ||
| 317 | (function :tag "Init function") | ||
| 318 | (choice :tag "Cleanup function" | ||
| 319 | (const :tag "flymake-simple-cleanup" nil) | ||
| 320 | function) | ||
| 321 | (choice :tag "Name function" | ||
| 322 | (const :tag "flymake-get-real-file-name" nil) | ||
| 323 | function)))) | ||
| 285 | 324 | ||
| 286 | (defun flymake-get-file-name-mode-and-masks (file-name) | 325 | (defun flymake-get-file-name-mode-and-masks (file-name) |
| 287 | "Return the corresponding entry from `flymake-allowed-file-name-masks'." | 326 | "Return the corresponding entry from `flymake-allowed-file-name-masks'." |
| 288 | (unless (stringp file-name) | 327 | (unless (stringp file-name) |
| 289 | (error "Invalid file-name")) | 328 | (error "Invalid file-name")) |
| 290 | (let ((fnm flymake-allowed-file-name-masks) | 329 | (let ((fnm flymake-allowed-file-name-masks) |
| 291 | (mode-and-masks nil)) | 330 | (mode-and-masks nil)) |
| 292 | (while (and (not mode-and-masks) fnm) | 331 | (while (and (not mode-and-masks) fnm) |
| 293 | (if (string-match (car (car fnm)) file-name) | 332 | (if (string-match (car (car fnm)) file-name) |
| 294 | (setq mode-and-masks (cdr (car fnm)))) | 333 | (setq mode-and-masks (cdr (car fnm)))) |
| @@ -314,18 +353,22 @@ Return nil if we cannot, non-nil if we can." | |||
| 314 | 'flymake-simple-cleanup)) | 353 | 'flymake-simple-cleanup)) |
| 315 | 354 | ||
| 316 | (defun flymake-get-real-file-name-function (file-name) | 355 | (defun flymake-get-real-file-name-function (file-name) |
| 317 | (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) | 356 | (or (nth 4 (flymake-get-file-name-mode-and-masks file-name)) |
| 318 | 'flymake-get-real-file-name)) | 357 | 'flymake-get-real-file-name)) |
| 319 | 358 | ||
| 320 | (defvar flymake-find-buildfile-cache (flymake-makehash 'equal)) | 359 | (defvar flymake-find-buildfile-cache (flymake-makehash 'equal)) |
| 321 | 360 | ||
| 322 | (defun flymake-get-buildfile-from-cache (dir-name) | 361 | (defun flymake-get-buildfile-from-cache (dir-name) |
| 362 | "Look up DIR-NAME in cache and return its associated value. | ||
| 363 | If DIR-NAME is not found, return nil." | ||
| 323 | (gethash dir-name flymake-find-buildfile-cache)) | 364 | (gethash dir-name flymake-find-buildfile-cache)) |
| 324 | 365 | ||
| 325 | (defun flymake-add-buildfile-to-cache (dir-name buildfile) | 366 | (defun flymake-add-buildfile-to-cache (dir-name buildfile) |
| 367 | "Associate DIR-NAME with BUILDFILE in the buildfile cache." | ||
| 326 | (puthash dir-name buildfile flymake-find-buildfile-cache)) | 368 | (puthash dir-name buildfile flymake-find-buildfile-cache)) |
| 327 | 369 | ||
| 328 | (defun flymake-clear-buildfile-cache () | 370 | (defun flymake-clear-buildfile-cache () |
| 371 | "Clear the buildfile cache." | ||
| 329 | (clrhash flymake-find-buildfile-cache)) | 372 | (clrhash flymake-find-buildfile-cache)) |
| 330 | 373 | ||
| 331 | (defun flymake-find-buildfile (buildfile-name source-dir-name) | 374 | (defun flymake-find-buildfile (buildfile-name source-dir-name) |
| @@ -372,9 +415,11 @@ Return t if so, nil if not." | |||
| 372 | 415 | ||
| 373 | (defun flymake-find-possible-master-files (file-name master-file-dirs masks) | 416 | (defun flymake-find-possible-master-files (file-name master-file-dirs masks) |
| 374 | "Find (by name and location) all possible master files. | 417 | "Find (by name and location) all possible master files. |
| 375 | Master files include .cpp and .c for .h. Files are searched for | 418 | |
| 376 | starting from the .h directory and max max-level parent dirs. | 419 | Name is specified by FILE-NAME and location is specified by |
| 377 | File contents are not checked." | 420 | MASTER-FILE-DIRS. Master files include .cpp and .c for .h. |
| 421 | Files are searched for starting from the .h directory and max | ||
| 422 | max-level parent dirs. File contents are not checked." | ||
| 378 | (let* ((dirs master-file-dirs) | 423 | (let* ((dirs master-file-dirs) |
| 379 | (files nil) | 424 | (files nil) |
| 380 | (done nil)) | 425 | (done nil)) |
| @@ -571,6 +616,8 @@ Find master file, patch and save it." | |||
| 571 | nil)))) | 616 | nil)))) |
| 572 | 617 | ||
| 573 | (defun flymake-save-buffer-in-file (file-name) | 618 | (defun flymake-save-buffer-in-file (file-name) |
| 619 | "Save the entire buffer contents into file FILE-NAME. | ||
| 620 | Create parent directories as needed." | ||
| 574 | (make-directory (file-name-directory file-name) 1) | 621 | (make-directory (file-name-directory file-name) 1) |
| 575 | (write-region nil nil file-name nil 566) | 622 | (write-region nil nil file-name nil 566) |
| 576 | (flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name)) | 623 | (flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name)) |
| @@ -1837,7 +1884,9 @@ Use CREATE-TEMP-F for creating temp copy." | |||
| 1837 | 1884 | ||
| 1838 | ;;;; xml-specific init-cleanup routines | 1885 | ;;;; xml-specific init-cleanup routines |
| 1839 | (defun flymake-xml-init () | 1886 | (defun flymake-xml-init () |
| 1840 | (list "xml" (list "val" (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)))) | 1887 | (list flymake-xml-program |
| 1888 | (list "val" (flymake-init-create-temp-buffer-copy | ||
| 1889 | 'flymake-create-temp-inplace)))) | ||
| 1841 | 1890 | ||
| 1842 | (provide 'flymake) | 1891 | (provide 'flymake) |
| 1843 | 1892 | ||
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 8ba2822c3a3..0b52302a98d 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el | |||
| @@ -91,7 +91,7 @@ | |||
| 91 | (require 'gud) | 91 | (require 'gud) |
| 92 | (require 'json) | 92 | (require 'json) |
| 93 | (require 'bindat) | 93 | (require 'bindat) |
| 94 | (eval-when-compile (require 'cl-lib)) | 94 | (require 'cl-lib) |
| 95 | 95 | ||
| 96 | (declare-function speedbar-change-initial-expansion-list | 96 | (declare-function speedbar-change-initial-expansion-list |
| 97 | "speedbar" (new-default)) | 97 | "speedbar" (new-default)) |
| @@ -206,8 +206,8 @@ Only used for files that Emacs can't find.") | |||
| 206 | (defvar gdb-last-command nil) | 206 | (defvar gdb-last-command nil) |
| 207 | (defvar gdb-prompt-name nil) | 207 | (defvar gdb-prompt-name nil) |
| 208 | (defvar gdb-token-number 0) | 208 | (defvar gdb-token-number 0) |
| 209 | (defvar gdb-handler-alist '()) | 209 | (defvar gdb-handler-list '() |
| 210 | (defvar gdb-handler-number nil) | 210 | "List of gdb-handler keeping track of all pending GDB commands.") |
| 211 | (defvar gdb-source-file-list nil | 211 | (defvar gdb-source-file-list nil |
| 212 | "List of source files for the current executable.") | 212 | "List of source files for the current executable.") |
| 213 | (defvar gdb-first-done-or-error t) | 213 | (defvar gdb-first-done-or-error t) |
| @@ -242,33 +242,114 @@ Possible values are these symbols: | |||
| 242 | disposition of output generated by commands that | 242 | disposition of output generated by commands that |
| 243 | gdb mode sends to gdb on its own behalf.") | 243 | gdb mode sends to gdb on its own behalf.") |
| 244 | 244 | ||
| 245 | ;; Pending triggers prevent congestion: Emacs won't send two similar | 245 | (defcustom gdb-discard-unordered-replies t |
| 246 | ;; consecutive requests. | 246 | "Non-nil means discard any out-of-order GDB replies. |
| 247 | 247 | This protects against lost GDB replies, assuming that GDB always | |
| 248 | (defvar gdb-pending-triggers '() | 248 | replies in the same order as Emacs sends commands. When receiving a |
| 249 | "A list of trigger functions which have not yet been handled. | 249 | reply with a given token-number, assume any pending messages with a |
| 250 | 250 | lower token-number are out-of-order." | |
| 251 | Elements are either function names or pairs (buffer . function)") | 251 | :type 'boolean |
| 252 | 252 | :group 'gud | |
| 253 | (defmacro gdb-add-pending (item) | 253 | :version "24.4") |
| 254 | `(push ,item gdb-pending-triggers)) | 254 | |
| 255 | (defmacro gdb-pending-p (item) | 255 | (cl-defstruct gdb-handler |
| 256 | `(member ,item gdb-pending-triggers)) | 256 | "Data required to handle the reply of a command sent to GDB." |
| 257 | (defmacro gdb-delete-pending (item) | 257 | ;; Prefix of the command sent to GDB. The GDB reply for this command |
| 258 | `(setq gdb-pending-triggers | 258 | ;; will be prefixed with this same TOKEN-NUMBER |
| 259 | (delete ,item gdb-pending-triggers))) | 259 | (token-number nil :read-only t) |
| 260 | ;; Callback to invoke when the reply is received from GDB | ||
| 261 | (function nil :read-only t) | ||
| 262 | ;; PENDING-TRIGGER is used to prevent congestion: Emacs won't send | ||
| 263 | ;; two requests with the same PENDING-TRIGGER until a reply is received | ||
| 264 | ;; for the first one." | ||
| 265 | (pending-trigger nil)) | ||
| 266 | |||
| 267 | (defun gdb-add-handler (token-number handler-function &optional pending-trigger) | ||
| 268 | "Insert a new GDB command handler in `gdb-handler-list'. | ||
| 269 | Handlers are used to keep track of the commands sent to GDB | ||
| 270 | and to handle the replies received. | ||
| 271 | Upon reception of a reply prefixed with TOKEN-NUMBER, | ||
| 272 | invoke the callback HANDLER-FUNCTION. | ||
| 273 | If PENDING-TRIGGER is specified, no new GDB commands will be | ||
| 274 | sent with this same PENDING-TRIGGER until a reply is received | ||
| 275 | for this handler." | ||
| 276 | |||
| 277 | (push (make-gdb-handler :token-number token-number | ||
| 278 | :function handler-function | ||
| 279 | :pending-trigger pending-trigger) | ||
| 280 | gdb-handler-list)) | ||
| 281 | |||
| 282 | (defun gdb-delete-handler (token-number) | ||
| 283 | "Remove the handler TOKEN-NUMBER from `gdb-handler-list'. | ||
| 284 | Additionally, if `gdb-discard-unordered-replies' is non-nil, | ||
| 285 | discard all handlers having a token number less than TOKEN-NUMBER." | ||
| 286 | (if gdb-discard-unordered-replies | ||
| 287 | |||
| 288 | (setq gdb-handler-list | ||
| 289 | (cl-delete-if | ||
| 290 | (lambda (handler) | ||
| 291 | "Discard any HANDLER with a token number `<=' than TOKEN-NUMBER." | ||
| 292 | (when (< (gdb-handler-token-number handler) token-number) | ||
| 293 | (message (format | ||
| 294 | "WARNING! Discarding GDB handler with token #%d\n" | ||
| 295 | (gdb-handler-token-number handler)))) | ||
| 296 | (<= (gdb-handler-token-number handler) token-number)) | ||
| 297 | gdb-handler-list)) | ||
| 298 | |||
| 299 | (setq gdb-handler-list | ||
| 300 | (cl-delete-if | ||
| 301 | (lambda (handler) | ||
| 302 | "Discard any HANDLER with a token number `eq' to TOKEN-NUMBER." | ||
| 303 | (eq (gdb-handler-token-number handler) token-number)) | ||
| 304 | gdb-handler-list)))) | ||
| 305 | |||
| 306 | (defun gdb-get-handler-function (token-number) | ||
| 307 | "Return the function callback registered with the handler TOKEN-NUMBER." | ||
| 308 | (gdb-handler-function | ||
| 309 | (cl-find-if (lambda (handler) (eq (gdb-handler-token-number handler) | ||
| 310 | token-number)) | ||
| 311 | gdb-handler-list))) | ||
| 312 | |||
| 313 | |||
| 314 | (defun gdb-pending-handler-p (pending-trigger) | ||
| 315 | "Return non-nil if a command handler is pending with trigger PENDING-TRIGGER." | ||
| 316 | (cl-find-if (lambda (handler) (eq (gdb-handler-pending-trigger handler) | ||
| 317 | pending-trigger)) | ||
| 318 | gdb-handler-list)) | ||
| 319 | |||
| 320 | |||
| 321 | (defun gdb-handle-reply (token-number) | ||
| 322 | "Handle the GDB reply TOKEN-NUMBER. | ||
| 323 | This invokes the handler registered with this token number | ||
| 324 | in `gdb-handler-list' and clears all pending handlers invalidated | ||
| 325 | by the reception of this reply." | ||
| 326 | (let ((handler-function (gdb-get-handler-function token-number))) | ||
| 327 | (when handler-function | ||
| 328 | (funcall handler-function) | ||
| 329 | (gdb-delete-handler token-number)))) | ||
| 330 | |||
| 331 | (defun gdb-remove-all-pending-triggers () | ||
| 332 | "Remove all pending triggers from gdb-handler-list. | ||
| 333 | The handlers are left in gdb-handler-list so that replies received | ||
| 334 | from GDB could still be handled. However, removing the pending triggers | ||
| 335 | allows Emacs to send new commands even if replies of previous commands | ||
| 336 | were not yet received." | ||
| 337 | (dolist (handler gdb-handler-list) | ||
| 338 | (setf (gdb-handler-pending-trigger handler) nil))) | ||
| 260 | 339 | ||
| 261 | (defmacro gdb-wait-for-pending (&rest body) | 340 | (defmacro gdb-wait-for-pending (&rest body) |
| 262 | "Wait until `gdb-pending-triggers' is empty and evaluate FORM. | 341 | "Wait for all pending GDB commands to finish and evaluate BODY. |
| 263 | 342 | ||
| 264 | This function checks `gdb-pending-triggers' value every | 343 | This function checks every 0.5 seconds if there are any pending |
| 265 | `gdb-wait-for-pending' seconds." | 344 | triggers in `gdb-handler-list'." |
| 266 | (run-with-timer | 345 | `(run-with-timer |
| 267 | 0.5 nil | 346 | 0.5 nil |
| 268 | `(lambda () | 347 | '(lambda () |
| 269 | (if (not gdb-pending-triggers) | 348 | (if (not (cl-find-if (lambda (handler) |
| 270 | (progn ,@body) | 349 | (gdb-handler-pending-trigger handler)) |
| 271 | (gdb-wait-for-pending ,@body))))) | 350 | gdb-handler-list)) |
| 351 | (progn ,@body) | ||
| 352 | (gdb-wait-for-pending ,@body))))) | ||
| 272 | 353 | ||
| 273 | ;; Publish-subscribe | 354 | ;; Publish-subscribe |
| 274 | 355 | ||
| @@ -574,21 +655,20 @@ NOARG must be t when this macro is used outside `gud-def'" | |||
| 574 | (concat (gdb-gud-context-command ,cmd1 ,noall) " " ,cmd2) | 655 | (concat (gdb-gud-context-command ,cmd1 ,noall) " " ,cmd2) |
| 575 | ,(when (not noarg) 'arg))) | 656 | ,(when (not noarg) 'arg))) |
| 576 | 657 | ||
| 577 | (defun gdb--check-interpreter (proc string) | 658 | (defun gdb--check-interpreter (filter proc string) |
| 578 | (unless (zerop (length string)) | 659 | (unless (zerop (length string)) |
| 579 | (let ((filter (process-get proc 'gud-normal-filter))) | 660 | (remove-function (process-filter proc) #'gdb--check-interpreter) |
| 580 | (set-process-filter proc filter) | 661 | (unless (memq (aref string 0) '(?^ ?~ ?@ ?& ?* ?=)) |
| 581 | (unless (memq (aref string 0) '(?^ ?~ ?@ ?& ?* ?=)) | 662 | ;; Apparently we're not running with -i=mi. |
| 582 | ;; Apparently we're not running with -i=mi. | 663 | (let ((msg "Error: you did not specify -i=mi on GDB's command line!")) |
| 583 | (let ((msg "Error: you did not specify -i=mi on GDB's command line!")) | 664 | (message msg) |
| 584 | (message msg) | 665 | (setq string (concat (propertize msg 'font-lock-face 'error) |
| 585 | (setq string (concat (propertize msg 'font-lock-face 'error) | 666 | "\n" string))) |
| 586 | "\n" string))) | 667 | ;; Use the old gud-gbd filter, not because it works, but because it |
| 587 | ;; Use the old gud-gbd filter, not because it works, but because it | 668 | ;; will properly display GDB's answers rather than hanging waiting for |
| 588 | ;; will properly display GDB's answers rather than hanging waiting for | 669 | ;; answers that aren't coming. |
| 589 | ;; answers that aren't coming. | 670 | (set (make-local-variable 'gud-marker-filter) #'gud-gdb-marker-filter)) |
| 590 | (set (make-local-variable 'gud-marker-filter) #'gud-gdb-marker-filter)) | 671 | (funcall filter proc string))) |
| 591 | (funcall filter proc string)))) | ||
| 592 | 672 | ||
| 593 | (defvar gdb-control-level 0) | 673 | (defvar gdb-control-level 0) |
| 594 | 674 | ||
| @@ -662,8 +742,7 @@ detailed description of this mode. | |||
| 662 | ;; Setup a temporary process filter to warn when GDB was not started | 742 | ;; Setup a temporary process filter to warn when GDB was not started |
| 663 | ;; with -i=mi. | 743 | ;; with -i=mi. |
| 664 | (let ((proc (get-buffer-process gud-comint-buffer))) | 744 | (let ((proc (get-buffer-process gud-comint-buffer))) |
| 665 | (process-put proc 'gud-normal-filter (process-filter proc)) | 745 | (add-function :around (process-filter proc) #'gdb--check-interpreter)) |
| 666 | (set-process-filter proc #'gdb--check-interpreter)) | ||
| 667 | 746 | ||
| 668 | (set (make-local-variable 'gud-minor-mode) 'gdbmi) | 747 | (set (make-local-variable 'gud-minor-mode) 'gdbmi) |
| 669 | (set (make-local-variable 'gdb-control-level) 0) | 748 | (set (make-local-variable 'gdb-control-level) 0) |
| @@ -822,14 +901,12 @@ detailed description of this mode. | |||
| 822 | gdb-frame-number nil | 901 | gdb-frame-number nil |
| 823 | gdb-thread-number nil | 902 | gdb-thread-number nil |
| 824 | gdb-var-list nil | 903 | gdb-var-list nil |
| 825 | gdb-pending-triggers nil | ||
| 826 | gdb-output-sink 'user | 904 | gdb-output-sink 'user |
| 827 | gdb-location-alist nil | 905 | gdb-location-alist nil |
| 828 | gdb-source-file-list nil | 906 | gdb-source-file-list nil |
| 829 | gdb-last-command nil | 907 | gdb-last-command nil |
| 830 | gdb-token-number 0 | 908 | gdb-token-number 0 |
| 831 | gdb-handler-alist '() | 909 | gdb-handler-list '() |
| 832 | gdb-handler-number nil | ||
| 833 | gdb-prompt-name nil | 910 | gdb-prompt-name nil |
| 834 | gdb-first-done-or-error t | 911 | gdb-first-done-or-error t |
| 835 | gdb-buffer-fringe-width (car (window-fringes)) | 912 | gdb-buffer-fringe-width (car (window-fringes)) |
| @@ -1109,17 +1186,15 @@ With arg, enter name of variable to be watched in the minibuffer." | |||
| 1109 | (message-box "No symbol \"%s\" in current context." expr)))) | 1186 | (message-box "No symbol \"%s\" in current context." expr)))) |
| 1110 | 1187 | ||
| 1111 | (defun gdb-speedbar-update () | 1188 | (defun gdb-speedbar-update () |
| 1112 | (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame) | 1189 | (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) |
| 1113 | (not (gdb-pending-p 'gdb-speedbar-timer))) | ||
| 1114 | ;; Dummy command to update speedbar even when idle. | 1190 | ;; Dummy command to update speedbar even when idle. |
| 1115 | (gdb-input "-environment-pwd" 'gdb-speedbar-timer-fn) | 1191 | (gdb-input "-environment-pwd" |
| 1116 | ;; Keep gdb-pending-triggers non-nil till end. | 1192 | 'gdb-speedbar-timer-fn |
| 1117 | (gdb-add-pending 'gdb-speedbar-timer))) | 1193 | 'gdb-speedbar-update))) |
| 1118 | 1194 | ||
| 1119 | (defun gdb-speedbar-timer-fn () | 1195 | (defun gdb-speedbar-timer-fn () |
| 1120 | (if gdb-speedbar-auto-raise | 1196 | (if gdb-speedbar-auto-raise |
| 1121 | (raise-frame speedbar-frame)) | 1197 | (raise-frame speedbar-frame)) |
| 1122 | (gdb-delete-pending 'gdb-speedbar-timer) | ||
| 1123 | (speedbar-timer-fn)) | 1198 | (speedbar-timer-fn)) |
| 1124 | 1199 | ||
| 1125 | (defun gdb-var-evaluate-expression-handler (varnum changed) | 1200 | (defun gdb-var-evaluate-expression-handler (varnum changed) |
| @@ -1209,9 +1284,9 @@ With arg, enter name of variable to be watched in the minibuffer." | |||
| 1209 | 1284 | ||
| 1210 | ; Uses "-var-update --all-values". Needs GDB 6.4 onwards. | 1285 | ; Uses "-var-update --all-values". Needs GDB 6.4 onwards. |
| 1211 | (defun gdb-var-update () | 1286 | (defun gdb-var-update () |
| 1212 | (if (not (gdb-pending-p 'gdb-var-update)) | 1287 | (gdb-input "-var-update --all-values *" |
| 1213 | (gdb-input "-var-update --all-values *" 'gdb-var-update-handler)) | 1288 | 'gdb-var-update-handler |
| 1214 | (gdb-add-pending 'gdb-var-update)) | 1289 | 'gdb-var-update)) |
| 1215 | 1290 | ||
| 1216 | (defun gdb-var-update-handler () | 1291 | (defun gdb-var-update-handler () |
| 1217 | (let ((changelist (bindat-get-field (gdb-json-partial-output) 'changelist))) | 1292 | (let ((changelist (bindat-get-field (gdb-json-partial-output) 'changelist))) |
| @@ -1274,8 +1349,6 @@ With arg, enter name of variable to be watched in the minibuffer." | |||
| 1274 | (push var1 var-list)) | 1349 | (push var1 var-list)) |
| 1275 | (setq var1 (pop temp-var-list))) | 1350 | (setq var1 (pop temp-var-list))) |
| 1276 | (setq gdb-var-list (nreverse var-list)))))))) | 1351 | (setq gdb-var-list (nreverse var-list)))))))) |
| 1277 | (setq gdb-pending-triggers | ||
| 1278 | (delq 'gdb-var-update gdb-pending-triggers)) | ||
| 1279 | (gdb-speedbar-update)) | 1352 | (gdb-speedbar-update)) |
| 1280 | 1353 | ||
| 1281 | (defun gdb-speedbar-expand-node (text token indent) | 1354 | (defun gdb-speedbar-expand-node (text token indent) |
| @@ -1729,18 +1802,25 @@ All embedded quotes, newlines, and backslashes are preceded with a backslash." | |||
| 1729 | (setq string (replace-regexp-in-string "\n" "\\n" string t t)) | 1802 | (setq string (replace-regexp-in-string "\n" "\\n" string t t)) |
| 1730 | (concat "\"" string "\"")) | 1803 | (concat "\"" string "\"")) |
| 1731 | 1804 | ||
| 1732 | (defun gdb-input (command handler-function) | 1805 | (defun gdb-input (command handler-function &optional trigger-name) |
| 1733 | "Send COMMAND to GDB via the MI interface. | 1806 | "Send COMMAND to GDB via the MI interface. |
| 1734 | Run the function HANDLER-FUNCTION, with no arguments, once the command is | 1807 | Run the function HANDLER-FUNCTION, with no arguments, once the command is |
| 1735 | complete." | 1808 | complete. Do not send COMMAND to GDB if TRIGGER-NAME is non-nil and |
| 1736 | (if gdb-enable-debug (push (list 'send-item command handler-function) | 1809 | Emacs is still waiting for a reply from another command previously |
| 1737 | gdb-debug-log)) | 1810 | sent with the same TRIGGER-NAME." |
| 1738 | (setq gdb-token-number (1+ gdb-token-number)) | 1811 | (when (or (not trigger-name) |
| 1739 | (setq command (concat (number-to-string gdb-token-number) command)) | 1812 | (not (gdb-pending-handler-p trigger-name))) |
| 1740 | (push (cons gdb-token-number handler-function) gdb-handler-alist) | 1813 | (setq gdb-token-number (1+ gdb-token-number)) |
| 1741 | (if gdbmi-debug-mode (message "gdb-input: %s" command)) | 1814 | (setq command (concat (number-to-string gdb-token-number) command)) |
| 1742 | (process-send-string (get-buffer-process gud-comint-buffer) | 1815 | |
| 1743 | (concat command "\n"))) | 1816 | (if gdb-enable-debug (push (list 'send-item command handler-function) |
| 1817 | gdb-debug-log)) | ||
| 1818 | |||
| 1819 | (gdb-add-handler gdb-token-number handler-function trigger-name) | ||
| 1820 | |||
| 1821 | (if gdbmi-debug-mode (message "gdb-input: %s" command)) | ||
| 1822 | (process-send-string (get-buffer-process gud-comint-buffer) | ||
| 1823 | (concat command "\n")))) | ||
| 1744 | 1824 | ||
| 1745 | ;; NOFRAME is used for gud execution control commands | 1825 | ;; NOFRAME is used for gud execution control commands |
| 1746 | (defun gdb-current-context-command (command) | 1826 | (defun gdb-current-context-command (command) |
| @@ -1776,7 +1856,7 @@ If `gdb-thread-number' is nil, just wrap NAME in asterisks." | |||
| 1776 | (defun gdb-resync() | 1856 | (defun gdb-resync() |
| 1777 | (setq gud-running nil) | 1857 | (setq gud-running nil) |
| 1778 | (setq gdb-output-sink 'user) | 1858 | (setq gdb-output-sink 'user) |
| 1779 | (setq gdb-pending-triggers nil)) | 1859 | (gdb-remove-all-pending-triggers)) |
| 1780 | 1860 | ||
| 1781 | (defun gdb-update (&optional no-proc) | 1861 | (defun gdb-update (&optional no-proc) |
| 1782 | "Update buffers showing status of debug session. | 1862 | "Update buffers showing status of debug session. |
| @@ -2149,19 +2229,23 @@ the end of the current result or async record is reached." | |||
| 2149 | ;; Search the data stream for the end of the current record: | 2229 | ;; Search the data stream for the end of the current record: |
| 2150 | (let* ((newline-pos (string-match "\n" gud-marker-acc gdbmi-bnf-offset)) | 2230 | (let* ((newline-pos (string-match "\n" gud-marker-acc gdbmi-bnf-offset)) |
| 2151 | (is-progressive (equal (cdr class-command) 'progressive)) | 2231 | (is-progressive (equal (cdr class-command) 'progressive)) |
| 2152 | (is-complete (not (null newline-pos))) | 2232 | (is-complete (not (null newline-pos))) |
| 2153 | result-str) | 2233 | result-str) |
| 2234 | |||
| 2235 | (when gdbmi-debug-mode | ||
| 2236 | (message "gdbmi-bnf-incomplete-record-result: %s" | ||
| 2237 | (substring gud-marker-acc gdbmi-bnf-offset newline-pos))) | ||
| 2154 | 2238 | ||
| 2155 | ;; Update the gdbmi-bnf-offset only if the current chunk of data can | 2239 | ;; Update the gdbmi-bnf-offset only if the current chunk of data can |
| 2156 | ;; be processed by the class-command handler: | 2240 | ;; be processed by the class-command handler: |
| 2157 | (when (or is-complete is-progressive) | 2241 | (when (or is-complete is-progressive) |
| 2158 | (setq result-str | 2242 | (setq result-str |
| 2159 | (substring gud-marker-acc gdbmi-bnf-offset newline-pos)) | 2243 | (substring gud-marker-acc gdbmi-bnf-offset newline-pos)) |
| 2160 | (setq gdbmi-bnf-offset (+ 1 newline-pos))) | ||
| 2161 | 2244 | ||
| 2162 | (if gdbmi-debug-mode | 2245 | ;; Move gdbmi-bnf-offset past the end of the chunk. |
| 2163 | (message "gdbmi-bnf-incomplete-record-result: %s" | 2246 | (setq gdbmi-bnf-offset (+ gdbmi-bnf-offset (length result-str))) |
| 2164 | (substring gud-marker-acc gdbmi-bnf-offset newline-pos))) | 2247 | (when newline-pos |
| 2248 | (setq gdbmi-bnf-offset (1+ gdbmi-bnf-offset)))) | ||
| 2165 | 2249 | ||
| 2166 | ;; Update the parsing state before invoking the handler in class-command | 2250 | ;; Update the parsing state before invoking the handler in class-command |
| 2167 | ;; to make sure it's not left in an invalid state if the handler was | 2251 | ;; to make sure it's not left in an invalid state if the handler was |
| @@ -2253,9 +2337,9 @@ Unset `gdb-thread-number' if current thread exited and update threads list." | |||
| 2253 | (if (string= gdb-thread-number thread-id) | 2337 | (if (string= gdb-thread-number thread-id) |
| 2254 | (gdb-setq-thread-number nil)) | 2338 | (gdb-setq-thread-number nil)) |
| 2255 | ;; When we continue current thread and it quickly exits, | 2339 | ;; When we continue current thread and it quickly exits, |
| 2256 | ;; gdb-pending-triggers left after gdb-running disallow us to | 2340 | ;; the pending triggers in gdb-handler-list left after gdb-running |
| 2257 | ;; properly call -thread-info without --thread option. Thus we | 2341 | ;; disallow us to properly call -thread-info without --thread option. |
| 2258 | ;; need to use gdb-wait-for-pending. | 2342 | ;; Thus we need to use gdb-wait-for-pending. |
| 2259 | (gdb-wait-for-pending | 2343 | (gdb-wait-for-pending |
| 2260 | (gdb-emit-signal gdb-buf-publisher 'update-threads)))) | 2344 | (gdb-emit-signal gdb-buf-publisher 'update-threads)))) |
| 2261 | 2345 | ||
| @@ -2270,9 +2354,10 @@ Sets `gdb-thread-number' to new id." | |||
| 2270 | ;; by `=thread-selected` notification. `^done` causes `gdb-update` | 2354 | ;; by `=thread-selected` notification. `^done` causes `gdb-update` |
| 2271 | ;; as usually. Things happen to fast and second call (from | 2355 | ;; as usually. Things happen to fast and second call (from |
| 2272 | ;; gdb-thread-selected handler) gets cut off by our beloved | 2356 | ;; gdb-thread-selected handler) gets cut off by our beloved |
| 2273 | ;; gdb-pending-triggers. | 2357 | ;; pending triggers. |
| 2274 | ;; Solution is `gdb-wait-for-pending` macro: it guarantees that its | 2358 | ;; Solution is `gdb-wait-for-pending' macro: it guarantees that its |
| 2275 | ;; body will get executed when `gdb-pending-triggers` is empty. | 2359 | ;; body will get executed when `gdb-handler-list' if free of |
| 2360 | ;; pending triggers. | ||
| 2276 | (gdb-wait-for-pending | 2361 | (gdb-wait-for-pending |
| 2277 | (gdb-update)))) | 2362 | (gdb-update)))) |
| 2278 | 2363 | ||
| @@ -2291,8 +2376,7 @@ Sets `gdb-thread-number' to new id." | |||
| 2291 | (propertize gdb-inferior-status 'face font-lock-type-face)) | 2376 | (propertize gdb-inferior-status 'face font-lock-type-face)) |
| 2292 | (when (not gdb-non-stop) | 2377 | (when (not gdb-non-stop) |
| 2293 | (setq gud-running t)) | 2378 | (setq gud-running t)) |
| 2294 | (setq gdb-active-process t) | 2379 | (setq gdb-active-process t)) |
| 2295 | (gdb-emit-signal gdb-buf-publisher 'update-threads)) | ||
| 2296 | 2380 | ||
| 2297 | (defun gdb-starting (_output-field _result) | 2381 | (defun gdb-starting (_output-field _result) |
| 2298 | ;; CLI commands don't emit ^running at the moment so use gdb-running too. | 2382 | ;; CLI commands don't emit ^running at the moment so use gdb-running too. |
| @@ -2300,11 +2384,7 @@ Sets `gdb-thread-number' to new id." | |||
| 2300 | (gdb-force-mode-line-update | 2384 | (gdb-force-mode-line-update |
| 2301 | (propertize gdb-inferior-status 'face font-lock-type-face)) | 2385 | (propertize gdb-inferior-status 'face font-lock-type-face)) |
| 2302 | (setq gdb-active-process t) | 2386 | (setq gdb-active-process t) |
| 2303 | (setq gud-running t) | 2387 | (setq gud-running t)) |
| 2304 | ;; GDB doesn't seem to respond to -thread-info before first stop or | ||
| 2305 | ;; thread exit (even in non-stop mode), so this is useless. | ||
| 2306 | ;; Behavior may change in the future. | ||
| 2307 | (gdb-emit-signal gdb-buf-publisher 'update-threads)) | ||
| 2308 | 2388 | ||
| 2309 | ;; -break-insert -t didn't give a reason before gdb 6.9 | 2389 | ;; -break-insert -t didn't give a reason before gdb 6.9 |
| 2310 | 2390 | ||
| @@ -2436,10 +2516,7 @@ current thread and update GDB buffers." | |||
| 2436 | (when (and token-number is-complete) | 2516 | (when (and token-number is-complete) |
| 2437 | (with-current-buffer | 2517 | (with-current-buffer |
| 2438 | (gdb-get-buffer-create 'gdb-partial-output-buffer) | 2518 | (gdb-get-buffer-create 'gdb-partial-output-buffer) |
| 2439 | (funcall | 2519 | (gdb-handle-reply (string-to-number token-number)))) |
| 2440 | (cdr (assoc (string-to-number token-number) gdb-handler-alist)))) | ||
| 2441 | (setq gdb-handler-alist | ||
| 2442 | (assq-delete-all token-number gdb-handler-alist))) | ||
| 2443 | 2520 | ||
| 2444 | (when is-complete | 2521 | (when is-complete |
| 2445 | (gdb-clear-partial-output)))) | 2522 | (gdb-clear-partial-output)))) |
| @@ -2657,27 +2734,23 @@ trigger argument when describing buffer types with | |||
| 2657 | (when | 2734 | (when |
| 2658 | (or (not ,signal-list) | 2735 | (or (not ,signal-list) |
| 2659 | (memq signal ,signal-list)) | 2736 | (memq signal ,signal-list)) |
| 2660 | (when (not (gdb-pending-p | 2737 | (gdb-input ,gdb-command |
| 2661 | (cons (current-buffer) ',trigger-name))) | 2738 | (gdb-bind-function-to-buffer ',handler-name (current-buffer)) |
| 2662 | (gdb-input ,gdb-command | 2739 | (cons (current-buffer) ',trigger-name))))) |
| 2663 | (gdb-bind-function-to-buffer ',handler-name (current-buffer))) | ||
| 2664 | (gdb-add-pending (cons (current-buffer) ',trigger-name)))))) | ||
| 2665 | 2740 | ||
| 2666 | ;; Used by disassembly buffer only, the rest use | 2741 | ;; Used by disassembly buffer only, the rest use |
| 2667 | ;; def-gdb-trigger-and-handler | 2742 | ;; def-gdb-trigger-and-handler |
| 2668 | (defmacro def-gdb-auto-update-handler (handler-name trigger-name custom-defun | 2743 | (defmacro def-gdb-auto-update-handler (handler-name custom-defun |
| 2669 | &optional nopreserve) | 2744 | &optional nopreserve) |
| 2670 | "Define a handler HANDLER-NAME for TRIGGER-NAME with CUSTOM-DEFUN. | 2745 | "Define a handler HANDLER-NAME calling CUSTOM-DEFUN. |
| 2671 | 2746 | ||
| 2672 | Handlers are normally called from the buffers they put output in. | 2747 | Handlers are normally called from the buffers they put output in. |
| 2673 | 2748 | ||
| 2674 | Delete ((current-buffer) . TRIGGER-NAME) from | 2749 | Erase current buffer and evaluate CUSTOM-DEFUN. |
| 2675 | `gdb-pending-triggers', erase current buffer and evaluate | 2750 | Then call `gdb-update-buffer-name'. |
| 2676 | CUSTOM-DEFUN. Then `gdb-update-buffer-name' is called. | ||
| 2677 | 2751 | ||
| 2678 | If NOPRESERVE is non-nil, window point is not restored after CUSTOM-DEFUN." | 2752 | If NOPRESERVE is non-nil, window point is not restored after CUSTOM-DEFUN." |
| 2679 | `(defun ,handler-name () | 2753 | `(defun ,handler-name () |
| 2680 | (gdb-delete-pending (cons (current-buffer) ',trigger-name)) | ||
| 2681 | (let* ((inhibit-read-only t) | 2754 | (let* ((inhibit-read-only t) |
| 2682 | ,@(unless nopreserve | 2755 | ,@(unless nopreserve |
| 2683 | '((window (get-buffer-window (current-buffer) 0)) | 2756 | '((window (get-buffer-window (current-buffer) 0)) |
| @@ -2705,7 +2778,7 @@ See `def-gdb-auto-update-handler'." | |||
| 2705 | ,gdb-command | 2778 | ,gdb-command |
| 2706 | ,handler-name ,signal-list) | 2779 | ,handler-name ,signal-list) |
| 2707 | (def-gdb-auto-update-handler ,handler-name | 2780 | (def-gdb-auto-update-handler ,handler-name |
| 2708 | ,trigger-name ,custom-defun))) | 2781 | ,custom-defun))) |
| 2709 | 2782 | ||
| 2710 | 2783 | ||
| 2711 | 2784 | ||
| @@ -3622,7 +3695,6 @@ DOC is an optional documentation string." | |||
| 3622 | 3695 | ||
| 3623 | (def-gdb-auto-update-handler | 3696 | (def-gdb-auto-update-handler |
| 3624 | gdb-disassembly-handler | 3697 | gdb-disassembly-handler |
| 3625 | gdb-invalidate-disassembly | ||
| 3626 | gdb-disassembly-handler-custom | 3698 | gdb-disassembly-handler-custom |
| 3627 | t) | 3699 | t) |
| 3628 | 3700 | ||
| @@ -4114,21 +4186,19 @@ member." | |||
| 4114 | 4186 | ||
| 4115 | ;; Needs GDB 6.4 onwards (used to fail with no stack). | 4187 | ;; Needs GDB 6.4 onwards (used to fail with no stack). |
| 4116 | (defun gdb-get-changed-registers () | 4188 | (defun gdb-get-changed-registers () |
| 4117 | (when (and (gdb-get-buffer 'gdb-registers-buffer) | 4189 | (when (gdb-get-buffer 'gdb-registers-buffer) |
| 4118 | (not (gdb-pending-p 'gdb-get-changed-registers))) | ||
| 4119 | (gdb-input "-data-list-changed-registers" | 4190 | (gdb-input "-data-list-changed-registers" |
| 4120 | 'gdb-changed-registers-handler) | 4191 | 'gdb-changed-registers-handler |
| 4121 | (gdb-add-pending 'gdb-get-changed-registers))) | 4192 | 'gdb-get-changed-registers))) |
| 4122 | 4193 | ||
| 4123 | (defun gdb-changed-registers-handler () | 4194 | (defun gdb-changed-registers-handler () |
| 4124 | (gdb-delete-pending 'gdb-get-changed-registers) | ||
| 4125 | (setq gdb-changed-registers nil) | 4195 | (setq gdb-changed-registers nil) |
| 4126 | (dolist (register-number | 4196 | (dolist (register-number |
| 4127 | (bindat-get-field (gdb-json-partial-output) 'changed-registers)) | 4197 | (bindat-get-field (gdb-json-partial-output) 'changed-registers)) |
| 4128 | (push register-number gdb-changed-registers))) | 4198 | (push register-number gdb-changed-registers))) |
| 4129 | 4199 | ||
| 4130 | (defun gdb-register-names-handler () | 4200 | (defun gdb-register-names-handler () |
| 4131 | ;; Don't use gdb-pending-triggers because this handler is called | 4201 | ;; Don't use pending triggers because this handler is called |
| 4132 | ;; only once (in gdb-init-1) | 4202 | ;; only once (in gdb-init-1) |
| 4133 | (setq gdb-register-names nil) | 4203 | (setq gdb-register-names nil) |
| 4134 | (dolist (register-name | 4204 | (dolist (register-name |
| @@ -4152,16 +4222,13 @@ is set in them." | |||
| 4152 | (defun gdb-get-main-selected-frame () | 4222 | (defun gdb-get-main-selected-frame () |
| 4153 | "Trigger for `gdb-frame-handler' which uses main current thread. | 4223 | "Trigger for `gdb-frame-handler' which uses main current thread. |
| 4154 | Called from `gdb-update'." | 4224 | Called from `gdb-update'." |
| 4155 | (if (not (gdb-pending-p 'gdb-get-main-selected-frame)) | 4225 | (gdb-input (gdb-current-context-command "-stack-info-frame") |
| 4156 | (progn | 4226 | 'gdb-frame-handler |
| 4157 | (gdb-input (gdb-current-context-command "-stack-info-frame") | 4227 | 'gdb-get-main-selected-frame)) |
| 4158 | 'gdb-frame-handler) | ||
| 4159 | (gdb-add-pending 'gdb-get-main-selected-frame)))) | ||
| 4160 | 4228 | ||
| 4161 | (defun gdb-frame-handler () | 4229 | (defun gdb-frame-handler () |
| 4162 | "Set `gdb-selected-frame' and `gdb-selected-file' to show | 4230 | "Set `gdb-selected-frame' and `gdb-selected-file' to show |
| 4163 | overlay arrow in source buffer." | 4231 | overlay arrow in source buffer." |
| 4164 | (gdb-delete-pending 'gdb-get-main-selected-frame) | ||
| 4165 | (let ((frame (bindat-get-field (gdb-json-partial-output) 'frame))) | 4232 | (let ((frame (bindat-get-field (gdb-json-partial-output) 'frame))) |
| 4166 | (when frame | 4233 | (when frame |
| 4167 | (setq gdb-selected-frame (bindat-get-field frame 'func)) | 4234 | (setq gdb-selected-frame (bindat-get-field frame 'func)) |
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 1e152c6d751..46af51e1f97 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el | |||
| @@ -410,7 +410,9 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies | |||
| 410 | (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t) | 410 | (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t) |
| 411 | (1 grep-error-face) | 411 | (1 grep-error-face) |
| 412 | (2 grep-error-face nil t)) | 412 | (2 grep-error-face nil t)) |
| 413 | ("^.+?-[0-9]+-.*\n" (0 grep-context-face))) | 413 | ;; "filename-linenumber-" format is used for context lines in GNU grep, |
| 414 | ;; "filename=linenumber=" for lines with function names in "git grep -p". | ||
| 415 | ("^.+?[-=][0-9]+[-=].*\n" (0 grep-context-face))) | ||
| 414 | "Additional things to highlight in grep output. | 416 | "Additional things to highlight in grep output. |
| 415 | This gets tacked on the end of the generated expressions.") | 417 | This gets tacked on the end of the generated expressions.") |
| 416 | 418 | ||
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index d339495d76a..c549d9eedef 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el | |||
| @@ -46,11 +46,8 @@ | |||
| 46 | (defvar gdb-show-changed-values) | 46 | (defvar gdb-show-changed-values) |
| 47 | (defvar gdb-source-window) | 47 | (defvar gdb-source-window) |
| 48 | (defvar gdb-var-list) | 48 | (defvar gdb-var-list) |
| 49 | (defvar gdb-speedbar-auto-raise) | ||
| 50 | (defvar gud-tooltip-mode) | ||
| 51 | (defvar hl-line-mode) | 49 | (defvar hl-line-mode) |
| 52 | (defvar hl-line-sticky-flag) | 50 | (defvar hl-line-sticky-flag) |
| 53 | (defvar tool-bar-map) | ||
| 54 | 51 | ||
| 55 | 52 | ||
| 56 | ;; ====================================================================== | 53 | ;; ====================================================================== |
| @@ -416,7 +413,7 @@ we're in the GUD buffer)." | |||
| 416 | 413 | ||
| 417 | ;; ====================================================================== | 414 | ;; ====================================================================== |
| 418 | ;; speedbar support functions and variables. | 415 | ;; speedbar support functions and variables. |
| 419 | (eval-when-compile (require 'speedbar)) ;For speedbar-with-attached-buffer. | 416 | (eval-when-compile (require 'dframe)) ; for dframe-with-attached-buffer |
| 420 | 417 | ||
| 421 | (defvar gud-last-speedbar-stackframe nil | 418 | (defvar gud-last-speedbar-stackframe nil |
| 422 | "Description of the currently displayed GUD stack. | 419 | "Description of the currently displayed GUD stack. |
| @@ -425,19 +422,24 @@ The value t means that there is no stack, and we are in display-file mode.") | |||
| 425 | (defvar gud-speedbar-key-map nil | 422 | (defvar gud-speedbar-key-map nil |
| 426 | "Keymap used when in the buffers display mode.") | 423 | "Keymap used when in the buffers display mode.") |
| 427 | 424 | ||
| 425 | ;; At runtime, will be pulled in as a require of speedbar. | ||
| 426 | (declare-function dframe-message "dframe" (fmt &rest args)) | ||
| 427 | |||
| 428 | (defun gud-speedbar-item-info () | 428 | (defun gud-speedbar-item-info () |
| 429 | "Display the data type of the watch expression element." | 429 | "Display the data type of the watch expression element." |
| 430 | (let ((var (nth (- (line-number-at-pos (point)) 2) gdb-var-list))) | 430 | (let ((var (nth (- (line-number-at-pos (point)) 2) gdb-var-list))) |
| 431 | (if (nth 7 var) | 431 | (if (nth 7 var) |
| 432 | (speedbar-message "%s: %s" (nth 7 var) (nth 3 var)) | 432 | (dframe-message "%s: %s" (nth 7 var) (nth 3 var)) |
| 433 | (speedbar-message "%s" (nth 3 var))))) | 433 | (dframe-message "%s" (nth 3 var))))) |
| 434 | |||
| 435 | (declare-function speedbar-make-specialized-keymap "speedbar" ()) | ||
| 436 | (declare-function speedbar-add-expansion-list "speedbar" (new-list)) | ||
| 437 | (defvar speedbar-mode-functions-list) | ||
| 434 | 438 | ||
| 435 | (defun gud-install-speedbar-variables () | 439 | (defun gud-install-speedbar-variables () |
| 436 | "Install those variables used by speedbar to enhance gud/gdb." | 440 | "Install those variables used by speedbar to enhance gud/gdb." |
| 437 | (if gud-speedbar-key-map | 441 | (unless gud-speedbar-key-map |
| 438 | nil | ||
| 439 | (setq gud-speedbar-key-map (speedbar-make-specialized-keymap)) | 442 | (setq gud-speedbar-key-map (speedbar-make-specialized-keymap)) |
| 440 | |||
| 441 | (define-key gud-speedbar-key-map "j" 'speedbar-edit-line) | 443 | (define-key gud-speedbar-key-map "j" 'speedbar-edit-line) |
| 442 | (define-key gud-speedbar-key-map "e" 'speedbar-edit-line) | 444 | (define-key gud-speedbar-key-map "e" 'speedbar-edit-line) |
| 443 | (define-key gud-speedbar-key-map "\C-m" 'speedbar-edit-line) | 445 | (define-key gud-speedbar-key-map "\C-m" 'speedbar-edit-line) |
| @@ -486,6 +488,13 @@ The value t means that there is no stack, and we are in display-file mode.") | |||
| 486 | DIRECTORY and ZERO are not used, but are required by the caller." | 488 | DIRECTORY and ZERO are not used, but are required by the caller." |
| 487 | (gud-speedbar-buttons gud-comint-buffer)) | 489 | (gud-speedbar-buttons gud-comint-buffer)) |
| 488 | 490 | ||
| 491 | (declare-function speedbar-make-tag-line "speedbar" | ||
| 492 | (type char func data tag tfunc tdata tface depth)) | ||
| 493 | (declare-function speedbar-remove-localized-speedbar-support "speedbar" | ||
| 494 | (buffer)) | ||
| 495 | (declare-function speedbar-insert-button "speedbar" | ||
| 496 | (text face mouse function &optional token prevline)) | ||
| 497 | |||
| 489 | (defun gud-speedbar-buttons (buffer) | 498 | (defun gud-speedbar-buttons (buffer) |
| 490 | "Create a speedbar display based on the current state of GUD. | 499 | "Create a speedbar display based on the current state of GUD. |
| 491 | If the GUD BUFFER is not running a supported debugger, then turn | 500 | If the GUD BUFFER is not running a supported debugger, then turn |
| @@ -707,6 +716,16 @@ The option \"--fullname\" must be included in this value." | |||
| 707 | (defvar gud-filter-pending-text nil | 716 | (defvar gud-filter-pending-text nil |
| 708 | "Non-nil means this is text that has been saved for later in `gud-filter'.") | 717 | "Non-nil means this is text that has been saved for later in `gud-filter'.") |
| 709 | 718 | ||
| 719 | ;; One of the nice features of GDB is its impressive support for | ||
| 720 | ;; context-sensitive command completion. We preserve that feature | ||
| 721 | ;; in the GUD buffer by using a GDB command designed just for Emacs. | ||
| 722 | |||
| 723 | (defvar gud-gdb-completion-function nil | ||
| 724 | "Completion function for GDB commands. | ||
| 725 | It receives two arguments: COMMAND, the prefix for which we seek | ||
| 726 | completion; and CONTEXT, the text before COMMAND on the line. | ||
| 727 | It should return a list of completion strings.") | ||
| 728 | |||
| 710 | ;; If in gdb mode, gdb-mi is loaded. | 729 | ;; If in gdb mode, gdb-mi is loaded. |
| 711 | (declare-function gdb-restore-windows "gdb-mi" ()) | 730 | (declare-function gdb-restore-windows "gdb-mi" ()) |
| 712 | 731 | ||
| @@ -767,16 +786,6 @@ directory and source-file directory for your debugger." | |||
| 767 | (setq gud-filter-pending-text nil) | 786 | (setq gud-filter-pending-text nil) |
| 768 | (run-hooks 'gud-gdb-mode-hook)) | 787 | (run-hooks 'gud-gdb-mode-hook)) |
| 769 | 788 | ||
| 770 | ;; One of the nice features of GDB is its impressive support for | ||
| 771 | ;; context-sensitive command completion. We preserve that feature | ||
| 772 | ;; in the GUD buffer by using a GDB command designed just for Emacs. | ||
| 773 | |||
| 774 | (defvar gud-gdb-completion-function nil | ||
| 775 | "Completion function for GDB commands. | ||
| 776 | It receives two arguments: COMMAND, the prefix for which we seek | ||
| 777 | completion; and CONTEXT, the text before COMMAND on the line. | ||
| 778 | It should return a list of completion strings.") | ||
| 779 | |||
| 780 | ;; The completion process filter indicates when it is finished. | 789 | ;; The completion process filter indicates when it is finished. |
| 781 | (defvar gud-gdb-fetch-lines-in-progress) | 790 | (defvar gud-gdb-fetch-lines-in-progress) |
| 782 | 791 | ||
| @@ -884,9 +893,14 @@ It is passed through `gud-gdb-marker-filter' before we look at it." | |||
| 884 | 893 | ||
| 885 | ;; gdb speedbar functions | 894 | ;; gdb speedbar functions |
| 886 | 895 | ||
| 896 | ;; Part of the macro expansion of dframe-with-attached-buffer. | ||
| 897 | ;; At runtime, will be pulled in as a require of speedbar. | ||
| 898 | (declare-function dframe-select-attached-frame "dframe" (&optional frame)) | ||
| 899 | (declare-function dframe-maybee-jump-to-attached-frame "dframe" ()) | ||
| 900 | |||
| 887 | (defun gud-gdb-goto-stackframe (_text token _indent) | 901 | (defun gud-gdb-goto-stackframe (_text token _indent) |
| 888 | "Goto the stackframe described by TEXT, TOKEN, and INDENT." | 902 | "Goto the stackframe described by TEXT, TOKEN, and INDENT." |
| 889 | (speedbar-with-attached-buffer | 903 | (dframe-with-attached-buffer |
| 890 | (gud-basic-call (concat "server frame " (nth 1 token))) | 904 | (gud-basic-call (concat "server frame " (nth 1 token))) |
| 891 | (sit-for 1))) | 905 | (sit-for 1))) |
| 892 | 906 | ||
| @@ -1487,14 +1501,38 @@ into one that invokes an Emacs-enabled debugging session. | |||
| 1487 | (let ((output "")) | 1501 | (let ((output "")) |
| 1488 | 1502 | ||
| 1489 | ;; Process all the complete markers in this chunk. | 1503 | ;; Process all the complete markers in this chunk. |
| 1490 | (while (string-match "\032\032\\(\\([a-zA-Z]:\\)?[^:\n]*\\):\\([0-9]*\\):.*\n" | 1504 | ;; |
| 1491 | gud-marker-acc) | 1505 | ;; Here I match the string coming out of perldb. |
| 1506 | ;; The strings can look like any of | ||
| 1507 | ;; | ||
| 1508 | ;; "\032\032/tmp/tst.pl:6:0\n" | ||
| 1509 | ;; "\032\032(eval 5)[/tmp/tst.pl:6]:3:0\n" | ||
| 1510 | ;; "\032\032(eval 17)[Basic/Core/Core.pm.PL (i.e. PDL::Core.pm):2931]:1:0\n" | ||
| 1511 | ;; | ||
| 1512 | ;; From those I want the filename and the line number. First I look for | ||
| 1513 | ;; the eval case. If that doesn't match, I look for the "normal" case. | ||
| 1514 | (while | ||
| 1515 | (string-match | ||
| 1516 | (eval-when-compile | ||
| 1517 | (let ((file-re "\\(?:[a-zA-Z]:\\)?[^:\n]*")) | ||
| 1518 | (concat "\032\032\\(?:" | ||
| 1519 | (concat | ||
| 1520 | "(eval [0-9]+)\\[" | ||
| 1521 | "\\(" file-re "\\)" ; Filename. | ||
| 1522 | "\\(?: (i\\.e\\. [^)]*)\\)?" | ||
| 1523 | ":\\([0-9]*\\)\\]") ; Line number. | ||
| 1524 | "\\|" | ||
| 1525 | (concat | ||
| 1526 | "\\(?1:" file-re "\\)" ; Filename. | ||
| 1527 | ":\\(?2:[0-9]*\\)") ; Line number. | ||
| 1528 | "\\):.*\n"))) | ||
| 1529 | gud-marker-acc) | ||
| 1492 | (setq | 1530 | (setq |
| 1493 | 1531 | ||
| 1494 | ;; Extract the frame position from the marker. | 1532 | ;; Extract the frame position from the marker. |
| 1495 | gud-last-frame | 1533 | gud-last-frame |
| 1496 | (cons (match-string 1 gud-marker-acc) | 1534 | (cons (match-string 1 gud-marker-acc) |
| 1497 | (string-to-number (match-string 3 gud-marker-acc))) | 1535 | (string-to-number (match-string 2 gud-marker-acc))) |
| 1498 | 1536 | ||
| 1499 | ;; Append any text before the marker to the output we're going | 1537 | ;; Append any text before the marker to the output we're going |
| 1500 | ;; to return - we don't include the marker in this text. | 1538 | ;; to return - we don't include the marker in this text. |
| @@ -2612,6 +2650,8 @@ It is saved for when this flag is not set.") | |||
| 2612 | (add-to-list 'overlay-arrow-variable-list 'gud-overlay-arrow-position) | 2650 | (add-to-list 'overlay-arrow-variable-list 'gud-overlay-arrow-position) |
| 2613 | 2651 | ||
| 2614 | (declare-function gdb-reset "gdb-mi" ()) | 2652 | (declare-function gdb-reset "gdb-mi" ()) |
| 2653 | (declare-function speedbar-change-initial-expansion-list "speedbar" (new)) | ||
| 2654 | (defvar speedbar-previously-used-expansion-list-name) | ||
| 2615 | 2655 | ||
| 2616 | (defun gud-sentinel (proc msg) | 2656 | (defun gud-sentinel (proc msg) |
| 2617 | (cond ((null (buffer-name (process-buffer proc))) | 2657 | (cond ((null (buffer-name (process-buffer proc))) |
| @@ -2619,7 +2659,7 @@ It is saved for when this flag is not set.") | |||
| 2619 | ;; Stop displaying an arrow in a source file. | 2659 | ;; Stop displaying an arrow in a source file. |
| 2620 | (setq gud-overlay-arrow-position nil) | 2660 | (setq gud-overlay-arrow-position nil) |
| 2621 | (set-process-buffer proc nil) | 2661 | (set-process-buffer proc nil) |
| 2622 | (if (and (boundp 'speedbar-frame) | 2662 | (if (and (boundp 'speedbar-initial-expansion-list-name) |
| 2623 | (string-equal speedbar-initial-expansion-list-name "GUD")) | 2663 | (string-equal speedbar-initial-expansion-list-name "GUD")) |
| 2624 | (speedbar-change-initial-expansion-list | 2664 | (speedbar-change-initial-expansion-list |
| 2625 | speedbar-previously-used-expansion-list-name)) | 2665 | speedbar-previously-used-expansion-list-name)) |
| @@ -3312,6 +3352,9 @@ only tooltips in the buffer containing the overlay arrow." | |||
| 3312 | :group 'gud | 3352 | :group 'gud |
| 3313 | :group 'tooltip) | 3353 | :group 'tooltip) |
| 3314 | 3354 | ||
| 3355 | (make-obsolete-variable 'gud-tooltip-echo-area | ||
| 3356 | "disable Tooltip mode instead" "24.4" 'set) | ||
| 3357 | |||
| 3315 | ;;; Reacting on mouse movements | 3358 | ;;; Reacting on mouse movements |
| 3316 | 3359 | ||
| 3317 | (defun gud-tooltip-change-major-mode () | 3360 | (defun gud-tooltip-change-major-mode () |
| @@ -3363,9 +3406,6 @@ ACTIVATEP non-nil means activate mouse motion events." | |||
| 3363 | 3406 | ||
| 3364 | ;;; Tips for `gud' | 3407 | ;;; Tips for `gud' |
| 3365 | 3408 | ||
| 3366 | (defvar gud-tooltip-original-filter nil | ||
| 3367 | "Process filter to restore after GUD output has been received.") | ||
| 3368 | |||
| 3369 | (defvar gud-tooltip-dereference nil | 3409 | (defvar gud-tooltip-dereference nil |
| 3370 | "Non-nil means print expressions with a `*' in front of them. | 3410 | "Non-nil means print expressions with a `*' in front of them. |
| 3371 | For C this would dereference a pointer expression.") | 3411 | For C this would dereference a pointer expression.") |
| @@ -3396,12 +3436,13 @@ With arg, dereference expr if ARG is positive, otherwise do not dereference." | |||
| 3396 | ; the tooltip incompletely and spill over into the gud buffer. | 3436 | ; the tooltip incompletely and spill over into the gud buffer. |
| 3397 | ; Switching the process-filter creates timing problems and | 3437 | ; Switching the process-filter creates timing problems and |
| 3398 | ; it may be difficult to do better. Using GDB/MI as in | 3438 | ; it may be difficult to do better. Using GDB/MI as in |
| 3399 | ; gdb-mi.el gets round this problem. | 3439 | ; gdb-mi.el gets around this problem. |
| 3400 | (defun gud-tooltip-process-output (process output) | 3440 | (defun gud-tooltip-process-output (process output) |
| 3401 | "Process debugger output and show it in a tooltip window." | 3441 | "Process debugger output and show it in a tooltip window." |
| 3402 | (set-process-filter process gud-tooltip-original-filter) | 3442 | (remove-function (process-filter process) #'gud-tooltip-process-output) |
| 3403 | (tooltip-show (tooltip-strip-prompt process output) | 3443 | (tooltip-show (tooltip-strip-prompt process output) |
| 3404 | (or gud-tooltip-echo-area tooltip-use-echo-area))) | 3444 | (or gud-tooltip-echo-area tooltip-use-echo-area |
| 3445 | (not tooltip-mode)))) | ||
| 3405 | 3446 | ||
| 3406 | (defun gud-tooltip-print-command (expr) | 3447 | (defun gud-tooltip-print-command (expr) |
| 3407 | "Return a suitable command to print the expression EXPR." | 3448 | "Return a suitable command to print the expression EXPR." |
| @@ -3411,7 +3452,7 @@ With arg, dereference expr if ARG is positive, otherwise do not dereference." | |||
| 3411 | ((or `xdb `pdb) (concat "p " expr)) | 3452 | ((or `xdb `pdb) (concat "p " expr)) |
| 3412 | (`sdb (concat expr "/")))) | 3453 | (`sdb (concat expr "/")))) |
| 3413 | 3454 | ||
| 3414 | (declare-function gdb-input "gdb-mi" (command handler)) | 3455 | (declare-function gdb-input "gdb-mi" (command handler &optional trigger)) |
| 3415 | (declare-function tooltip-expr-to-print "tooltip" (event)) | 3456 | (declare-function tooltip-expr-to-print "tooltip" (event)) |
| 3416 | (declare-function tooltip-event-buffer "tooltip" (event)) | 3457 | (declare-function tooltip-event-buffer "tooltip" (event)) |
| 3417 | 3458 | ||
| @@ -3444,7 +3485,8 @@ This function must return nil if it doesn't handle EVENT." | |||
| 3444 | (unless (null define-elt) | 3485 | (unless (null define-elt) |
| 3445 | (tooltip-show | 3486 | (tooltip-show |
| 3446 | (cdr define-elt) | 3487 | (cdr define-elt) |
| 3447 | (or gud-tooltip-echo-area tooltip-use-echo-area)) | 3488 | (or gud-tooltip-echo-area tooltip-use-echo-area |
| 3489 | (not tooltip-mode))) | ||
| 3448 | expr)))) | 3490 | expr)))) |
| 3449 | (when gud-tooltip-dereference | 3491 | (when gud-tooltip-dereference |
| 3450 | (setq expr (concat "*" expr))) | 3492 | (setq expr (concat "*" expr))) |
| @@ -3466,8 +3508,8 @@ so they have been disabled.")) | |||
| 3466 | (gdb-input | 3508 | (gdb-input |
| 3467 | (concat cmd "\n") | 3509 | (concat cmd "\n") |
| 3468 | `(lambda () (gdb-tooltip-print ,expr)))) | 3510 | `(lambda () (gdb-tooltip-print ,expr)))) |
| 3469 | (setq gud-tooltip-original-filter (process-filter process)) | 3511 | (add-function :override (process-filter process) |
| 3470 | (set-process-filter process 'gud-tooltip-process-output) | 3512 | #'gud-tooltip-process-output) |
| 3471 | (gud-basic-call cmd)) | 3513 | (gud-basic-call cmd)) |
| 3472 | expr)))))))) | 3514 | expr)))))))) |
| 3473 | 3515 | ||
diff --git a/lisp/progmodes/idlw-help.el b/lisp/progmodes/idlw-help.el index 749b0b65576..7060cae5080 100644 --- a/lisp/progmodes/idlw-help.el +++ b/lisp/progmodes/idlw-help.el | |||
| @@ -90,16 +90,15 @@ Defaults to `browse-url-browser-function', which see." | |||
| 90 | (defcustom idlwave-help-browser-generic-program browse-url-generic-program | 90 | (defcustom idlwave-help-browser-generic-program browse-url-generic-program |
| 91 | "Program to run if using `browse-url-generic-program'." | 91 | "Program to run if using `browse-url-generic-program'." |
| 92 | :group 'idlwave-online-help | 92 | :group 'idlwave-online-help |
| 93 | :type 'string) | 93 | :type '(choice (const nil) string)) |
| 94 | |||
| 95 | (defvar browse-url-generic-args) | ||
| 96 | 94 | ||
| 95 | ;; AFAICS, never used since it was introduced in 2004. | ||
| 97 | (defcustom idlwave-help-browser-generic-args | 96 | (defcustom idlwave-help-browser-generic-args |
| 98 | (if (boundp 'browse-url-generic-args) | 97 | (if (boundp 'browse-url-generic-args) |
| 99 | browse-url-generic-args "") | 98 | browse-url-generic-args "") |
| 100 | "Program args to use if using `browse-url-generic-program'." | 99 | "Program args to use if using `browse-url-generic-program'." |
| 101 | :group 'idlwave-online-help | 100 | :group 'idlwave-online-help |
| 102 | :type 'string) | 101 | :type '(repeat string)) |
| 103 | 102 | ||
| 104 | (defcustom idlwave-help-browser-is-local nil | 103 | (defcustom idlwave-help-browser-is-local nil |
| 105 | "Whether the browser will display locally in an Emacs window. | 104 | "Whether the browser will display locally in an Emacs window. |
| @@ -1179,7 +1178,7 @@ Useful when source code is displayed as help. See the option | |||
| 1179 | (if (featurep 'font-lock) | 1178 | (if (featurep 'font-lock) |
| 1180 | (let ((major-mode 'idlwave-mode) | 1179 | (let ((major-mode 'idlwave-mode) |
| 1181 | (font-lock-verbose | 1180 | (font-lock-verbose |
| 1182 | (if (interactive-p) font-lock-verbose nil)) | 1181 | (if (called-interactively-p 'interactive) font-lock-verbose nil)) |
| 1183 | (syntax-table (syntax-table))) | 1182 | (syntax-table (syntax-table))) |
| 1184 | (unwind-protect | 1183 | (unwind-protect |
| 1185 | (progn | 1184 | (progn |
diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el index aeaf1acb2ac..ba9a632b949 100644 --- a/lisp/progmodes/idlwave.el +++ b/lisp/progmodes/idlwave.el | |||
| @@ -5078,11 +5078,14 @@ Cache to disk for quick recovery." | |||
| 5078 | ;; The sequence here is important because earlier definitions shadow | 5078 | ;; The sequence here is important because earlier definitions shadow |
| 5079 | ;; later ones. We assume that if things in the buffers are newer | 5079 | ;; later ones. We assume that if things in the buffers are newer |
| 5080 | ;; then in the shell of the system, they are meant to be different. | 5080 | ;; then in the shell of the system, they are meant to be different. |
| 5081 | (setcdr idlwave-last-system-routine-info-cons-cell | 5081 | (let ((temp (append idlwave-buffer-routines |
| 5082 | (append idlwave-buffer-routines | 5082 | idlwave-compiled-routines |
| 5083 | idlwave-compiled-routines | 5083 | idlwave-library-catalog-routines |
| 5084 | idlwave-library-catalog-routines | 5084 | idlwave-user-catalog-routines))) |
| 5085 | idlwave-user-catalog-routines)) | 5085 | ;; Not actually used for anything? |
| 5086 | (if idlwave-last-system-routine-info-cons-cell | ||
| 5087 | (setcdr idlwave-last-system-routine-info-cons-cell temp) | ||
| 5088 | (setq idlwave-last-system-routine-info-cons-cell (cons temp nil)))) | ||
| 5086 | (setq idlwave-class-alist nil) | 5089 | (setq idlwave-class-alist nil) |
| 5087 | 5090 | ||
| 5088 | ;; Give a message with information about the number of routines we have. | 5091 | ;; Give a message with information about the number of routines we have. |
| @@ -5481,30 +5484,21 @@ directories and save the routine info. | |||
| 5481 | (message "Creating user catalog file...") | 5484 | (message "Creating user catalog file...") |
| 5482 | (kill-buffer "*idlwave-scan.pro*") | 5485 | (kill-buffer "*idlwave-scan.pro*") |
| 5483 | (kill-buffer (get-buffer-create "*IDLWAVE Widget*")) | 5486 | (kill-buffer (get-buffer-create "*IDLWAVE Widget*")) |
| 5484 | (let ((font-lock-maximum-size 0) | 5487 | (with-temp-buffer |
| 5485 | (auto-mode-alist nil)) | 5488 | (insert ";; IDLWAVE user catalog file\n") |
| 5486 | (find-file idlwave-user-catalog-file)) | 5489 | (insert (format ";; Created %s\n\n" (current-time-string))) |
| 5487 | (if (and (boundp 'font-lock-mode) | 5490 | |
| 5488 | font-lock-mode) | 5491 | ;; Define the routine info list |
| 5489 | (font-lock-mode 0)) | 5492 | (insert "\n(setq idlwave-user-catalog-routines\n '(") |
| 5490 | (erase-buffer) | 5493 | (let ((standard-output (current-buffer))) |
| 5491 | (insert ";; IDLWAVE user catalog file\n") | 5494 | (mapc (lambda (x) |
| 5492 | (insert (format ";; Created %s\n\n" (current-time-string))) | 5495 | (insert "\n ") |
| 5493 | 5496 | (prin1 x) | |
| 5494 | ;; Define the routine info list | 5497 | (goto-char (point-max))) |
| 5495 | (insert "\n(setq idlwave-user-catalog-routines\n '(") | 5498 | idlwave-user-catalog-routines)) |
| 5496 | (let ((standard-output (current-buffer))) | 5499 | (insert (format "))\n\n;;; %s ends here\n" |
| 5497 | (mapc (lambda (x) | 5500 | (file-name-nondirectory idlwave-user-catalog-file))) |
| 5498 | (insert "\n ") | 5501 | (write-region nil nil idlwave-user-catalog-file))) |
| 5499 | (prin1 x) | ||
| 5500 | (goto-char (point-max))) | ||
| 5501 | idlwave-user-catalog-routines)) | ||
| 5502 | (insert (format "))\n\n;;; %s ends here\n" | ||
| 5503 | (file-name-nondirectory idlwave-user-catalog-file))) | ||
| 5504 | (goto-char (point-min)) | ||
| 5505 | ;; Save the buffer | ||
| 5506 | (save-buffer 0) | ||
| 5507 | (kill-buffer (current-buffer))) | ||
| 5508 | (message "Creating user catalog file...done") | 5502 | (message "Creating user catalog file...done") |
| 5509 | (message "Info for %d routines saved in %s" | 5503 | (message "Info for %d routines saved in %s" |
| 5510 | (length idlwave-user-catalog-routines) | 5504 | (length idlwave-user-catalog-routines) |
| @@ -5522,31 +5516,23 @@ directories and save the routine info. | |||
| 5522 | (defun idlwave-write-paths () | 5516 | (defun idlwave-write-paths () |
| 5523 | (interactive) | 5517 | (interactive) |
| 5524 | (when (and idlwave-path-alist idlwave-system-directory) | 5518 | (when (and idlwave-path-alist idlwave-system-directory) |
| 5525 | (let ((font-lock-maximum-size 0) | 5519 | (with-temp-buffer |
| 5526 | (auto-mode-alist nil)) | 5520 | (insert ";; IDLWAVE paths\n") |
| 5527 | (find-file idlwave-path-file)) | 5521 | (insert (format ";; Created %s\n\n" (current-time-string))) |
| 5528 | (if (and (boundp 'font-lock-mode) | ||
| 5529 | font-lock-mode) | ||
| 5530 | (font-lock-mode 0)) | ||
| 5531 | (erase-buffer) | ||
| 5532 | (insert ";; IDLWAVE paths\n") | ||
| 5533 | (insert (format ";; Created %s\n\n" (current-time-string))) | ||
| 5534 | ;; Define the variable which knows the value of "!DIR" | 5522 | ;; Define the variable which knows the value of "!DIR" |
| 5535 | (insert (format "\n(setq idlwave-system-directory \"%s\")\n" | 5523 | (insert (format "\n(setq idlwave-system-directory \"%s\")\n" |
| 5536 | idlwave-system-directory)) | 5524 | idlwave-system-directory)) |
| 5537 | 5525 | ||
| 5538 | ;; Define the variable which contains a list of all scanned directories | 5526 | ;; Define the variable which contains a list of all scanned directories |
| 5539 | (insert "\n(setq idlwave-path-alist\n '(") | 5527 | (insert "\n(setq idlwave-path-alist\n '(") |
| 5540 | (let ((standard-output (current-buffer))) | 5528 | (let ((standard-output (current-buffer))) |
| 5541 | (mapc (lambda (x) | 5529 | (mapc (lambda (x) |
| 5542 | (insert "\n ") | 5530 | (insert "\n ") |
| 5543 | (prin1 x) | 5531 | (prin1 x) |
| 5544 | (goto-char (point-max))) | 5532 | (goto-char (point-max))) |
| 5545 | idlwave-path-alist)) | 5533 | idlwave-path-alist)) |
| 5546 | (insert "))\n") | 5534 | (insert "))\n") |
| 5547 | (save-buffer 0) | 5535 | (write-region nil nil idlwave-path-file)))) |
| 5548 | (kill-buffer (current-buffer)))) | ||
| 5549 | |||
| 5550 | 5536 | ||
| 5551 | (defun idlwave-expand-path (path &optional default-dir) | 5537 | (defun idlwave-expand-path (path &optional default-dir) |
| 5552 | ;; Expand parts of path starting with '+' recursively into directory list. | 5538 | ;; Expand parts of path starting with '+' recursively into directory list. |
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 2ea78fc321c..28ee859f9db 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el | |||
| @@ -55,7 +55,6 @@ | |||
| 55 | 55 | ||
| 56 | (eval-when-compile | 56 | (eval-when-compile |
| 57 | (require 'cl-lib) | 57 | (require 'cl-lib) |
| 58 | (require 'comint) | ||
| 59 | (require 'ido)) | 58 | (require 'ido)) |
| 60 | 59 | ||
| 61 | (defvar inferior-moz-buffer) | 60 | (defvar inferior-moz-buffer) |
| @@ -2217,6 +2216,9 @@ marker." | |||
| 2217 | 2216 | ||
| 2218 | (defvar find-tag-marker-ring) ; etags | 2217 | (defvar find-tag-marker-ring) ; etags |
| 2219 | 2218 | ||
| 2219 | ;; etags loads ring. | ||
| 2220 | (declare-function ring-insert "ring" (ring item)) | ||
| 2221 | |||
| 2220 | (defun js-find-symbol (&optional arg) | 2222 | (defun js-find-symbol (&optional arg) |
| 2221 | "Read a JavaScript symbol and jump to it. | 2223 | "Read a JavaScript symbol and jump to it. |
| 2222 | With a prefix argument, restrict symbols to those from the | 2224 | With a prefix argument, restrict symbols to those from the |
| @@ -2639,6 +2641,11 @@ with `js--js-encode-value'." | |||
| 2639 | ;; order to catch a prompt that's only partially arrived | 2641 | ;; order to catch a prompt that's only partially arrived |
| 2640 | (save-excursion (forward-line 0) (point)))) | 2642 | (save-excursion (forward-line 0) (point)))) |
| 2641 | 2643 | ||
| 2644 | ;; Presumably "inferior-moz-process" loads comint. | ||
| 2645 | (declare-function comint-send-string "comint" (process string)) | ||
| 2646 | (declare-function comint-send-input "comint" | ||
| 2647 | (&optional no-newline artificial)) | ||
| 2648 | |||
| 2642 | (defun js--js-enter-repl () | 2649 | (defun js--js-enter-repl () |
| 2643 | (inferior-moz-process) ; called for side-effect | 2650 | (inferior-moz-process) ; called for side-effect |
| 2644 | (with-current-buffer inferior-moz-buffer | 2651 | (with-current-buffer inferior-moz-buffer |
| @@ -2697,6 +2704,10 @@ with `js--js-encode-value'." | |||
| 2697 | (defsubst js--js-true (value) | 2704 | (defsubst js--js-true (value) |
| 2698 | (not (js--js-not value))) | 2705 | (not (js--js-not value))) |
| 2699 | 2706 | ||
| 2707 | ;; The somewhat complex code layout confuses the byte-compiler into | ||
| 2708 | ;; thinking this function "might not be defined at runtime". | ||
| 2709 | (declare-function js--optimize-arglist "js" (arglist)) | ||
| 2710 | |||
| 2700 | (eval-and-compile | 2711 | (eval-and-compile |
| 2701 | (defun js--optimize-arglist (arglist) | 2712 | (defun js--optimize-arglist (arglist) |
| 2702 | "Convert immediate js< and js! references to deferred ones." | 2713 | "Convert immediate js< and js! references to deferred ones." |
| @@ -2824,6 +2835,8 @@ If nil, the whole Array is treated as a JS symbol.") | |||
| 2824 | (`error (signal 'js-js-error (list (cl-second result)))) | 2835 | (`error (signal 'js-js-error (list (cl-second result)))) |
| 2825 | (x (error "Unmatched case in js--js-decode-retval: %S" x)))) | 2836 | (x (error "Unmatched case in js--js-decode-retval: %S" x)))) |
| 2826 | 2837 | ||
| 2838 | (defvar comint-last-input-end) | ||
| 2839 | |||
| 2827 | (defun js--js-funcall (function &rest arguments) | 2840 | (defun js--js-funcall (function &rest arguments) |
| 2828 | "Call the Mozilla function FUNCTION with arguments ARGUMENTS. | 2841 | "Call the Mozilla function FUNCTION with arguments ARGUMENTS. |
| 2829 | If function is a string, look it up as a property on the global | 2842 | If function is a string, look it up as a property on the global |
| @@ -2996,6 +3009,8 @@ left-to-right." | |||
| 2996 | 3009 | ||
| 2997 | (defvar js-read-tab-history nil) | 3010 | (defvar js-read-tab-history nil) |
| 2998 | 3011 | ||
| 3012 | (declare-function ido-chop "ido" (items elem)) | ||
| 3013 | |||
| 2999 | (defun js--read-tab (prompt) | 3014 | (defun js--read-tab (prompt) |
| 3000 | "Read a Mozilla tab with prompt PROMPT. | 3015 | "Read a Mozilla tab with prompt PROMPT. |
| 3001 | Return a cons of (TYPE . OBJECT). TYPE is either 'window or | 3016 | Return a cons of (TYPE . OBJECT). TYPE is either 'window or |
diff --git a/lisp/progmodes/ld-script.el b/lisp/progmodes/ld-script.el index 34d1525bbab..ffb425ee1e9 100644 --- a/lisp/progmodes/ld-script.el +++ b/lisp/progmodes/ld-script.el | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | (modify-syntax-entry ?\) ")(" st) | 48 | (modify-syntax-entry ?\) ")(" st) |
| 49 | (modify-syntax-entry ?\[ "(]" st) | 49 | (modify-syntax-entry ?\[ "(]" st) |
| 50 | (modify-syntax-entry ?\] ")[" st) | 50 | (modify-syntax-entry ?\] ")[" st) |
| 51 | (modify-syntax-entry ?_ "w" st) | 51 | (modify-syntax-entry ?_ "_" st) |
| 52 | (modify-syntax-entry ?. "_" st) | 52 | (modify-syntax-entry ?. "_" st) |
| 53 | (modify-syntax-entry ?\\ "\\" st) | 53 | (modify-syntax-entry ?\\ "\\" st) |
| 54 | (modify-syntax-entry ?: "." st) | 54 | (modify-syntax-entry ?: "." st) |
| @@ -154,10 +154,10 @@ | |||
| 154 | 154 | ||
| 155 | (defvar ld-script-font-lock-keywords | 155 | (defvar ld-script-font-lock-keywords |
| 156 | (append | 156 | (append |
| 157 | `((,(regexp-opt ld-script-keywords 'words) | 157 | `((,(concat "\\_<" (regexp-opt ld-script-keywords) "\\_>") |
| 158 | 1 font-lock-keyword-face) | 158 | 0 font-lock-keyword-face) |
| 159 | (,(regexp-opt ld-script-builtins 'words) | 159 | (,(concat "\\_<" (regexp-opt ld-script-builtins) "\\_>") |
| 160 | 1 font-lock-builtin-face) | 160 | 0 font-lock-builtin-face) |
| 161 | ;; 3.6.7 Output Section Discarding | 161 | ;; 3.6.7 Output Section Discarding |
| 162 | ;; 3.6.4.1 Input Section Basics | 162 | ;; 3.6.4.1 Input Section Basics |
| 163 | ;; 3.6.8.7 Output Section Phdr | 163 | ;; 3.6.8.7 Output Section Phdr |
diff --git a/lisp/progmodes/m4-mode.el b/lisp/progmodes/m4-mode.el index 0641fc776de..4ba2ae1ded9 100644 --- a/lisp/progmodes/m4-mode.el +++ b/lisp/progmodes/m4-mode.el | |||
| @@ -45,15 +45,10 @@ | |||
| 45 | :prefix "m4-" | 45 | :prefix "m4-" |
| 46 | :group 'languages) | 46 | :group 'languages) |
| 47 | 47 | ||
| 48 | (defcustom m4-program | 48 | (defcustom m4-program "m4" |
| 49 | (cond | 49 | "File name of the m4 executable. |
| 50 | ((file-exists-p "/usr/local/bin/m4") "/usr/local/bin/m4") | 50 | If m4 is not in your PATH, set this to an absolute file name." |
| 51 | ((file-exists-p "/usr/bin/m4") "/usr/bin/m4") | 51 | :version "24.4" |
| 52 | ((file-exists-p "/bin/m4") "/bin/m4") | ||
| 53 | ((file-exists-p "/usr/ccs/bin/m4") "/usr/ccs/bin/m4") | ||
| 54 | ( t "m4") | ||
| 55 | ) | ||
| 56 | "File name of the m4 executable." | ||
| 57 | :type 'file | 52 | :type 'file |
| 58 | :group 'm4) | 53 | :group 'm4) |
| 59 | 54 | ||
| @@ -85,19 +80,24 @@ | |||
| 85 | :group 'm4) | 80 | :group 'm4) |
| 86 | 81 | ||
| 87 | ;;this may still need some work | 82 | ;;this may still need some work |
| 88 | (defvar m4-mode-syntax-table nil | 83 | (defvar m4-mode-syntax-table |
| 84 | (let ((table (make-syntax-table))) | ||
| 85 | (modify-syntax-entry ?` "('" table) | ||
| 86 | (modify-syntax-entry ?' ")`" table) | ||
| 87 | (modify-syntax-entry ?# "<\n" table) | ||
| 88 | (modify-syntax-entry ?\n ">#" table) | ||
| 89 | (modify-syntax-entry ?{ "_" table) | ||
| 90 | (modify-syntax-entry ?} "_" table) | ||
| 91 | ;; FIXME: This symbol syntax for underscore looks OK on its own, but it's | ||
| 92 | ;; odd that it should have the same syntax as { and } are these really | ||
| 93 | ;; valid in m4 symbols? | ||
| 94 | (modify-syntax-entry ?_ "_" table) | ||
| 95 | ;; FIXME: These three chars with word syntax look wrong. | ||
| 96 | (modify-syntax-entry ?* "w" table) | ||
| 97 | (modify-syntax-entry ?\" "w" table) | ||
| 98 | (modify-syntax-entry ?\" "w" table) | ||
| 99 | table) | ||
| 89 | "Syntax table used while in `m4-mode'.") | 100 | "Syntax table used while in `m4-mode'.") |
| 90 | (setq m4-mode-syntax-table (make-syntax-table)) | ||
| 91 | (modify-syntax-entry ?` "('" m4-mode-syntax-table) | ||
| 92 | (modify-syntax-entry ?' ")`" m4-mode-syntax-table) | ||
| 93 | (modify-syntax-entry ?# "<\n" m4-mode-syntax-table) | ||
| 94 | (modify-syntax-entry ?\n ">#" m4-mode-syntax-table) | ||
| 95 | (modify-syntax-entry ?{ "_" m4-mode-syntax-table) | ||
| 96 | (modify-syntax-entry ?} "_" m4-mode-syntax-table) | ||
| 97 | (modify-syntax-entry ?* "w" m4-mode-syntax-table) | ||
| 98 | (modify-syntax-entry ?_ "w" m4-mode-syntax-table) | ||
| 99 | (modify-syntax-entry ?\" "w" m4-mode-syntax-table) | ||
| 100 | (modify-syntax-entry ?\" "w" m4-mode-syntax-table) | ||
| 101 | 101 | ||
| 102 | (defvar m4-mode-map | 102 | (defvar m4-mode-map |
| 103 | (let ((map (make-sparse-keymap)) | 103 | (let ((map (make-sparse-keymap)) |
| @@ -117,12 +117,6 @@ | |||
| 117 | :help "Send contents of the current region to m4")) | 117 | :help "Send contents of the current region to m4")) |
| 118 | map)) | 118 | map)) |
| 119 | 119 | ||
| 120 | (defvar m4-mode-abbrev-table nil | ||
| 121 | "Abbrev table used while in `m4-mode'.") | ||
| 122 | |||
| 123 | (unless m4-mode-abbrev-table | ||
| 124 | (define-abbrev-table 'm4-mode-abbrev-table ())) | ||
| 125 | |||
| 126 | (defun m4-m4-buffer () | 120 | (defun m4-m4-buffer () |
| 127 | "Send contents of the current buffer to m4." | 121 | "Send contents of the current buffer to m4." |
| 128 | (interactive) | 122 | (interactive) |
| @@ -151,7 +145,6 @@ | |||
| 151 | ;;;###autoload | 145 | ;;;###autoload |
| 152 | (define-derived-mode m4-mode prog-mode "m4" | 146 | (define-derived-mode m4-mode prog-mode "m4" |
| 153 | "A major mode to edit m4 macro files." | 147 | "A major mode to edit m4 macro files." |
| 154 | :abbrev-table m4-mode-abbrev-table | ||
| 155 | (setq-local comment-start "#") | 148 | (setq-local comment-start "#") |
| 156 | (setq-local parse-sexp-ignore-comments t) | 149 | (setq-local parse-sexp-ignore-comments t) |
| 157 | (setq-local add-log-current-defun-function #'m4-current-defun-name) | 150 | (setq-local add-log-current-defun-function #'m4-current-defun-name) |
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index 20673866bc4..3069c790e1c 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el | |||
| @@ -241,7 +241,7 @@ to MODIFY A FILE WITHOUT YOUR CONFIRMATION when \"it seems necessary\"." | |||
| 241 | "List of special targets. | 241 | "List of special targets. |
| 242 | You will be offered to complete on one of those in the minibuffer whenever | 242 | You will be offered to complete on one of those in the minibuffer whenever |
| 243 | you enter a \".\" at the beginning of a line in `makefile-mode'." | 243 | you enter a \".\" at the beginning of a line in `makefile-mode'." |
| 244 | :type '(repeat (list string)) | 244 | :type '(repeat string) |
| 245 | :group 'makefile) | 245 | :group 'makefile) |
| 246 | (put 'makefile-special-targets-list 'risky-local-variable t) | 246 | (put 'makefile-special-targets-list 'risky-local-variable t) |
| 247 | 247 | ||
diff --git a/lisp/progmodes/meta-mode.el b/lisp/progmodes/meta-mode.el index b090435ac9b..6a150667f19 100644 --- a/lisp/progmodes/meta-mode.el +++ b/lisp/progmodes/meta-mode.el | |||
| @@ -794,6 +794,7 @@ The environment marked is the one that contains point or follows point." | |||
| 794 | 794 | ||
| 795 | (defvar meta-common-mode-syntax-table | 795 | (defvar meta-common-mode-syntax-table |
| 796 | (let ((st (make-syntax-table))) | 796 | (let ((st (make-syntax-table))) |
| 797 | ;; FIXME: This goes against the convention! | ||
| 797 | ;; underscores are word constituents | 798 | ;; underscores are word constituents |
| 798 | (modify-syntax-entry ?_ "w" st) | 799 | (modify-syntax-entry ?_ "w" st) |
| 799 | ;; miscellaneous non-word symbols | 800 | ;; miscellaneous non-word symbols |
diff --git a/lisp/progmodes/octave-inf.el b/lisp/progmodes/octave-inf.el deleted file mode 100644 index de7ca32befe..00000000000 --- a/lisp/progmodes/octave-inf.el +++ /dev/null | |||
| @@ -1,386 +0,0 @@ | |||
| 1 | ;;; octave-inf.el --- running Octave as an inferior Emacs process | ||
| 2 | |||
| 3 | ;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> | ||
| 6 | ;; John Eaton <jwe@bevo.che.wisc.edu> | ||
| 7 | ;; Maintainer: FSF | ||
| 8 | ;; Keywords: languages | ||
| 9 | ;; Package: octave-mod | ||
| 10 | |||
| 11 | ;; This file is part of GNU Emacs. | ||
| 12 | |||
| 13 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 14 | ;; it under the terms of the GNU General Public License as published by | ||
| 15 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 16 | ;; (at your option) any later version. | ||
| 17 | |||
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | ;; GNU General Public License for more details. | ||
| 22 | |||
| 23 | ;; You should have received a copy of the GNU General Public License | ||
| 24 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 25 | |||
| 26 | ;;; Commentary: | ||
| 27 | |||
| 28 | ;;; Code: | ||
| 29 | |||
| 30 | (require 'octave-mod) | ||
| 31 | (require 'comint) | ||
| 32 | |||
| 33 | (defgroup octave-inferior nil | ||
| 34 | "Running Octave as an inferior Emacs process." | ||
| 35 | :group 'octave) | ||
| 36 | |||
| 37 | (defcustom inferior-octave-program "octave" | ||
| 38 | "Program invoked by `inferior-octave'." | ||
| 39 | :type 'string | ||
| 40 | :group 'octave-inferior) | ||
| 41 | |||
| 42 | (defcustom inferior-octave-prompt | ||
| 43 | "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ " | ||
| 44 | "Regexp to match prompts for the inferior Octave process." | ||
| 45 | :type 'regexp | ||
| 46 | :group 'octave-inferior) | ||
| 47 | |||
| 48 | (defcustom inferior-octave-startup-file nil | ||
| 49 | "Name of the inferior Octave startup file. | ||
| 50 | The contents of this file are sent to the inferior Octave process on | ||
| 51 | startup." | ||
| 52 | :type '(choice (const :tag "None" nil) | ||
| 53 | file) | ||
| 54 | :group 'octave-inferior) | ||
| 55 | |||
| 56 | (defcustom inferior-octave-startup-args nil | ||
| 57 | "List of command line arguments for the inferior Octave process. | ||
| 58 | For example, for suppressing the startup message and using `traditional' | ||
| 59 | mode, set this to (\"-q\" \"--traditional\")." | ||
| 60 | :type '(repeat string) | ||
| 61 | :group 'octave-inferior) | ||
| 62 | |||
| 63 | (defvar inferior-octave-mode-map | ||
| 64 | (let ((map (make-sparse-keymap))) | ||
| 65 | (set-keymap-parent map comint-mode-map) | ||
| 66 | (define-key map "\t" 'comint-dynamic-complete) | ||
| 67 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) | ||
| 68 | (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring) | ||
| 69 | (define-key map [menu-bar inout list-history] | ||
| 70 | '("List Input History" . inferior-octave-dynamic-list-input-ring)) | ||
| 71 | ;; FIXME: free C-h so it can do the describe-prefix-bindings. | ||
| 72 | (define-key map "\C-c\C-h" 'info-lookup-symbol) | ||
| 73 | map) | ||
| 74 | "Keymap used in Inferior Octave mode.") | ||
| 75 | |||
| 76 | (defvar inferior-octave-mode-syntax-table | ||
| 77 | (let ((table (make-syntax-table octave-mode-syntax-table))) | ||
| 78 | table) | ||
| 79 | "Syntax table in use in inferior-octave-mode buffers.") | ||
| 80 | |||
| 81 | (defcustom inferior-octave-mode-hook nil | ||
| 82 | "Hook to be run when Inferior Octave mode is started." | ||
| 83 | :type 'hook | ||
| 84 | :group 'octave-inferior) | ||
| 85 | |||
| 86 | (defvar inferior-octave-font-lock-keywords | ||
| 87 | (list | ||
| 88 | (cons inferior-octave-prompt 'font-lock-type-face)) | ||
| 89 | ;; Could certainly do more font locking in inferior Octave ... | ||
| 90 | "Additional expressions to highlight in Inferior Octave mode.") | ||
| 91 | |||
| 92 | |||
| 93 | ;;; Compatibility functions | ||
| 94 | (if (not (fboundp 'comint-line-beginning-position)) | ||
| 95 | ;; comint-line-beginning-position is defined in Emacs 21 | ||
| 96 | (defun comint-line-beginning-position () | ||
| 97 | "Returns the buffer position of the beginning of the line, after any prompt. | ||
| 98 | The prompt is assumed to be any text at the beginning of the line matching | ||
| 99 | the regular expression `comint-prompt-regexp', a buffer local variable." | ||
| 100 | (save-excursion (comint-bol nil) (point)))) | ||
| 101 | |||
| 102 | |||
| 103 | (defvar inferior-octave-output-list nil) | ||
| 104 | (defvar inferior-octave-output-string nil) | ||
| 105 | (defvar inferior-octave-receive-in-progress nil) | ||
| 106 | |||
| 107 | (defvar inferior-octave-startup-hook nil) | ||
| 108 | |||
| 109 | (defvar inferior-octave-complete-impossible nil | ||
| 110 | "Non-nil means that `inferior-octave-complete' is impossible.") | ||
| 111 | |||
| 112 | (defvar inferior-octave-has-built-in-variables nil | ||
| 113 | "Non-nil means that Octave has built-in variables.") | ||
| 114 | |||
| 115 | (defvar inferior-octave-dynamic-complete-functions | ||
| 116 | '(inferior-octave-completion-at-point comint-filename-completion) | ||
| 117 | "List of functions called to perform completion for inferior Octave. | ||
| 118 | This variable is used to initialize `comint-dynamic-complete-functions' | ||
| 119 | in the Inferior Octave buffer.") | ||
| 120 | |||
| 121 | (defvar info-lookup-mode) | ||
| 122 | |||
| 123 | (define-derived-mode inferior-octave-mode comint-mode "Inferior Octave" | ||
| 124 | "Major mode for interacting with an inferior Octave process. | ||
| 125 | Runs Octave as a subprocess of Emacs, with Octave I/O through an Emacs | ||
| 126 | buffer. | ||
| 127 | |||
| 128 | Entry to this mode successively runs the hooks `comint-mode-hook' and | ||
| 129 | `inferior-octave-mode-hook'." | ||
| 130 | (setq comint-prompt-regexp inferior-octave-prompt | ||
| 131 | mode-line-process '(":%s") | ||
| 132 | local-abbrev-table octave-abbrev-table) | ||
| 133 | |||
| 134 | (set (make-local-variable 'comment-start) octave-comment-start) | ||
| 135 | (set (make-local-variable 'comment-end) "") | ||
| 136 | (set (make-local-variable 'comment-column) 32) | ||
| 137 | (set (make-local-variable 'comment-start-skip) octave-comment-start-skip) | ||
| 138 | |||
| 139 | (set (make-local-variable 'font-lock-defaults) | ||
| 140 | '(inferior-octave-font-lock-keywords nil nil)) | ||
| 141 | |||
| 142 | (set (make-local-variable 'info-lookup-mode) 'octave-mode) | ||
| 143 | |||
| 144 | (setq comint-input-ring-file-name | ||
| 145 | (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist") | ||
| 146 | comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)) | ||
| 147 | (set (make-local-variable 'comint-dynamic-complete-functions) | ||
| 148 | inferior-octave-dynamic-complete-functions) | ||
| 149 | (add-hook 'comint-input-filter-functions | ||
| 150 | 'inferior-octave-directory-tracker nil t) | ||
| 151 | (comint-read-input-ring t)) | ||
| 152 | |||
| 153 | ;;;###autoload | ||
| 154 | (defun inferior-octave (&optional arg) | ||
| 155 | "Run an inferior Octave process, I/O via `inferior-octave-buffer'. | ||
| 156 | This buffer is put in Inferior Octave mode. See `inferior-octave-mode'. | ||
| 157 | |||
| 158 | Unless ARG is non-nil, switches to this buffer. | ||
| 159 | |||
| 160 | The elements of the list `inferior-octave-startup-args' are sent as | ||
| 161 | command line arguments to the inferior Octave process on startup. | ||
| 162 | |||
| 163 | Additional commands to be executed on startup can be provided either in | ||
| 164 | the file specified by `inferior-octave-startup-file' or by the default | ||
| 165 | startup file, `~/.emacs-octave'." | ||
| 166 | (interactive "P") | ||
| 167 | (let ((buffer inferior-octave-buffer)) | ||
| 168 | (get-buffer-create buffer) | ||
| 169 | (if (comint-check-proc buffer) | ||
| 170 | () | ||
| 171 | (with-current-buffer buffer | ||
| 172 | (comint-mode) | ||
| 173 | (inferior-octave-startup) | ||
| 174 | (inferior-octave-mode))) | ||
| 175 | (if (not arg) | ||
| 176 | (pop-to-buffer buffer)))) | ||
| 177 | |||
| 178 | ;;;###autoload | ||
| 179 | (defalias 'run-octave 'inferior-octave) | ||
| 180 | |||
| 181 | (defun inferior-octave-startup () | ||
| 182 | "Start an inferior Octave process." | ||
| 183 | (let ((proc (comint-exec-1 | ||
| 184 | (substring inferior-octave-buffer 1 -1) | ||
| 185 | inferior-octave-buffer | ||
| 186 | inferior-octave-program | ||
| 187 | (append (list "-i" "--no-line-editing") | ||
| 188 | inferior-octave-startup-args)))) | ||
| 189 | (set-process-filter proc 'inferior-octave-output-digest) | ||
| 190 | (setq comint-ptyp process-connection-type | ||
| 191 | inferior-octave-process proc | ||
| 192 | inferior-octave-output-list nil | ||
| 193 | inferior-octave-output-string nil | ||
| 194 | inferior-octave-receive-in-progress t) | ||
| 195 | |||
| 196 | ;; This may look complicated ... However, we need to make sure that | ||
| 197 | ;; we additional startup code only AFTER Octave is ready (otherwise, | ||
| 198 | ;; output may be mixed up). Hence, we need to digest the Octave | ||
| 199 | ;; output to see when it issues a prompt. | ||
| 200 | (while inferior-octave-receive-in-progress | ||
| 201 | (accept-process-output inferior-octave-process)) | ||
| 202 | (goto-char (point-max)) | ||
| 203 | (set-marker (process-mark proc) (point)) | ||
| 204 | (insert-before-markers | ||
| 205 | (concat | ||
| 206 | (if (not (bobp)) "\n") | ||
| 207 | (if inferior-octave-output-list | ||
| 208 | (concat (mapconcat | ||
| 209 | 'identity inferior-octave-output-list "\n") | ||
| 210 | "\n")))) | ||
| 211 | |||
| 212 | ;; Find out whether Octave has built-in variables. | ||
| 213 | (inferior-octave-send-list-and-digest | ||
| 214 | (list "exist \"LOADPATH\"\n")) | ||
| 215 | (setq inferior-octave-has-built-in-variables | ||
| 216 | (string-match "101$" (car inferior-octave-output-list))) | ||
| 217 | |||
| 218 | ;; An empty secondary prompt, as e.g. obtained by '--braindead', | ||
| 219 | ;; means trouble. | ||
| 220 | (inferior-octave-send-list-and-digest (list "PS2\n")) | ||
| 221 | (if (string-match "\\(PS2\\|ans\\) = *$" (car inferior-octave-output-list)) | ||
| 222 | (inferior-octave-send-list-and-digest | ||
| 223 | (list (if inferior-octave-has-built-in-variables | ||
| 224 | "PS2 = \"> \"\n" | ||
| 225 | "PS2 (\"> \");\n")))) | ||
| 226 | |||
| 227 | ;; O.k., now we are ready for the Inferior Octave startup commands. | ||
| 228 | (let* (commands | ||
| 229 | (program (file-name-nondirectory inferior-octave-program)) | ||
| 230 | (file (or inferior-octave-startup-file | ||
| 231 | (concat "~/.emacs-" program)))) | ||
| 232 | (setq commands | ||
| 233 | (list "more off;\n" | ||
| 234 | (if (not (string-equal | ||
| 235 | inferior-octave-output-string ">> ")) | ||
| 236 | (if inferior-octave-has-built-in-variables | ||
| 237 | "PS1=\"\\\\s> \";\n" | ||
| 238 | "PS1 (\"\\\\s> \");\n")) | ||
| 239 | (if (file-exists-p file) | ||
| 240 | (format "source (\"%s\");\n" file)))) | ||
| 241 | (inferior-octave-send-list-and-digest commands)) | ||
| 242 | (insert-before-markers | ||
| 243 | (concat | ||
| 244 | (if inferior-octave-output-list | ||
| 245 | (concat (mapconcat | ||
| 246 | 'identity inferior-octave-output-list "\n") | ||
| 247 | "\n")) | ||
| 248 | inferior-octave-output-string)) | ||
| 249 | ;; Next, we check whether Octave supports `completion_matches' ... | ||
| 250 | (inferior-octave-send-list-and-digest | ||
| 251 | (list "exist \"completion_matches\"\n")) | ||
| 252 | (setq inferior-octave-complete-impossible | ||
| 253 | (not (string-match "5$" (car inferior-octave-output-list)))) | ||
| 254 | |||
| 255 | ;; And finally, everything is back to normal. | ||
| 256 | (set-process-filter proc 'inferior-octave-output-filter) | ||
| 257 | (run-hooks 'inferior-octave-startup-hook) | ||
| 258 | (run-hooks 'inferior-octave-startup-hook) | ||
| 259 | ;; Just in case, to be sure a cd in the startup file | ||
| 260 | ;; won't have detrimental effects. | ||
| 261 | (inferior-octave-resync-dirs))) | ||
| 262 | |||
| 263 | |||
| 264 | (defun inferior-octave-completion-at-point () | ||
| 265 | "Return the data to complete the Octave symbol at point." | ||
| 266 | (let* ((end (point)) | ||
| 267 | (start | ||
| 268 | (save-excursion | ||
| 269 | (skip-syntax-backward "w_" (comint-line-beginning-position)) | ||
| 270 | (point)))) | ||
| 271 | (cond ((eq start end) nil) | ||
| 272 | (inferior-octave-complete-impossible | ||
| 273 | (message (concat | ||
| 274 | "Your Octave does not have `completion_matches'. " | ||
| 275 | "Please upgrade to version 2.X.")) | ||
| 276 | nil) | ||
| 277 | (t | ||
| 278 | (list | ||
| 279 | start end | ||
| 280 | (completion-table-dynamic | ||
| 281 | (lambda (command) | ||
| 282 | (inferior-octave-send-list-and-digest | ||
| 283 | (list (concat "completion_matches (\"" command "\");\n"))) | ||
| 284 | (sort (delete-dups inferior-octave-output-list) | ||
| 285 | 'string-lessp)))))))) | ||
| 286 | |||
| 287 | (define-obsolete-function-alias 'inferior-octave-complete | ||
| 288 | 'completion-at-point "24.1") | ||
| 289 | |||
| 290 | (defun inferior-octave-dynamic-list-input-ring () | ||
| 291 | "List the buffer's input history in a help buffer." | ||
| 292 | ;; We cannot use `comint-dynamic-list-input-ring', because it replaces | ||
| 293 | ;; "completion" by "history reference" ... | ||
| 294 | (interactive) | ||
| 295 | (if (or (not (ring-p comint-input-ring)) | ||
| 296 | (ring-empty-p comint-input-ring)) | ||
| 297 | (message "No history") | ||
| 298 | (let ((history nil) | ||
| 299 | (history-buffer " *Input History*") | ||
| 300 | (index (1- (ring-length comint-input-ring))) | ||
| 301 | (conf (current-window-configuration))) | ||
| 302 | ;; We have to build up a list ourselves from the ring vector. | ||
| 303 | (while (>= index 0) | ||
| 304 | (setq history (cons (ring-ref comint-input-ring index) history) | ||
| 305 | index (1- index))) | ||
| 306 | ;; Change "completion" to "history reference" | ||
| 307 | ;; to make the display accurate. | ||
| 308 | (with-output-to-temp-buffer history-buffer | ||
| 309 | (display-completion-list history) | ||
| 310 | (set-buffer history-buffer)) | ||
| 311 | (message "Hit space to flush") | ||
| 312 | (let ((ch (read-event))) | ||
| 313 | (if (eq ch ?\ ) | ||
| 314 | (set-window-configuration conf) | ||
| 315 | (setq unread-command-events (list ch))))))) | ||
| 316 | |||
| 317 | (defun inferior-octave-strip-ctrl-g (string) | ||
| 318 | "Strip leading `^G' character. | ||
| 319 | If STRING starts with a `^G', ring the bell and strip it." | ||
| 320 | (if (string-match "^\a" string) | ||
| 321 | (progn | ||
| 322 | (ding) | ||
| 323 | (setq string (substring string 1)))) | ||
| 324 | string) | ||
| 325 | |||
| 326 | (defun inferior-octave-output-filter (proc string) | ||
| 327 | "Standard output filter for the inferior Octave process. | ||
| 328 | Ring Emacs bell if process output starts with an ASCII bell, and pass | ||
| 329 | the rest to `comint-output-filter'." | ||
| 330 | (comint-output-filter proc (inferior-octave-strip-ctrl-g string))) | ||
| 331 | |||
| 332 | (defun inferior-octave-output-digest (_proc string) | ||
| 333 | "Special output filter for the inferior Octave process. | ||
| 334 | Save all output between newlines into `inferior-octave-output-list', and | ||
| 335 | the rest to `inferior-octave-output-string'." | ||
| 336 | (setq string (concat inferior-octave-output-string string)) | ||
| 337 | (while (string-match "\n" string) | ||
| 338 | (setq inferior-octave-output-list | ||
| 339 | (append inferior-octave-output-list | ||
| 340 | (list (substring string 0 (match-beginning 0)))) | ||
| 341 | string (substring string (match-end 0)))) | ||
| 342 | (if (string-match inferior-octave-prompt string) | ||
| 343 | (setq inferior-octave-receive-in-progress nil)) | ||
| 344 | (setq inferior-octave-output-string string)) | ||
| 345 | |||
| 346 | (defun inferior-octave-send-list-and-digest (list) | ||
| 347 | "Send LIST to the inferior Octave process and digest the output. | ||
| 348 | The elements of LIST have to be strings and are sent one by one. All | ||
| 349 | output is passed to the filter `inferior-octave-output-digest'." | ||
| 350 | (let* ((proc inferior-octave-process) | ||
| 351 | (filter (process-filter proc)) | ||
| 352 | string) | ||
| 353 | (set-process-filter proc 'inferior-octave-output-digest) | ||
| 354 | (setq inferior-octave-output-list nil) | ||
| 355 | (unwind-protect | ||
| 356 | (while (setq string (car list)) | ||
| 357 | (setq inferior-octave-output-string nil | ||
| 358 | inferior-octave-receive-in-progress t) | ||
| 359 | (comint-send-string proc string) | ||
| 360 | (while inferior-octave-receive-in-progress | ||
| 361 | (accept-process-output proc)) | ||
| 362 | (setq list (cdr list))) | ||
| 363 | (set-process-filter proc filter)))) | ||
| 364 | |||
| 365 | (defun inferior-octave-directory-tracker (string) | ||
| 366 | "Tracks `cd' commands issued to the inferior Octave process. | ||
| 367 | Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused." | ||
| 368 | (cond | ||
| 369 | ((string-match "^[ \t]*cd[ \t;]*$" string) | ||
| 370 | (cd "~")) | ||
| 371 | ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string) | ||
| 372 | (cd (substring string (match-beginning 1) (match-end 1)))))) | ||
| 373 | |||
| 374 | (defun inferior-octave-resync-dirs () | ||
| 375 | "Resync the buffer's idea of the current directory. | ||
| 376 | This command queries the inferior Octave process about its current | ||
| 377 | directory and makes this the current buffer's default directory." | ||
| 378 | (interactive) | ||
| 379 | (inferior-octave-send-list-and-digest '("disp (pwd ())\n")) | ||
| 380 | (cd (car inferior-octave-output-list))) | ||
| 381 | |||
| 382 | ;;; provide ourself | ||
| 383 | |||
| 384 | (provide 'octave-inf) | ||
| 385 | |||
| 386 | ;;; octave-inf.el ends here | ||
diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave-mod.el deleted file mode 100644 index 806afe5a537..00000000000 --- a/lisp/progmodes/octave-mod.el +++ /dev/null | |||
| @@ -1,1152 +0,0 @@ | |||
| 1 | ;;; octave-mod.el --- editing Octave source files under Emacs | ||
| 2 | |||
| 3 | ;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> | ||
| 6 | ;; John Eaton <jwe@octave.org> | ||
| 7 | ;; Maintainer: FSF | ||
| 8 | ;; Keywords: languages | ||
| 9 | |||
| 10 | ;; This file is part of GNU Emacs. | ||
| 11 | |||
| 12 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 13 | ;; it under the terms of the GNU General Public License as published by | ||
| 14 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 15 | ;; (at your option) any later version. | ||
| 16 | |||
| 17 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | ;; GNU General Public License for more details. | ||
| 21 | |||
| 22 | ;; You should have received a copy of the GNU General Public License | ||
| 23 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 24 | |||
| 25 | ;;; Commentary: | ||
| 26 | |||
| 27 | ;; This package provides Emacs support for Octave. | ||
| 28 | ;; It defines Octave mode, a major mode for editing | ||
| 29 | ;; Octave code. | ||
| 30 | |||
| 31 | ;; The file octave-inf.el contains code for interacting with an inferior | ||
| 32 | ;; Octave process using comint. | ||
| 33 | |||
| 34 | ;; See the documentation of `octave-mode' and | ||
| 35 | ;; `run-octave' for further information on usage and customization. | ||
| 36 | |||
| 37 | ;;; Code: | ||
| 38 | (require 'custom) | ||
| 39 | |||
| 40 | (defgroup octave nil | ||
| 41 | "Major mode for editing Octave source files." | ||
| 42 | :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) | ||
| 43 | :group 'languages) | ||
| 44 | |||
| 45 | (defvar inferior-octave-output-list nil) | ||
| 46 | (defvar inferior-octave-output-string nil) | ||
| 47 | (defvar inferior-octave-receive-in-progress nil) | ||
| 48 | |||
| 49 | (declare-function inferior-octave-send-list-and-digest "octave-inf" (list)) | ||
| 50 | |||
| 51 | (defconst octave-maintainer-address | ||
| 52 | "Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>, bug-gnu-emacs@gnu.org" | ||
| 53 | "Current maintainer of the Emacs Octave package.") | ||
| 54 | |||
| 55 | (define-abbrev-table 'octave-abbrev-table | ||
| 56 | (mapcar (lambda (e) (append e '(nil 0 t))) | ||
| 57 | '(("`a" "all_va_args") | ||
| 58 | ("`b" "break") | ||
| 59 | ("`cs" "case") | ||
| 60 | ("`ca" "catch") | ||
| 61 | ("`c" "continue") | ||
| 62 | ("`el" "else") | ||
| 63 | ("`eli" "elseif") | ||
| 64 | ("`et" "end_try_catch") | ||
| 65 | ("`eu" "end_unwind_protect") | ||
| 66 | ("`ef" "endfor") | ||
| 67 | ("`efu" "endfunction") | ||
| 68 | ("`ei" "endif") | ||
| 69 | ("`es" "endswitch") | ||
| 70 | ("`ew" "endwhile") | ||
| 71 | ("`f" "for") | ||
| 72 | ("`fu" "function") | ||
| 73 | ("`gl" "global") | ||
| 74 | ("`gp" "gplot") | ||
| 75 | ("`gs" "gsplot") | ||
| 76 | ("`if" "if ()") | ||
| 77 | ("`o" "otherwise") | ||
| 78 | ("`rp" "replot") | ||
| 79 | ("`r" "return") | ||
| 80 | ("`s" "switch") | ||
| 81 | ("`t" "try") | ||
| 82 | ("`u" "until ()") | ||
| 83 | ("`up" "unwind_protect") | ||
| 84 | ("`upc" "unwind_protect_cleanup") | ||
| 85 | ("`w" "while ()"))) | ||
| 86 | "Abbrev table for Octave's reserved words. | ||
| 87 | Used in `octave-mode' and inferior-octave-mode buffers. | ||
| 88 | All Octave abbrevs start with a grave accent (`)." | ||
| 89 | :regexp "\\(?:[^`]\\|^\\)\\(\\(?:\\<\\|`\\)\\w+\\)\\W*") | ||
| 90 | |||
| 91 | (defvar octave-comment-char ?# | ||
| 92 | "Character to start an Octave comment.") | ||
| 93 | (defvar octave-comment-start | ||
| 94 | (string octave-comment-char ?\s) | ||
| 95 | "String to insert to start a new Octave in-line comment.") | ||
| 96 | (defvar octave-comment-start-skip "\\s<+\\s-*" | ||
| 97 | "Regexp to match the start of an Octave comment up to its body.") | ||
| 98 | |||
| 99 | (defvar octave-begin-keywords | ||
| 100 | '("do" "for" "function" "if" "switch" "try" "unwind_protect" "while")) | ||
| 101 | (defvar octave-else-keywords | ||
| 102 | '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup")) | ||
| 103 | (defvar octave-end-keywords | ||
| 104 | '("endfor" "endfunction" "endif" "endswitch" "end_try_catch" | ||
| 105 | "end_unwind_protect" "endwhile" "until" "end")) | ||
| 106 | |||
| 107 | (defvar octave-reserved-words | ||
| 108 | (append octave-begin-keywords | ||
| 109 | octave-else-keywords | ||
| 110 | octave-end-keywords | ||
| 111 | '("break" "continue" "end" "global" "persistent" "return")) | ||
| 112 | "Reserved words in Octave.") | ||
| 113 | |||
| 114 | (defvar octave-text-functions | ||
| 115 | '("casesen" "cd" "chdir" "clear" "diary" "dir" "document" "echo" | ||
| 116 | "edit_history" "format" "help" "history" "hold" | ||
| 117 | "load" "ls" "more" "run_history" "save" "type" | ||
| 118 | "which" "who" "whos") | ||
| 119 | "Text functions in Octave.") | ||
| 120 | |||
| 121 | (defvar octave-variables | ||
| 122 | '("DEFAULT_EXEC_PATH" "DEFAULT_LOADPATH" | ||
| 123 | "EDITOR" "EXEC_PATH" "F_DUPFD" "F_GETFD" "F_GETFL" "F_SETFD" | ||
| 124 | "F_SETFL" "I" "IMAGE_PATH" "Inf" "J" | ||
| 125 | "NaN" "OCTAVE_VERSION" "O_APPEND" "O_CREAT" "O_EXCL" | ||
| 126 | "O_NONBLOCK" "O_RDONLY" "O_RDWR" "O_TRUNC" "O_WRONLY" "PAGER" "PS1" | ||
| 127 | "PS2" "PS4" "PWD" "SEEK_CUR" "SEEK_END" "SEEK_SET" "__F_DUPFD__" | ||
| 128 | "__F_GETFD__" "__F_GETFL__" "__F_SETFD__" "__F_SETFL__" "__I__" | ||
| 129 | "__Inf__" "__J__" "__NaN__" "__OCTAVE_VERSION__" "__O_APPEND__" | ||
| 130 | "__O_CREAT__" "__O_EXCL__" "__O_NONBLOCK__" "__O_RDONLY__" | ||
| 131 | "__O_RDWR__" "__O_TRUNC__" "__O_WRONLY__" "__PWD__" "__SEEK_CUR__" | ||
| 132 | "__SEEK_END__" "__SEEK_SET__" "__argv__" "__e__" "__eps__" | ||
| 133 | "__i__" "__inf__" "__j__" "__nan__" "__pi__" | ||
| 134 | "__program_invocation_name__" "__program_name__" "__realmax__" | ||
| 135 | "__realmin__" "__stderr__" "__stdin__" "__stdout__" "ans" "argv" | ||
| 136 | "beep_on_error" "completion_append_char" | ||
| 137 | "crash_dumps_octave_core" "default_save_format" | ||
| 138 | "e" "echo_executing_commands" "eps" | ||
| 139 | "error_text" "gnuplot_binary" "history_file" | ||
| 140 | "history_size" "ignore_function_time_stamp" | ||
| 141 | "inf" "nan" "nargin" "output_max_field_width" "output_precision" | ||
| 142 | "page_output_immediately" "page_screen_output" "pi" | ||
| 143 | "print_answer_id_name" "print_empty_dimensions" | ||
| 144 | "program_invocation_name" "program_name" | ||
| 145 | "realmax" "realmin" "return_last_computed_value" "save_precision" | ||
| 146 | "saving_history" "sighup_dumps_octave_core" "sigterm_dumps_octave_core" | ||
| 147 | "silent_functions" "split_long_rows" "stderr" "stdin" "stdout" | ||
| 148 | "string_fill_char" "struct_levels_to_print" | ||
| 149 | "suppress_verbose_help_message") | ||
| 150 | "Builtin variables in Octave.") | ||
| 151 | |||
| 152 | (defvar octave-function-header-regexp | ||
| 153 | (concat "^\\s-*\\_<\\(function\\)\\_>" | ||
| 154 | "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>") | ||
| 155 | "Regexp to match an Octave function header. | ||
| 156 | The string `function' and its name are given by the first and third | ||
| 157 | parenthetical grouping.") | ||
| 158 | |||
| 159 | (defvar octave-font-lock-keywords | ||
| 160 | (list | ||
| 161 | ;; Fontify all builtin keywords. | ||
| 162 | (cons (concat "\\_<\\(" | ||
| 163 | (regexp-opt (append octave-reserved-words | ||
| 164 | octave-text-functions)) | ||
| 165 | "\\)\\_>") | ||
| 166 | 'font-lock-keyword-face) | ||
| 167 | ;; Fontify all builtin operators. | ||
| 168 | (cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)" | ||
| 169 | (if (boundp 'font-lock-builtin-face) | ||
| 170 | 'font-lock-builtin-face | ||
| 171 | 'font-lock-preprocessor-face)) | ||
| 172 | ;; Fontify all builtin variables. | ||
| 173 | (cons (concat "\\_<" (regexp-opt octave-variables) "\\_>") | ||
| 174 | 'font-lock-variable-name-face) | ||
| 175 | ;; Fontify all function declarations. | ||
| 176 | (list octave-function-header-regexp | ||
| 177 | '(1 font-lock-keyword-face) | ||
| 178 | '(3 font-lock-function-name-face nil t))) | ||
| 179 | "Additional Octave expressions to highlight.") | ||
| 180 | |||
| 181 | (defun octave-syntax-propertize-function (start end) | ||
| 182 | (goto-char start) | ||
| 183 | (octave-syntax-propertize-sqs end) | ||
| 184 | (funcall (syntax-propertize-rules | ||
| 185 | ;; Try to distinguish the string-quotes from the transpose-quotes. | ||
| 186 | ("[[({,; ]\\('\\)" | ||
| 187 | (1 (prog1 "\"'" (octave-syntax-propertize-sqs end))))) | ||
| 188 | (point) end)) | ||
| 189 | |||
| 190 | (defun octave-syntax-propertize-sqs (end) | ||
| 191 | "Propertize the content/end of single-quote strings." | ||
| 192 | (when (eq (nth 3 (syntax-ppss)) ?\') | ||
| 193 | ;; A '..' string. | ||
| 194 | (when (re-search-forward | ||
| 195 | "\\(?:\\=\\|[^']\\)\\(?:''\\)*\\('\\)\\($\\|[^']\\)" end 'move) | ||
| 196 | (goto-char (match-beginning 2)) | ||
| 197 | (when (eq (char-before (match-beginning 1)) ?\\) | ||
| 198 | ;; Backslash cannot escape a single quote. | ||
| 199 | (put-text-property (1- (match-beginning 1)) (match-beginning 1) | ||
| 200 | 'syntax-table (string-to-syntax "."))) | ||
| 201 | (put-text-property (match-beginning 1) (match-end 1) | ||
| 202 | 'syntax-table (string-to-syntax "\"'"))))) | ||
| 203 | |||
| 204 | (defcustom inferior-octave-buffer "*Inferior Octave*" | ||
| 205 | "Name of buffer for running an inferior Octave process." | ||
| 206 | :type 'string | ||
| 207 | :group 'octave-inferior) | ||
| 208 | |||
| 209 | (defvar inferior-octave-process nil) | ||
| 210 | |||
| 211 | (defvar octave-mode-map | ||
| 212 | (let ((map (make-sparse-keymap))) | ||
| 213 | (define-key map "`" 'octave-abbrev-start) | ||
| 214 | (define-key map "\e\n" 'octave-indent-new-comment-line) | ||
| 215 | (define-key map "\M-\C-q" 'octave-indent-defun) | ||
| 216 | (define-key map "\C-c\C-b" 'octave-submit-bug-report) | ||
| 217 | (define-key map "\C-c\C-p" 'octave-previous-code-line) | ||
| 218 | (define-key map "\C-c\C-n" 'octave-next-code-line) | ||
| 219 | (define-key map "\C-c\C-a" 'octave-beginning-of-line) | ||
| 220 | (define-key map "\C-c\C-e" 'octave-end-of-line) | ||
| 221 | (define-key map [remap down-list] 'smie-down-list) | ||
| 222 | (define-key map "\C-c\M-\C-h" 'octave-mark-block) | ||
| 223 | (define-key map "\C-c]" 'smie-close-block) | ||
| 224 | (define-key map "\C-c/" 'smie-close-block) | ||
| 225 | (define-key map "\C-c\C-f" 'octave-insert-defun) | ||
| 226 | ;; FIXME: free C-h so it can do the describe-prefix-bindings. | ||
| 227 | (define-key map "\C-c\C-h" 'info-lookup-symbol) | ||
| 228 | (define-key map "\C-c\C-il" 'octave-send-line) | ||
| 229 | (define-key map "\C-c\C-ib" 'octave-send-block) | ||
| 230 | (define-key map "\C-c\C-if" 'octave-send-defun) | ||
| 231 | (define-key map "\C-c\C-ir" 'octave-send-region) | ||
| 232 | (define-key map "\C-c\C-is" 'octave-show-process-buffer) | ||
| 233 | (define-key map "\C-c\C-ih" 'octave-hide-process-buffer) | ||
| 234 | (define-key map "\C-c\C-ik" 'octave-kill-process) | ||
| 235 | (define-key map "\C-c\C-i\C-l" 'octave-send-line) | ||
| 236 | (define-key map "\C-c\C-i\C-b" 'octave-send-block) | ||
| 237 | (define-key map "\C-c\C-i\C-f" 'octave-send-defun) | ||
| 238 | (define-key map "\C-c\C-i\C-r" 'octave-send-region) | ||
| 239 | (define-key map "\C-c\C-i\C-s" 'octave-show-process-buffer) | ||
| 240 | ;; FIXME: free C-h so it can do the describe-prefix-bindings. | ||
| 241 | (define-key map "\C-c\C-i\C-h" 'octave-hide-process-buffer) | ||
| 242 | (define-key map "\C-c\C-i\C-k" 'octave-kill-process) | ||
| 243 | map) | ||
| 244 | "Keymap used in Octave mode.") | ||
| 245 | |||
| 246 | |||
| 247 | |||
| 248 | (easy-menu-define octave-mode-menu octave-mode-map | ||
| 249 | "Menu for Octave mode." | ||
| 250 | '("Octave" | ||
| 251 | ("Lines" | ||
| 252 | ["Previous Code Line" octave-previous-code-line t] | ||
| 253 | ["Next Code Line" octave-next-code-line t] | ||
| 254 | ["Begin of Continuation" octave-beginning-of-line t] | ||
| 255 | ["End of Continuation" octave-end-of-line t] | ||
| 256 | ["Split Line at Point" octave-indent-new-comment-line t]) | ||
| 257 | ("Blocks" | ||
| 258 | ["Mark Block" octave-mark-block t] | ||
| 259 | ["Close Block" smie-close-block t]) | ||
| 260 | ("Functions" | ||
| 261 | ["Indent Function" octave-indent-defun t] | ||
| 262 | ["Insert Function" octave-insert-defun t]) | ||
| 263 | "-" | ||
| 264 | ("Debug" | ||
| 265 | ["Send Current Line" octave-send-line t] | ||
| 266 | ["Send Current Block" octave-send-block t] | ||
| 267 | ["Send Current Function" octave-send-defun t] | ||
| 268 | ["Send Region" octave-send-region t] | ||
| 269 | ["Show Process Buffer" octave-show-process-buffer t] | ||
| 270 | ["Hide Process Buffer" octave-hide-process-buffer t] | ||
| 271 | ["Kill Process" octave-kill-process t]) | ||
| 272 | "-" | ||
| 273 | ["Indent Line" indent-according-to-mode t] | ||
| 274 | ["Complete Symbol" completion-at-point t] | ||
| 275 | "-" | ||
| 276 | ["Toggle Abbrev Mode" abbrev-mode | ||
| 277 | :style toggle :selected abbrev-mode] | ||
| 278 | ["Toggle Auto-Fill Mode" auto-fill-mode | ||
| 279 | :style toggle :selected auto-fill-function] | ||
| 280 | "-" | ||
| 281 | ["Submit Bug Report" octave-submit-bug-report t] | ||
| 282 | "-" | ||
| 283 | ["Describe Octave Mode" describe-mode t] | ||
| 284 | ["Lookup Octave Index" info-lookup-symbol t])) | ||
| 285 | |||
| 286 | (defvar octave-mode-syntax-table | ||
| 287 | (let ((table (make-syntax-table))) | ||
| 288 | (modify-syntax-entry ?\r " " table) | ||
| 289 | (modify-syntax-entry ?+ "." table) | ||
| 290 | (modify-syntax-entry ?- "." table) | ||
| 291 | (modify-syntax-entry ?= "." table) | ||
| 292 | (modify-syntax-entry ?* "." table) | ||
| 293 | (modify-syntax-entry ?/ "." table) | ||
| 294 | (modify-syntax-entry ?> "." table) | ||
| 295 | (modify-syntax-entry ?< "." table) | ||
| 296 | (modify-syntax-entry ?& "." table) | ||
| 297 | (modify-syntax-entry ?| "." table) | ||
| 298 | (modify-syntax-entry ?! "." table) | ||
| 299 | (modify-syntax-entry ?\\ "\\" table) | ||
| 300 | (modify-syntax-entry ?\' "." table) | ||
| 301 | ;; Was "w" for abbrevs, but now that it's not necessary any more, | ||
| 302 | (modify-syntax-entry ?\` "." table) | ||
| 303 | (modify-syntax-entry ?\" "\"" table) | ||
| 304 | (modify-syntax-entry ?. "_" table) | ||
| 305 | (modify-syntax-entry ?_ "_" table) | ||
| 306 | ;; The "b" flag only applies to the second letter of the comstart | ||
| 307 | ;; and the first letter of the comend, i.e. the "4b" below is ineffective. | ||
| 308 | ;; If we try to put `b' on the single-line comments, we get a similar | ||
| 309 | ;; problem where the % and # chars appear as first chars of the 2-char | ||
| 310 | ;; comend, so the multi-line ender is also turned into style-b. | ||
| 311 | ;; So we need the new "c" comment style. | ||
| 312 | (modify-syntax-entry ?\% "< 13" table) | ||
| 313 | (modify-syntax-entry ?\# "< 13" table) | ||
| 314 | (modify-syntax-entry ?\{ "(} 2c" table) | ||
| 315 | (modify-syntax-entry ?\} "){ 4c" table) | ||
| 316 | (modify-syntax-entry ?\n ">" table) | ||
| 317 | table) | ||
| 318 | "Syntax table in use in `octave-mode' buffers.") | ||
| 319 | |||
| 320 | (defcustom octave-blink-matching-block t | ||
| 321 | "Control the blinking of matching Octave block keywords. | ||
| 322 | Non-nil means show matching begin of block when inserting a space, | ||
| 323 | newline or semicolon after an else or end keyword." | ||
| 324 | :type 'boolean | ||
| 325 | :group 'octave) | ||
| 326 | |||
| 327 | (defcustom octave-block-offset 2 | ||
| 328 | "Extra indentation applied to statements in Octave block structures." | ||
| 329 | :type 'integer | ||
| 330 | :group 'octave) | ||
| 331 | |||
| 332 | (defvar octave-block-comment-start | ||
| 333 | (concat (make-string 2 octave-comment-char) " ") | ||
| 334 | "String to insert to start a new Octave comment on an empty line.") | ||
| 335 | |||
| 336 | (defcustom octave-continuation-offset 4 | ||
| 337 | "Extra indentation applied to Octave continuation lines." | ||
| 338 | :type 'integer | ||
| 339 | :group 'octave) | ||
| 340 | (eval-and-compile | ||
| 341 | (defconst octave-continuation-marker-regexp "\\\\\\|\\.\\.\\.")) | ||
| 342 | (defvar octave-continuation-regexp | ||
| 343 | (concat "[^#%\n]*\\(" octave-continuation-marker-regexp | ||
| 344 | "\\)\\s-*\\(\\s<.*\\)?$")) | ||
| 345 | (defcustom octave-continuation-string "\\" | ||
| 346 | "Character string used for Octave continuation lines. Normally \\." | ||
| 347 | :type 'string | ||
| 348 | :group 'octave) | ||
| 349 | |||
| 350 | (defvar octave-completion-alist nil | ||
| 351 | "Alist of Octave symbols for completion in Octave mode. | ||
| 352 | Each element looks like (VAR . VAR), where the car and cdr are the same | ||
| 353 | symbol (an Octave command or variable name). | ||
| 354 | Currently, only builtin variables can be completed.") | ||
| 355 | |||
| 356 | (defvar octave-mode-imenu-generic-expression | ||
| 357 | (list | ||
| 358 | ;; Functions | ||
| 359 | (list nil octave-function-header-regexp 3)) | ||
| 360 | "Imenu expression for Octave mode. See `imenu-generic-expression'.") | ||
| 361 | |||
| 362 | (defcustom octave-mode-hook nil | ||
| 363 | "Hook to be run when Octave mode is started." | ||
| 364 | :type 'hook | ||
| 365 | :group 'octave) | ||
| 366 | |||
| 367 | (defcustom octave-send-show-buffer t | ||
| 368 | "Non-nil means display `inferior-octave-buffer' after sending to it." | ||
| 369 | :type 'boolean | ||
| 370 | :group 'octave) | ||
| 371 | (defcustom octave-send-line-auto-forward t | ||
| 372 | "Control auto-forward after sending to the inferior Octave process. | ||
| 373 | Non-nil means always go to the next Octave code line after sending." | ||
| 374 | :type 'boolean | ||
| 375 | :group 'octave) | ||
| 376 | (defcustom octave-send-echo-input t | ||
| 377 | "Non-nil means echo input sent to the inferior Octave process." | ||
| 378 | :type 'boolean | ||
| 379 | :group 'octave) | ||
| 380 | |||
| 381 | |||
| 382 | ;;; SMIE indentation | ||
| 383 | |||
| 384 | (require 'smie) | ||
| 385 | |||
| 386 | (defconst octave-operator-table | ||
| 387 | '((assoc ";" "\n") (assoc ",") ; The doc claims they have equal precedence!? | ||
| 388 | (right "=" "+=" "-=" "*=" "/=") | ||
| 389 | (assoc "&&") (assoc "||") ; The doc claims they have equal precedence!? | ||
| 390 | (assoc "&") (assoc "|") ; The doc claims they have equal precedence!? | ||
| 391 | (nonassoc "<" "<=" "==" ">=" ">" "!=" "~=") | ||
| 392 | (nonassoc ":") ;No idea what this is. | ||
| 393 | (assoc "+" "-") | ||
| 394 | (assoc "*" "/" "\\" ".\\" ".*" "./") | ||
| 395 | (nonassoc "'" ".'") | ||
| 396 | (nonassoc "++" "--" "!" "~") ;And unary "+" and "-". | ||
| 397 | (right "^" "**" ".^" ".**") | ||
| 398 | ;; It's not really an operator, but for indentation purposes it | ||
| 399 | ;; could be convenient to treat it as one. | ||
| 400 | (assoc "..."))) | ||
| 401 | |||
| 402 | (defconst octave-smie-bnf-table | ||
| 403 | '((atom) | ||
| 404 | ;; We can't distinguish the first element in a sequence with | ||
| 405 | ;; precedence grammars, so we can't distinguish the condition | ||
| 406 | ;; if the `if' from the subsequent body, for example. | ||
| 407 | ;; This has to be done later in the indentation rules. | ||
| 408 | (exp (exp "\n" exp) | ||
| 409 | ;; We need to mention at least one of the operators in this part | ||
| 410 | ;; of the grammar: if the BNF and the operator table have | ||
| 411 | ;; no overlap, SMIE can't know how they relate. | ||
| 412 | (exp ";" exp) | ||
| 413 | ("try" exp "catch" exp "end_try_catch") | ||
| 414 | ("try" exp "catch" exp "end") | ||
| 415 | ("unwind_protect" exp | ||
| 416 | "unwind_protect_cleanup" exp "end_unwind_protect") | ||
| 417 | ("unwind_protect" exp "unwind_protect_cleanup" exp "end") | ||
| 418 | ("for" exp "endfor") | ||
| 419 | ("for" exp "end") | ||
| 420 | ("do" exp "until" atom) | ||
| 421 | ("while" exp "endwhile") | ||
| 422 | ("while" exp "end") | ||
| 423 | ("if" exp "endif") | ||
| 424 | ("if" exp "else" exp "endif") | ||
| 425 | ("if" exp "elseif" exp "else" exp "endif") | ||
| 426 | ("if" exp "elseif" exp "elseif" exp "else" exp "endif") | ||
| 427 | ("if" exp "elseif" exp "elseif" exp "else" exp "end") | ||
| 428 | ("switch" exp "case" exp "endswitch") | ||
| 429 | ("switch" exp "case" exp "otherwise" exp "endswitch") | ||
| 430 | ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch") | ||
| 431 | ("switch" exp "case" exp "case" exp "otherwise" exp "end") | ||
| 432 | ("function" exp "endfunction") | ||
| 433 | ("function" exp "end")) | ||
| 434 | ;; (fundesc (atom "=" atom)) | ||
| 435 | )) | ||
| 436 | |||
| 437 | (defconst octave-smie-grammar | ||
| 438 | (smie-prec2->grammar | ||
| 439 | (smie-merge-prec2s | ||
| 440 | (smie-bnf->prec2 octave-smie-bnf-table | ||
| 441 | '((assoc "\n" ";"))) | ||
| 442 | |||
| 443 | (smie-precs->prec2 octave-operator-table)))) | ||
| 444 | |||
| 445 | ;; Tokenizing needs to be refined so that ";;" is treated as two | ||
| 446 | ;; tokens and also so as to recognize the \n separator (and | ||
| 447 | ;; corresponding continuation lines). | ||
| 448 | |||
| 449 | (defconst octave-operator-regexp | ||
| 450 | (regexp-opt (apply 'append (mapcar 'cdr octave-operator-table)))) | ||
| 451 | |||
| 452 | (defun octave-smie-backward-token () | ||
| 453 | (let ((pos (point))) | ||
| 454 | (forward-comment (- (point))) | ||
| 455 | (cond | ||
| 456 | ((and (not (eq (char-before) ?\;)) ;Coalesce ";" and "\n". | ||
| 457 | (> pos (line-end-position)) | ||
| 458 | (if (looking-back octave-continuation-marker-regexp (- (point) 3)) | ||
| 459 | (progn | ||
| 460 | (goto-char (match-beginning 0)) | ||
| 461 | (forward-comment (- (point))) | ||
| 462 | nil) | ||
| 463 | t) | ||
| 464 | ;; Ignore it if it's within parentheses. | ||
| 465 | (let ((ppss (syntax-ppss))) | ||
| 466 | (not (and (nth 1 ppss) | ||
| 467 | (eq ?\( (char-after (nth 1 ppss))))))) | ||
| 468 | (skip-chars-forward " \t") | ||
| 469 | ;; Why bother distinguishing \n and ;? | ||
| 470 | ";") ;;"\n" | ||
| 471 | ((and (looking-back octave-operator-regexp (- (point) 3) 'greedy) | ||
| 472 | ;; Don't mistake a string quote for a transpose. | ||
| 473 | (not (looking-back "\\s\"" (1- (point))))) | ||
| 474 | (goto-char (match-beginning 0)) | ||
| 475 | (match-string-no-properties 0)) | ||
| 476 | (t | ||
| 477 | (smie-default-backward-token))))) | ||
| 478 | |||
| 479 | (defun octave-smie-forward-token () | ||
| 480 | (skip-chars-forward " \t") | ||
| 481 | (when (looking-at (eval-when-compile | ||
| 482 | (concat "\\(" octave-continuation-marker-regexp | ||
| 483 | "\\)[ \t]*\\($\\|[%#]\\)"))) | ||
| 484 | (goto-char (match-end 1)) | ||
| 485 | (forward-comment 1)) | ||
| 486 | (cond | ||
| 487 | ((and (looking-at "$\\|[%#]") | ||
| 488 | ;; Ignore it if it's within parentheses. | ||
| 489 | (prog1 (let ((ppss (syntax-ppss))) | ||
| 490 | (not (and (nth 1 ppss) | ||
| 491 | (eq ?\( (char-after (nth 1 ppss)))))) | ||
| 492 | (forward-comment (point-max)))) | ||
| 493 | ;; Why bother distinguishing \n and ;? | ||
| 494 | ";") ;;"\n" | ||
| 495 | ((looking-at ";[ \t]*\\($\\|[%#]\\)") | ||
| 496 | ;; Combine the ; with the subsequent \n. | ||
| 497 | (goto-char (match-beginning 1)) | ||
| 498 | (forward-comment 1) | ||
| 499 | ";") | ||
| 500 | ((and (looking-at octave-operator-regexp) | ||
| 501 | ;; Don't mistake a string quote for a transpose. | ||
| 502 | (not (looking-at "\\s\""))) | ||
| 503 | (goto-char (match-end 0)) | ||
| 504 | (match-string-no-properties 0)) | ||
| 505 | (t | ||
| 506 | (smie-default-forward-token)))) | ||
| 507 | |||
| 508 | (defun octave-smie-rules (kind token) | ||
| 509 | (pcase (cons kind token) | ||
| 510 | ;; We could set smie-indent-basic instead, but that would have two | ||
| 511 | ;; disadvantages: | ||
| 512 | ;; - changes to octave-block-offset wouldn't take effect immediately. | ||
| 513 | ;; - edebug wouldn't show the use of this variable. | ||
| 514 | (`(:elem . basic) octave-block-offset) | ||
| 515 | ;; Since "case" is in the same BNF rules as switch..end, SMIE by default | ||
| 516 | ;; aligns it with "switch". | ||
| 517 | (`(:before . "case") (if (not (smie-rule-sibling-p)) octave-block-offset)) | ||
| 518 | (`(:after . ";") | ||
| 519 | (if (smie-rule-parent-p "function" "if" "while" "else" "elseif" "for" | ||
| 520 | "otherwise" "case" "try" "catch" "unwind_protect" | ||
| 521 | "unwind_protect_cleanup") | ||
| 522 | (smie-rule-parent octave-block-offset) | ||
| 523 | ;; For (invalid) code between switch and case. | ||
| 524 | ;; (if (smie-parent-p "switch") 4) | ||
| 525 | 0)))) | ||
| 526 | |||
| 527 | (defvar electric-layout-rules) | ||
| 528 | |||
| 529 | ;;;###autoload | ||
| 530 | (define-derived-mode octave-mode prog-mode "Octave" | ||
| 531 | "Major mode for editing Octave code. | ||
| 532 | |||
| 533 | This mode makes it easier to write Octave code by helping with | ||
| 534 | indentation, doing some of the typing for you (with Abbrev mode) and by | ||
| 535 | showing keywords, comments, strings, etc. in different faces (with | ||
| 536 | Font Lock mode on terminals that support it). | ||
| 537 | |||
| 538 | Octave itself is a high-level language, primarily intended for numerical | ||
| 539 | computations. It provides a convenient command line interface for | ||
| 540 | solving linear and nonlinear problems numerically. Function definitions | ||
| 541 | can also be stored in files, and it can be used in a batch mode (which | ||
| 542 | is why you need this mode!). | ||
| 543 | |||
| 544 | The latest released version of Octave is always available via anonymous | ||
| 545 | ftp from ftp.octave.org in the directory `/pub/octave'. Complete | ||
| 546 | source and binaries for several popular systems are available. | ||
| 547 | |||
| 548 | Type \\[list-abbrevs] to display the built-in abbrevs for Octave keywords. | ||
| 549 | |||
| 550 | Keybindings | ||
| 551 | =========== | ||
| 552 | |||
| 553 | \\{octave-mode-map} | ||
| 554 | |||
| 555 | Variables you can use to customize Octave mode | ||
| 556 | ============================================== | ||
| 557 | |||
| 558 | `octave-blink-matching-block' | ||
| 559 | Non-nil means show matching begin of block when inserting a space, | ||
| 560 | newline or semicolon after an else or end keyword. Default is t. | ||
| 561 | |||
| 562 | `octave-block-offset' | ||
| 563 | Extra indentation applied to statements in block structures. | ||
| 564 | Default is 2. | ||
| 565 | |||
| 566 | `octave-continuation-offset' | ||
| 567 | Extra indentation applied to Octave continuation lines. | ||
| 568 | Default is 4. | ||
| 569 | |||
| 570 | `octave-continuation-string' | ||
| 571 | String used for Octave continuation lines. | ||
| 572 | Default is a backslash. | ||
| 573 | |||
| 574 | `octave-send-echo-input' | ||
| 575 | Non-nil means always display `inferior-octave-buffer' after sending a | ||
| 576 | command to the inferior Octave process. | ||
| 577 | |||
| 578 | `octave-send-line-auto-forward' | ||
| 579 | Non-nil means always go to the next unsent line of Octave code after | ||
| 580 | sending a line to the inferior Octave process. | ||
| 581 | |||
| 582 | `octave-send-echo-input' | ||
| 583 | Non-nil means echo input sent to the inferior Octave process. | ||
| 584 | |||
| 585 | Turning on Octave mode runs the hook `octave-mode-hook'. | ||
| 586 | |||
| 587 | To begin using this mode for all `.m' files that you edit, add the | ||
| 588 | following lines to your init file: | ||
| 589 | |||
| 590 | (add-to-list 'auto-mode-alist '(\"\\\\.m\\\\'\" . octave-mode)) | ||
| 591 | |||
| 592 | To automatically turn on the abbrev and auto-fill features, | ||
| 593 | add the following lines to your init file as well: | ||
| 594 | |||
| 595 | (add-hook 'octave-mode-hook | ||
| 596 | (lambda () | ||
| 597 | (abbrev-mode 1) | ||
| 598 | (auto-fill-mode 1))) | ||
| 599 | |||
| 600 | To submit a problem report, enter \\[octave-submit-bug-report] from \ | ||
| 601 | an Octave mode buffer. | ||
| 602 | This automatically sets up a mail buffer with version information | ||
| 603 | already added. You just need to add a description of the problem, | ||
| 604 | including a reproducible test case and send the message." | ||
| 605 | (setq local-abbrev-table octave-abbrev-table) | ||
| 606 | |||
| 607 | (smie-setup octave-smie-grammar #'octave-smie-rules | ||
| 608 | :forward-token #'octave-smie-forward-token | ||
| 609 | :backward-token #'octave-smie-backward-token) | ||
| 610 | (set (make-local-variable 'smie-indent-basic) 'octave-block-offset) | ||
| 611 | |||
| 612 | (set (make-local-variable 'smie-blink-matching-triggers) | ||
| 613 | (cons ?\; smie-blink-matching-triggers)) | ||
| 614 | (unless octave-blink-matching-block | ||
| 615 | (remove-hook 'post-self-insert-hook #'smie-blink-matching-open 'local)) | ||
| 616 | |||
| 617 | (set (make-local-variable 'electric-indent-chars) | ||
| 618 | (cons ?\; electric-indent-chars)) | ||
| 619 | ;; IIUC matlab-mode takes the opposite approach: it makes RET insert | ||
| 620 | ;; a ";" at those places where it's correct (i.e. outside of parens). | ||
| 621 | (set (make-local-variable 'electric-layout-rules) '((?\; . after))) | ||
| 622 | |||
| 623 | (set (make-local-variable 'comment-start) octave-comment-start) | ||
| 624 | (set (make-local-variable 'comment-end) "") | ||
| 625 | ;; Don't set it here: it's not really a property of the language, | ||
| 626 | ;; just a personal preference of the author. | ||
| 627 | ;; (set (make-local-variable 'comment-column) 32) | ||
| 628 | (set (make-local-variable 'comment-start-skip) "\\s<+\\s-*") | ||
| 629 | (set (make-local-variable 'comment-add) 1) | ||
| 630 | |||
| 631 | (set (make-local-variable 'parse-sexp-ignore-comments) t) | ||
| 632 | (set (make-local-variable 'paragraph-start) | ||
| 633 | (concat "\\s-*$\\|" page-delimiter)) | ||
| 634 | (set (make-local-variable 'paragraph-separate) paragraph-start) | ||
| 635 | (set (make-local-variable 'paragraph-ignore-fill-prefix) t) | ||
| 636 | (set (make-local-variable 'fill-paragraph-function) 'octave-fill-paragraph) | ||
| 637 | ;; FIXME: Why disable it? | ||
| 638 | ;; (set (make-local-variable 'adaptive-fill-regexp) nil) | ||
| 639 | ;; Again, this is not a property of the language, don't set it here. | ||
| 640 | ;; (set (make-local-variable 'fill-column) 72) | ||
| 641 | (set (make-local-variable 'normal-auto-fill-function) 'octave-auto-fill) | ||
| 642 | |||
| 643 | (set (make-local-variable 'font-lock-defaults) | ||
| 644 | '(octave-font-lock-keywords)) | ||
| 645 | |||
| 646 | (set (make-local-variable 'syntax-propertize-function) | ||
| 647 | #'octave-syntax-propertize-function) | ||
| 648 | |||
| 649 | (set (make-local-variable 'imenu-generic-expression) | ||
| 650 | octave-mode-imenu-generic-expression) | ||
| 651 | (set (make-local-variable 'imenu-case-fold-search) nil) | ||
| 652 | |||
| 653 | (add-hook 'completion-at-point-functions | ||
| 654 | 'octave-completion-at-point-function nil t) | ||
| 655 | (set (make-local-variable 'beginning-of-defun-function) | ||
| 656 | 'octave-beginning-of-defun) | ||
| 657 | |||
| 658 | (easy-menu-add octave-mode-menu) | ||
| 659 | (octave-initialize-completions)) | ||
| 660 | |||
| 661 | ;;; Miscellaneous useful functions | ||
| 662 | |||
| 663 | (defsubst octave-in-comment-p () | ||
| 664 | "Return t if point is inside an Octave comment." | ||
| 665 | (nth 4 (syntax-ppss))) | ||
| 666 | |||
| 667 | (defsubst octave-in-string-p () | ||
| 668 | "Return t if point is inside an Octave string." | ||
| 669 | (nth 3 (syntax-ppss))) | ||
| 670 | |||
| 671 | (defsubst octave-not-in-string-or-comment-p () | ||
| 672 | "Return t if point is not inside an Octave string or comment." | ||
| 673 | (let ((pps (syntax-ppss))) | ||
| 674 | (not (or (nth 3 pps) (nth 4 pps))))) | ||
| 675 | |||
| 676 | |||
| 677 | (defun octave-looking-at-kw (regexp) | ||
| 678 | "Like `looking-at', but sets `case-fold-search' nil." | ||
| 679 | (let ((case-fold-search nil)) | ||
| 680 | (looking-at regexp))) | ||
| 681 | |||
| 682 | (defun octave-maybe-insert-continuation-string () | ||
| 683 | (if (or (octave-in-comment-p) | ||
| 684 | (save-excursion | ||
| 685 | (beginning-of-line) | ||
| 686 | (looking-at octave-continuation-regexp))) | ||
| 687 | nil | ||
| 688 | (delete-horizontal-space) | ||
| 689 | (insert (concat " " octave-continuation-string)))) | ||
| 690 | |||
| 691 | ;;; Indentation | ||
| 692 | |||
| 693 | (defun octave-indent-new-comment-line () | ||
| 694 | "Break Octave line at point, continuing comment if within one. | ||
| 695 | If within code, insert `octave-continuation-string' before breaking the | ||
| 696 | line. If within a string, signal an error. | ||
| 697 | The new line is properly indented." | ||
| 698 | (interactive) | ||
| 699 | (delete-horizontal-space) | ||
| 700 | (cond | ||
| 701 | ((octave-in-comment-p) | ||
| 702 | (indent-new-comment-line)) | ||
| 703 | ((octave-in-string-p) | ||
| 704 | (error "Cannot split a code line inside a string")) | ||
| 705 | (t | ||
| 706 | (insert (concat " " octave-continuation-string)) | ||
| 707 | (reindent-then-newline-and-indent)))) | ||
| 708 | |||
| 709 | (defun octave-indent-defun () | ||
| 710 | "Properly indent the Octave function which contains point." | ||
| 711 | (interactive) | ||
| 712 | (save-excursion | ||
| 713 | (mark-defun) | ||
| 714 | (message "Indenting function...") | ||
| 715 | (indent-region (point) (mark) nil)) | ||
| 716 | (message "Indenting function...done.")) | ||
| 717 | |||
| 718 | |||
| 719 | ;;; Motion | ||
| 720 | (defun octave-next-code-line (&optional arg) | ||
| 721 | "Move ARG lines of Octave code forward (backward if ARG is negative). | ||
| 722 | Skips past all empty and comment lines. Default for ARG is 1. | ||
| 723 | |||
| 724 | On success, return 0. Otherwise, go as far as possible and return -1." | ||
| 725 | (interactive "p") | ||
| 726 | (or arg (setq arg 1)) | ||
| 727 | (beginning-of-line) | ||
| 728 | (let ((n 0) | ||
| 729 | (inc (if (> arg 0) 1 -1))) | ||
| 730 | (while (and (/= arg 0) (= n 0)) | ||
| 731 | (setq n (forward-line inc)) | ||
| 732 | (while (and (= n 0) | ||
| 733 | (looking-at "\\s-*\\($\\|\\s<\\)")) | ||
| 734 | (setq n (forward-line inc))) | ||
| 735 | (setq arg (- arg inc))) | ||
| 736 | n)) | ||
| 737 | |||
| 738 | (defun octave-previous-code-line (&optional arg) | ||
| 739 | "Move ARG lines of Octave code backward (forward if ARG is negative). | ||
| 740 | Skips past all empty and comment lines. Default for ARG is 1. | ||
| 741 | |||
| 742 | On success, return 0. Otherwise, go as far as possible and return -1." | ||
| 743 | (interactive "p") | ||
| 744 | (or arg (setq arg 1)) | ||
| 745 | (octave-next-code-line (- arg))) | ||
| 746 | |||
| 747 | (defun octave-beginning-of-line () | ||
| 748 | "Move point to beginning of current Octave line. | ||
| 749 | If on an empty or comment line, go to the beginning of that line. | ||
| 750 | Otherwise, move backward to the beginning of the first Octave code line | ||
| 751 | which is not inside a continuation statement, i.e., which does not | ||
| 752 | follow a code line ending in `...' or `\\', or is inside an open | ||
| 753 | parenthesis list." | ||
| 754 | (interactive) | ||
| 755 | (beginning-of-line) | ||
| 756 | (if (not (looking-at "\\s-*\\($\\|\\s<\\)")) | ||
| 757 | (while (or (condition-case nil | ||
| 758 | (progn | ||
| 759 | (up-list -1) | ||
| 760 | (beginning-of-line) | ||
| 761 | t) | ||
| 762 | (error nil)) | ||
| 763 | (and (or (looking-at "\\s-*\\($\\|\\s<\\)") | ||
| 764 | (save-excursion | ||
| 765 | (if (zerop (octave-previous-code-line)) | ||
| 766 | (looking-at octave-continuation-regexp)))) | ||
| 767 | (zerop (forward-line -1))))))) | ||
| 768 | |||
| 769 | (defun octave-end-of-line () | ||
| 770 | "Move point to end of current Octave line. | ||
| 771 | If on an empty or comment line, go to the end of that line. | ||
| 772 | Otherwise, move forward to the end of the first Octave code line which | ||
| 773 | does not end in `...' or `\\' or is inside an open parenthesis list." | ||
| 774 | (interactive) | ||
| 775 | (end-of-line) | ||
| 776 | (if (save-excursion | ||
| 777 | (beginning-of-line) | ||
| 778 | (looking-at "\\s-*\\($\\|\\s<\\)")) | ||
| 779 | () | ||
| 780 | (while (or (condition-case nil | ||
| 781 | (progn | ||
| 782 | (up-list 1) | ||
| 783 | (end-of-line) | ||
| 784 | t) | ||
| 785 | (error nil)) | ||
| 786 | (and (save-excursion | ||
| 787 | (beginning-of-line) | ||
| 788 | (or (looking-at "\\s-*\\($\\|\\s<\\)") | ||
| 789 | (looking-at octave-continuation-regexp))) | ||
| 790 | (zerop (forward-line 1))))) | ||
| 791 | (end-of-line))) | ||
| 792 | |||
| 793 | (defun octave-mark-block () | ||
| 794 | "Put point at the beginning of this Octave block, mark at the end. | ||
| 795 | The block marked is the one that contains point or follows point." | ||
| 796 | (interactive) | ||
| 797 | (if (and (looking-at "\\sw\\|\\s_") | ||
| 798 | (looking-back "\\sw\\|\\s_" (1- (point)))) | ||
| 799 | (skip-syntax-forward "w_")) | ||
| 800 | (unless (or (looking-at "\\s(") | ||
| 801 | (save-excursion | ||
| 802 | (let* ((token (funcall smie-forward-token-function)) | ||
| 803 | (level (assoc token smie-grammar))) | ||
| 804 | (and level (not (numberp (cadr level))))))) | ||
| 805 | (backward-up-list 1)) | ||
| 806 | (mark-sexp)) | ||
| 807 | |||
| 808 | (defun octave-beginning-of-defun (&optional arg) | ||
| 809 | "Move backward to the beginning of an Octave function. | ||
| 810 | With positive ARG, do it that many times. Negative argument -N means | ||
| 811 | move forward to Nth following beginning of a function. | ||
| 812 | Returns t unless search stops at the beginning or end of the buffer." | ||
| 813 | (let* ((arg (or arg 1)) | ||
| 814 | (inc (if (> arg 0) 1 -1)) | ||
| 815 | (found nil) | ||
| 816 | (case-fold-search nil)) | ||
| 817 | (and (not (eobp)) | ||
| 818 | (not (and (> arg 0) (looking-at "\\_<function\\_>"))) | ||
| 819 | (skip-syntax-forward "w")) | ||
| 820 | (while (and (/= arg 0) | ||
| 821 | (setq found | ||
| 822 | (re-search-backward "\\_<function\\_>" inc))) | ||
| 823 | (if (octave-not-in-string-or-comment-p) | ||
| 824 | (setq arg (- arg inc)))) | ||
| 825 | (if found | ||
| 826 | (progn | ||
| 827 | (and (< inc 0) (goto-char (match-beginning 0))) | ||
| 828 | t)))) | ||
| 829 | |||
| 830 | |||
| 831 | ;;; Filling | ||
| 832 | (defun octave-auto-fill () | ||
| 833 | "Perform auto-fill in Octave mode. | ||
| 834 | Returns nil if no feasible place to break the line could be found, and t | ||
| 835 | otherwise." | ||
| 836 | (let (fc give-up) | ||
| 837 | (if (or (null (setq fc (current-fill-column))) | ||
| 838 | (save-excursion | ||
| 839 | (beginning-of-line) | ||
| 840 | (and auto-fill-inhibit-regexp | ||
| 841 | (octave-looking-at-kw auto-fill-inhibit-regexp)))) | ||
| 842 | nil ; Can't do anything | ||
| 843 | (if (and (not (octave-in-comment-p)) | ||
| 844 | (> (current-column) fc)) | ||
| 845 | (setq fc (- fc (+ (length octave-continuation-string) 1)))) | ||
| 846 | (while (and (not give-up) (> (current-column) fc)) | ||
| 847 | (let* ((opoint (point)) | ||
| 848 | (fpoint | ||
| 849 | (save-excursion | ||
| 850 | (move-to-column (+ fc 1)) | ||
| 851 | (skip-chars-backward "^ \t\n") | ||
| 852 | ;; If we're at the beginning of the line, break after | ||
| 853 | ;; the first word | ||
| 854 | (if (bolp) | ||
| 855 | (re-search-forward "[ \t]" opoint t)) | ||
| 856 | ;; If we're in a comment line, don't break after the | ||
| 857 | ;; comment chars | ||
| 858 | (if (save-excursion | ||
| 859 | (skip-syntax-backward " <") | ||
| 860 | (bolp)) | ||
| 861 | (re-search-forward "[ \t]" (line-end-position) | ||
| 862 | 'move)) | ||
| 863 | ;; If we're not in a comment line and just ahead the | ||
| 864 | ;; continuation string, don't break here. | ||
| 865 | (if (and (not (octave-in-comment-p)) | ||
| 866 | (looking-at | ||
| 867 | (concat "\\s-*" | ||
| 868 | (regexp-quote | ||
| 869 | octave-continuation-string) | ||
| 870 | "\\s-*$"))) | ||
| 871 | (end-of-line)) | ||
| 872 | (skip-chars-backward " \t") | ||
| 873 | (point)))) | ||
| 874 | (if (save-excursion | ||
| 875 | (goto-char fpoint) | ||
| 876 | (not (or (bolp) (eolp)))) | ||
| 877 | (let ((prev-column (current-column))) | ||
| 878 | (if (save-excursion | ||
| 879 | (skip-chars-backward " \t") | ||
| 880 | (= (point) fpoint)) | ||
| 881 | (progn | ||
| 882 | (octave-maybe-insert-continuation-string) | ||
| 883 | (indent-new-comment-line t)) | ||
| 884 | (save-excursion | ||
| 885 | (goto-char fpoint) | ||
| 886 | (octave-maybe-insert-continuation-string) | ||
| 887 | (indent-new-comment-line t))) | ||
| 888 | (if (>= (current-column) prev-column) | ||
| 889 | (setq give-up t))) | ||
| 890 | (setq give-up t)))) | ||
| 891 | (not give-up)))) | ||
| 892 | |||
| 893 | (defun octave-fill-paragraph (&optional _arg) | ||
| 894 | "Fill paragraph of Octave code, handling Octave comments." | ||
| 895 | ;; FIXME: difference with generic fill-paragraph: | ||
| 896 | ;; - code lines are only split, never joined. | ||
| 897 | ;; - \n that end comments are never removed. | ||
| 898 | ;; - insert continuation marker when splitting code lines. | ||
| 899 | (interactive "P") | ||
| 900 | (save-excursion | ||
| 901 | (let ((end (progn (forward-paragraph) (copy-marker (point) t))) | ||
| 902 | (beg (progn | ||
| 903 | (forward-paragraph -1) | ||
| 904 | (skip-chars-forward " \t\n") | ||
| 905 | (beginning-of-line) | ||
| 906 | (point))) | ||
| 907 | (cfc (current-fill-column)) | ||
| 908 | comment-prefix) | ||
| 909 | (goto-char beg) | ||
| 910 | (while (< (point) end) | ||
| 911 | (condition-case nil | ||
| 912 | (indent-according-to-mode) | ||
| 913 | (error nil)) | ||
| 914 | (move-to-column cfc) | ||
| 915 | ;; First check whether we need to combine non-empty comment lines | ||
| 916 | (if (and (< (current-column) cfc) | ||
| 917 | (octave-in-comment-p) | ||
| 918 | (not (save-excursion | ||
| 919 | (beginning-of-line) | ||
| 920 | (looking-at "^\\s-*\\s<+\\s-*$")))) | ||
| 921 | ;; This is a nonempty comment line which does not extend | ||
| 922 | ;; past the fill column. If it is followed by a nonempty | ||
| 923 | ;; comment line with the same comment prefix, try to | ||
| 924 | ;; combine them, and repeat this until either we reach the | ||
| 925 | ;; fill-column or there is nothing more to combine. | ||
| 926 | (progn | ||
| 927 | ;; Get the comment prefix | ||
| 928 | (save-excursion | ||
| 929 | (beginning-of-line) | ||
| 930 | (while (and (re-search-forward "\\s<+") | ||
| 931 | (not (octave-in-comment-p)))) | ||
| 932 | (setq comment-prefix (match-string 0))) | ||
| 933 | ;; And keep combining ... | ||
| 934 | (while (and (< (current-column) cfc) | ||
| 935 | (save-excursion | ||
| 936 | (forward-line 1) | ||
| 937 | (and (looking-at | ||
| 938 | (concat "^\\s-*" | ||
| 939 | comment-prefix | ||
| 940 | "\\S<")) | ||
| 941 | (not (looking-at | ||
| 942 | (concat "^\\s-*" | ||
| 943 | comment-prefix | ||
| 944 | "\\s-*$")))))) | ||
| 945 | (delete-char 1) | ||
| 946 | (re-search-forward comment-prefix) | ||
| 947 | (delete-region (match-beginning 0) (match-end 0)) | ||
| 948 | (fixup-whitespace) | ||
| 949 | (move-to-column cfc)))) | ||
| 950 | ;; We might also try to combine continued code lines> Perhaps | ||
| 951 | ;; some other time ... | ||
| 952 | (skip-chars-forward "^ \t\n") | ||
| 953 | (delete-horizontal-space) | ||
| 954 | (if (or (< (current-column) cfc) | ||
| 955 | (and (= (current-column) cfc) (eolp))) | ||
| 956 | (forward-line 1) | ||
| 957 | (if (not (eolp)) (insert " ")) | ||
| 958 | (or (octave-auto-fill) | ||
| 959 | (forward-line 1)))) | ||
| 960 | t))) | ||
| 961 | |||
| 962 | |||
| 963 | ;;; Completions | ||
| 964 | (defun octave-initialize-completions () | ||
| 965 | "Create an alist for Octave completions." | ||
| 966 | (if octave-completion-alist | ||
| 967 | () | ||
| 968 | (setq octave-completion-alist | ||
| 969 | (append octave-reserved-words | ||
| 970 | octave-text-functions | ||
| 971 | octave-variables)))) | ||
| 972 | |||
| 973 | (defun octave-completion-at-point-function () | ||
| 974 | "Find the text to complete and the corresponding table." | ||
| 975 | (let* ((beg (save-excursion (skip-syntax-backward "w_") (point))) | ||
| 976 | (end (point))) | ||
| 977 | (if (< beg (point)) | ||
| 978 | ;; Extend region past point, if applicable. | ||
| 979 | (save-excursion (skip-syntax-forward "w_") | ||
| 980 | (setq end (point)))) | ||
| 981 | (list beg end octave-completion-alist))) | ||
| 982 | |||
| 983 | (define-obsolete-function-alias 'octave-complete-symbol | ||
| 984 | 'completion-at-point "24.1") | ||
| 985 | |||
| 986 | ;;; Electric characters && friends | ||
| 987 | |||
| 988 | (defun octave-abbrev-start () | ||
| 989 | "Start entering an Octave abbreviation. | ||
| 990 | If Abbrev mode is turned on, typing ` (grave accent) followed by ? or | ||
| 991 | \\[help-command] lists all Octave abbrevs. Any other key combination is | ||
| 992 | executed normally. | ||
| 993 | Note that all Octave mode abbrevs start with a grave accent." | ||
| 994 | (interactive) | ||
| 995 | (self-insert-command 1) | ||
| 996 | (when abbrev-mode | ||
| 997 | (set-temporary-overlay-map | ||
| 998 | (let ((map (make-sparse-keymap))) | ||
| 999 | (define-key map [??] 'list-abbrevs) | ||
| 1000 | (define-key map (vector help-char) 'list-abbrevs) | ||
| 1001 | map)))) | ||
| 1002 | |||
| 1003 | (define-skeleton octave-insert-defun | ||
| 1004 | "Insert an Octave function skeleton. | ||
| 1005 | Prompt for the function's name, arguments and return values (to be | ||
| 1006 | entered without parens)." | ||
| 1007 | (let* ((defname (substring (buffer-name) 0 -2)) | ||
| 1008 | (name (read-string (format "Function name (default %s): " defname) | ||
| 1009 | nil nil defname)) | ||
| 1010 | (args (read-string "Arguments: ")) | ||
| 1011 | (vals (read-string "Return values: "))) | ||
| 1012 | (format "%s%s (%s)" | ||
| 1013 | (cond | ||
| 1014 | ((string-equal vals "") vals) | ||
| 1015 | ((string-match "[ ,]" vals) (concat "[" vals "] = ")) | ||
| 1016 | (t (concat vals " = "))) | ||
| 1017 | name | ||
| 1018 | args)) | ||
| 1019 | \n "function " > str \n \n | ||
| 1020 | octave-block-comment-start "usage: " str \n | ||
| 1021 | octave-block-comment-start \n octave-block-comment-start | ||
| 1022 | \n _ \n | ||
| 1023 | "endfunction" > \n) | ||
| 1024 | |||
| 1025 | ;;; Communication with the inferior Octave process | ||
| 1026 | (defun octave-kill-process () | ||
| 1027 | "Kill inferior Octave process and its buffer." | ||
| 1028 | (interactive) | ||
| 1029 | (if inferior-octave-process | ||
| 1030 | (progn | ||
| 1031 | (process-send-string inferior-octave-process "quit;\n") | ||
| 1032 | (accept-process-output inferior-octave-process))) | ||
| 1033 | (if inferior-octave-buffer | ||
| 1034 | (kill-buffer inferior-octave-buffer))) | ||
| 1035 | |||
| 1036 | (defun octave-show-process-buffer () | ||
| 1037 | "Make sure that `inferior-octave-buffer' is displayed." | ||
| 1038 | (interactive) | ||
| 1039 | (if (get-buffer inferior-octave-buffer) | ||
| 1040 | (display-buffer inferior-octave-buffer) | ||
| 1041 | (message "No buffer named %s" inferior-octave-buffer))) | ||
| 1042 | |||
| 1043 | (defun octave-hide-process-buffer () | ||
| 1044 | "Delete all windows that display `inferior-octave-buffer'." | ||
| 1045 | (interactive) | ||
| 1046 | (if (get-buffer inferior-octave-buffer) | ||
| 1047 | (delete-windows-on inferior-octave-buffer) | ||
| 1048 | (message "No buffer named %s" inferior-octave-buffer))) | ||
| 1049 | |||
| 1050 | (defun octave-send-region (beg end) | ||
| 1051 | "Send current region to the inferior Octave process." | ||
| 1052 | (interactive "r") | ||
| 1053 | (inferior-octave t) | ||
| 1054 | (let ((proc inferior-octave-process) | ||
| 1055 | (string (buffer-substring-no-properties beg end)) | ||
| 1056 | line) | ||
| 1057 | (with-current-buffer inferior-octave-buffer | ||
| 1058 | (setq inferior-octave-output-list nil) | ||
| 1059 | (while (not (string-equal string "")) | ||
| 1060 | (if (string-match "\n" string) | ||
| 1061 | (setq line (substring string 0 (match-beginning 0)) | ||
| 1062 | string (substring string (match-end 0))) | ||
| 1063 | (setq line string string "")) | ||
| 1064 | (setq inferior-octave-receive-in-progress t) | ||
| 1065 | (inferior-octave-send-list-and-digest (list (concat line "\n"))) | ||
| 1066 | (while inferior-octave-receive-in-progress | ||
| 1067 | (accept-process-output proc)) | ||
| 1068 | (insert-before-markers | ||
| 1069 | (mapconcat 'identity | ||
| 1070 | (append | ||
| 1071 | (if octave-send-echo-input (list line) (list "")) | ||
| 1072 | (mapcar 'inferior-octave-strip-ctrl-g | ||
| 1073 | inferior-octave-output-list) | ||
| 1074 | (list inferior-octave-output-string)) | ||
| 1075 | "\n"))))) | ||
| 1076 | (if octave-send-show-buffer | ||
| 1077 | (display-buffer inferior-octave-buffer))) | ||
| 1078 | |||
| 1079 | (defun octave-send-block () | ||
| 1080 | "Send current Octave block to the inferior Octave process." | ||
| 1081 | (interactive) | ||
| 1082 | (save-excursion | ||
| 1083 | (octave-mark-block) | ||
| 1084 | (octave-send-region (point) (mark)))) | ||
| 1085 | |||
| 1086 | (defun octave-send-defun () | ||
| 1087 | "Send current Octave function to the inferior Octave process." | ||
| 1088 | (interactive) | ||
| 1089 | (save-excursion | ||
| 1090 | (mark-defun) | ||
| 1091 | (octave-send-region (point) (mark)))) | ||
| 1092 | |||
| 1093 | (defun octave-send-line (&optional arg) | ||
| 1094 | "Send current Octave code line to the inferior Octave process. | ||
| 1095 | With positive prefix ARG, send that many lines. | ||
| 1096 | If `octave-send-line-auto-forward' is non-nil, go to the next unsent | ||
| 1097 | code line." | ||
| 1098 | (interactive "P") | ||
| 1099 | (or arg (setq arg 1)) | ||
| 1100 | (if (> arg 0) | ||
| 1101 | (let (beg end) | ||
| 1102 | (beginning-of-line) | ||
| 1103 | (setq beg (point)) | ||
| 1104 | (octave-next-code-line (- arg 1)) | ||
| 1105 | (end-of-line) | ||
| 1106 | (setq end (point)) | ||
| 1107 | (if octave-send-line-auto-forward | ||
| 1108 | (octave-next-code-line 1)) | ||
| 1109 | (octave-send-region beg end)))) | ||
| 1110 | |||
| 1111 | (defun octave-eval-print-last-sexp () | ||
| 1112 | "Evaluate Octave sexp before point and print value into current buffer." | ||
| 1113 | (interactive) | ||
| 1114 | (inferior-octave t) | ||
| 1115 | (let ((standard-output (current-buffer)) | ||
| 1116 | (print-escape-newlines nil) | ||
| 1117 | (opoint (point))) | ||
| 1118 | (terpri) | ||
| 1119 | (prin1 | ||
| 1120 | (save-excursion | ||
| 1121 | (forward-sexp -1) | ||
| 1122 | (inferior-octave-send-list-and-digest | ||
| 1123 | (list (concat (buffer-substring-no-properties (point) opoint) | ||
| 1124 | "\n"))) | ||
| 1125 | (mapconcat 'identity inferior-octave-output-list "\n"))) | ||
| 1126 | (terpri))) | ||
| 1127 | |||
| 1128 | ;;; Bug reporting | ||
| 1129 | (defun octave-submit-bug-report () | ||
| 1130 | "Submit a bug report on the Emacs Octave package via mail." | ||
| 1131 | (interactive) | ||
| 1132 | (require 'reporter) | ||
| 1133 | (and | ||
| 1134 | (y-or-n-p "Do you want to submit a bug report? ") | ||
| 1135 | (reporter-submit-bug-report | ||
| 1136 | octave-maintainer-address | ||
| 1137 | (concat "Emacs version " emacs-version) | ||
| 1138 | (list | ||
| 1139 | 'octave-blink-matching-block | ||
| 1140 | 'octave-block-offset | ||
| 1141 | 'octave-comment-char | ||
| 1142 | 'octave-continuation-offset | ||
| 1143 | 'octave-continuation-string | ||
| 1144 | 'octave-send-echo-input | ||
| 1145 | 'octave-send-line-auto-forward | ||
| 1146 | 'octave-send-show-buffer)))) | ||
| 1147 | |||
| 1148 | ;; provide ourself | ||
| 1149 | |||
| 1150 | (provide 'octave-mod) | ||
| 1151 | |||
| 1152 | ;;; octave-mod.el ends here | ||
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el new file mode 100644 index 00000000000..c6e19fe3a15 --- /dev/null +++ b/lisp/progmodes/octave.el | |||
| @@ -0,0 +1,1732 @@ | |||
| 1 | ;;; octave.el --- editing octave source files under emacs -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 1997, 2001-2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> | ||
| 6 | ;; John Eaton <jwe@octave.org> | ||
| 7 | ;; Maintainer: FSF | ||
| 8 | ;; Keywords: languages | ||
| 9 | |||
| 10 | ;; This file is part of GNU Emacs. | ||
| 11 | |||
| 12 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 13 | ;; it under the terms of the GNU General Public License as published by | ||
| 14 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 15 | ;; (at your option) any later version. | ||
| 16 | |||
| 17 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | ;; GNU General Public License for more details. | ||
| 21 | |||
| 22 | ;; You should have received a copy of the GNU General Public License | ||
| 23 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 24 | |||
| 25 | ;;; Commentary: | ||
| 26 | |||
| 27 | ;; This package provides emacs support for Octave. It defines a major | ||
| 28 | ;; mode for editing Octave code and contains code for interacting with | ||
| 29 | ;; an inferior Octave process using comint. | ||
| 30 | |||
| 31 | ;; See the documentation of `octave-mode' and `run-octave' for further | ||
| 32 | ;; information on usage and customization. | ||
| 33 | |||
| 34 | ;;; Code: | ||
| 35 | (require 'comint) | ||
| 36 | |||
| 37 | ;;; For emacs < 24.3. | ||
| 38 | (require 'newcomment) | ||
| 39 | (eval-and-compile | ||
| 40 | (unless (fboundp 'user-error) | ||
| 41 | (defalias 'user-error 'error)) | ||
| 42 | (unless (fboundp 'delete-consecutive-dups) | ||
| 43 | (defalias 'delete-consecutive-dups 'delete-dups))) | ||
| 44 | (eval-when-compile | ||
| 45 | (unless (fboundp 'setq-local) | ||
| 46 | (defmacro setq-local (var val) | ||
| 47 | "Set variable VAR to value VAL in current buffer." | ||
| 48 | (list 'set (list 'make-local-variable (list 'quote var)) val)))) | ||
| 49 | |||
| 50 | (defgroup octave nil | ||
| 51 | "Editing Octave code." | ||
| 52 | :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) | ||
| 53 | :group 'languages) | ||
| 54 | |||
| 55 | (define-obsolete-function-alias 'octave-submit-bug-report | ||
| 56 | 'report-emacs-bug "24.4") | ||
| 57 | |||
| 58 | (define-abbrev-table 'octave-abbrev-table nil | ||
| 59 | "Abbrev table for Octave's reserved words. | ||
| 60 | Used in `octave-mode' and `inferior-octave-mode' buffers.") | ||
| 61 | |||
| 62 | (defvar octave-comment-char ?# | ||
| 63 | "Character to start an Octave comment.") | ||
| 64 | |||
| 65 | (defvar octave-comment-start (char-to-string octave-comment-char) | ||
| 66 | "Octave-specific `comment-start' (which see).") | ||
| 67 | |||
| 68 | (defvar octave-comment-start-skip "\\(^\\|\\S<\\)\\(?:%!\\|\\s<+\\)\\s-*" | ||
| 69 | "Octave-specific `comment-start-skip' (which see).") | ||
| 70 | |||
| 71 | (defvar octave-begin-keywords | ||
| 72 | '("classdef" "do" "enumeration" "events" "for" "function" "if" "methods" | ||
| 73 | "parfor" "properties" "switch" "try" "unwind_protect" "while")) | ||
| 74 | |||
| 75 | (defvar octave-else-keywords | ||
| 76 | '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup")) | ||
| 77 | |||
| 78 | (defvar octave-end-keywords | ||
| 79 | '("endclassdef" "endenumeration" "endevents" "endfor" "endfunction" "endif" | ||
| 80 | "endmethods" "endparfor" "endproperties" "endswitch" "end_try_catch" | ||
| 81 | "end_unwind_protect" "endwhile" "until" "end")) | ||
| 82 | |||
| 83 | (defvar octave-reserved-words | ||
| 84 | (append octave-begin-keywords | ||
| 85 | octave-else-keywords | ||
| 86 | octave-end-keywords | ||
| 87 | '("break" "continue" "global" "persistent" "return")) | ||
| 88 | "Reserved words in Octave.") | ||
| 89 | |||
| 90 | (defvar octave-function-header-regexp | ||
| 91 | (concat "^\\s-*\\_<\\(function\\)\\_>" | ||
| 92 | "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\(?:\\w\\|\\s_\\)+\\)\\_>") | ||
| 93 | "Regexp to match an Octave function header. | ||
| 94 | The string `function' and its name are given by the first and third | ||
| 95 | parenthetical grouping.") | ||
| 96 | |||
| 97 | |||
| 98 | (defvar octave-mode-map | ||
| 99 | (let ((map (make-sparse-keymap))) | ||
| 100 | (define-key map "\M-." 'octave-find-definition) | ||
| 101 | (define-key map "\M-\C-j" 'octave-indent-new-comment-line) | ||
| 102 | (define-key map "\C-c\C-p" 'octave-previous-code-line) | ||
| 103 | (define-key map "\C-c\C-n" 'octave-next-code-line) | ||
| 104 | (define-key map "\C-c\C-a" 'octave-beginning-of-line) | ||
| 105 | (define-key map "\C-c\C-e" 'octave-end-of-line) | ||
| 106 | (define-key map [remap down-list] 'smie-down-list) | ||
| 107 | (define-key map "\C-c\M-\C-h" 'octave-mark-block) | ||
| 108 | (define-key map "\C-c]" 'smie-close-block) | ||
| 109 | (define-key map "\C-c/" 'smie-close-block) | ||
| 110 | (define-key map "\C-c;" 'octave-update-function-file-comment) | ||
| 111 | (define-key map "\C-hd" 'octave-help) | ||
| 112 | (define-key map "\C-c\C-f" 'octave-insert-defun) | ||
| 113 | (define-key map "\C-c\C-il" 'octave-send-line) | ||
| 114 | (define-key map "\C-c\C-ib" 'octave-send-block) | ||
| 115 | (define-key map "\C-c\C-if" 'octave-send-defun) | ||
| 116 | (define-key map "\C-c\C-ir" 'octave-send-region) | ||
| 117 | (define-key map "\C-c\C-is" 'octave-show-process-buffer) | ||
| 118 | (define-key map "\C-c\C-iq" 'octave-hide-process-buffer) | ||
| 119 | (define-key map "\C-c\C-ik" 'octave-kill-process) | ||
| 120 | (define-key map "\C-c\C-i\C-l" 'octave-send-line) | ||
| 121 | (define-key map "\C-c\C-i\C-b" 'octave-send-block) | ||
| 122 | (define-key map "\C-c\C-i\C-f" 'octave-send-defun) | ||
| 123 | (define-key map "\C-c\C-i\C-r" 'octave-send-region) | ||
| 124 | (define-key map "\C-c\C-i\C-s" 'octave-show-process-buffer) | ||
| 125 | (define-key map "\C-c\C-i\C-q" 'octave-hide-process-buffer) | ||
| 126 | (define-key map "\C-c\C-i\C-k" 'octave-kill-process) | ||
| 127 | map) | ||
| 128 | "Keymap used in Octave mode.") | ||
| 129 | |||
| 130 | |||
| 131 | |||
| 132 | (easy-menu-define octave-mode-menu octave-mode-map | ||
| 133 | "Menu for Octave mode." | ||
| 134 | '("Octave" | ||
| 135 | ["Split Line at Point" octave-indent-new-comment-line t] | ||
| 136 | ["Previous Code Line" octave-previous-code-line t] | ||
| 137 | ["Next Code Line" octave-next-code-line t] | ||
| 138 | ["Begin of Line" octave-beginning-of-line t] | ||
| 139 | ["End of Line" octave-end-of-line t] | ||
| 140 | ["Mark Block" octave-mark-block t] | ||
| 141 | ["Close Block" smie-close-block t] | ||
| 142 | "---" | ||
| 143 | ["Start Octave Process" run-octave t] | ||
| 144 | ["Documentation Lookup" info-lookup-symbol t] | ||
| 145 | ["Help on Function" octave-help t] | ||
| 146 | ["Find Function Definition" octave-find-definition t] | ||
| 147 | ["Insert Function" octave-insert-defun t] | ||
| 148 | ["Update Function File Comment" octave-update-function-file-comment t] | ||
| 149 | "---" | ||
| 150 | ["Function Syntax Hints" (call-interactively | ||
| 151 | (if (fboundp 'eldoc-post-insert-mode) | ||
| 152 | 'eldoc-post-insert-mode | ||
| 153 | 'eldoc-mode)) | ||
| 154 | :style toggle :selected (or eldoc-post-insert-mode eldoc-mode) | ||
| 155 | :help "Display function signatures after typing `SPC' or `('"] | ||
| 156 | ["Delimiter Matching" smie-highlight-matching-block-mode | ||
| 157 | :style toggle :selected smie-highlight-matching-block-mode | ||
| 158 | :help "Highlight matched pairs such as `if ... end'" | ||
| 159 | :visible (fboundp 'smie-highlight-matching-block-mode)] | ||
| 160 | ["Auto Fill" auto-fill-mode | ||
| 161 | :style toggle :selected auto-fill-function | ||
| 162 | :help "Automatic line breaking"] | ||
| 163 | ["Electric Layout" electric-layout-mode | ||
| 164 | :style toggle :selected electric-layout-mode | ||
| 165 | :help "Automatically insert newlines around some chars"] | ||
| 166 | "---" | ||
| 167 | ("Debug" | ||
| 168 | ["Send Current Line" octave-send-line t] | ||
| 169 | ["Send Current Block" octave-send-block t] | ||
| 170 | ["Send Current Function" octave-send-defun t] | ||
| 171 | ["Send Region" octave-send-region t] | ||
| 172 | ["Show Process Buffer" octave-show-process-buffer t] | ||
| 173 | ["Hide Process Buffer" octave-hide-process-buffer t] | ||
| 174 | ["Kill Process" octave-kill-process t]) | ||
| 175 | "---" | ||
| 176 | ["Customize Octave" (customize-group 'octave) t] | ||
| 177 | ["Submit Bug Report" report-emacs-bug t])) | ||
| 178 | |||
| 179 | (defvar octave-mode-syntax-table | ||
| 180 | (let ((table (make-syntax-table))) | ||
| 181 | (modify-syntax-entry ?\r " " table) | ||
| 182 | (modify-syntax-entry ?+ "." table) | ||
| 183 | (modify-syntax-entry ?- "." table) | ||
| 184 | (modify-syntax-entry ?= "." table) | ||
| 185 | (modify-syntax-entry ?* "." table) | ||
| 186 | (modify-syntax-entry ?/ "." table) | ||
| 187 | (modify-syntax-entry ?> "." table) | ||
| 188 | (modify-syntax-entry ?< "." table) | ||
| 189 | (modify-syntax-entry ?& "." table) | ||
| 190 | (modify-syntax-entry ?| "." table) | ||
| 191 | (modify-syntax-entry ?! "." table) | ||
| 192 | (modify-syntax-entry ?\\ "." table) | ||
| 193 | (modify-syntax-entry ?\' "." table) | ||
| 194 | (modify-syntax-entry ?\` "." table) | ||
| 195 | (modify-syntax-entry ?. "." table) | ||
| 196 | (modify-syntax-entry ?\" "\"" table) | ||
| 197 | (modify-syntax-entry ?_ "_" table) | ||
| 198 | ;; The "b" flag only applies to the second letter of the comstart | ||
| 199 | ;; and the first letter of the comend, i.e. the "4b" below is ineffective. | ||
| 200 | ;; If we try to put `b' on the single-line comments, we get a similar | ||
| 201 | ;; problem where the % and # chars appear as first chars of the 2-char | ||
| 202 | ;; comend, so the multi-line ender is also turned into style-b. | ||
| 203 | ;; So we need the new "c" comment style. | ||
| 204 | (modify-syntax-entry ?\% "< 13" table) | ||
| 205 | (modify-syntax-entry ?\# "< 13" table) | ||
| 206 | (modify-syntax-entry ?\{ "(} 2c" table) | ||
| 207 | (modify-syntax-entry ?\} "){ 4c" table) | ||
| 208 | (modify-syntax-entry ?\n ">" table) | ||
| 209 | table) | ||
| 210 | "Syntax table in use in `octave-mode' buffers.") | ||
| 211 | |||
| 212 | (defcustom octave-font-lock-texinfo-comment t | ||
| 213 | "Control whether to highlight the texinfo comment block." | ||
| 214 | :type 'boolean | ||
| 215 | :group 'octave | ||
| 216 | :version "24.4") | ||
| 217 | |||
| 218 | (defcustom octave-blink-matching-block t | ||
| 219 | "Control the blinking of matching Octave block keywords. | ||
| 220 | Non-nil means show matching begin of block when inserting a space, | ||
| 221 | newline or semicolon after an else or end keyword." | ||
| 222 | :type 'boolean | ||
| 223 | :group 'octave) | ||
| 224 | |||
| 225 | (defcustom octave-block-offset 2 | ||
| 226 | "Extra indentation applied to statements in Octave block structures." | ||
| 227 | :type 'integer | ||
| 228 | :group 'octave) | ||
| 229 | |||
| 230 | (defvar octave-block-comment-start | ||
| 231 | (concat (make-string 2 octave-comment-char) " ") | ||
| 232 | "String to insert to start a new Octave comment on an empty line.") | ||
| 233 | |||
| 234 | (defcustom octave-continuation-offset 4 | ||
| 235 | "Extra indentation applied to Octave continuation lines." | ||
| 236 | :type 'integer | ||
| 237 | :group 'octave) | ||
| 238 | |||
| 239 | (eval-and-compile | ||
| 240 | (defconst octave-continuation-marker-regexp "\\\\\\|\\.\\.\\.")) | ||
| 241 | |||
| 242 | (defvar octave-continuation-regexp | ||
| 243 | (concat "[^#%\n]*\\(" octave-continuation-marker-regexp | ||
| 244 | "\\)\\s-*\\(\\s<.*\\)?$")) | ||
| 245 | |||
| 246 | ;; Char \ is considered a bad decision for continuing a line. | ||
| 247 | (defconst octave-continuation-string "..." | ||
| 248 | "Character string used for Octave continuation lines.") | ||
| 249 | |||
| 250 | (defvar octave-mode-imenu-generic-expression | ||
| 251 | (list | ||
| 252 | ;; Functions | ||
| 253 | (list nil octave-function-header-regexp 3)) | ||
| 254 | "Imenu expression for Octave mode. See `imenu-generic-expression'.") | ||
| 255 | |||
| 256 | (defcustom octave-mode-hook nil | ||
| 257 | "Hook to be run when Octave mode is started." | ||
| 258 | :type 'hook | ||
| 259 | :group 'octave) | ||
| 260 | |||
| 261 | (defcustom octave-send-show-buffer t | ||
| 262 | "Non-nil means display `inferior-octave-buffer' after sending to it." | ||
| 263 | :type 'boolean | ||
| 264 | :group 'octave) | ||
| 265 | |||
| 266 | (defcustom octave-send-line-auto-forward t | ||
| 267 | "Control auto-forward after sending to the inferior Octave process. | ||
| 268 | Non-nil means always go to the next Octave code line after sending." | ||
| 269 | :type 'boolean | ||
| 270 | :group 'octave) | ||
| 271 | |||
| 272 | (defcustom octave-send-echo-input t | ||
| 273 | "Non-nil means echo input sent to the inferior Octave process." | ||
| 274 | :type 'boolean | ||
| 275 | :group 'octave) | ||
| 276 | |||
| 277 | |||
| 278 | ;;; SMIE indentation | ||
| 279 | |||
| 280 | (require 'smie) | ||
| 281 | |||
| 282 | ;; Use '__operators__' in Octave REPL to get a full list. | ||
| 283 | (defconst octave-operator-table | ||
| 284 | '((assoc ";" "\n") (assoc ",") ; The doc claims they have equal precedence!? | ||
| 285 | (right "=" "+=" "-=" "*=" "/=") | ||
| 286 | (assoc "&&") (assoc "||") ; The doc claims they have equal precedence!? | ||
| 287 | (assoc "&") (assoc "|") ; The doc claims they have equal precedence!? | ||
| 288 | (nonassoc "<" "<=" "==" ">=" ">" "!=" "~=") | ||
| 289 | (nonassoc ":") ;No idea what this is. | ||
| 290 | (assoc "+" "-") | ||
| 291 | (assoc "*" "/" "\\" ".\\" ".*" "./") | ||
| 292 | (nonassoc "'" ".'") | ||
| 293 | (nonassoc "++" "--" "!" "~") ;And unary "+" and "-". | ||
| 294 | (right "^" "**" ".^" ".**") | ||
| 295 | ;; It's not really an operator, but for indentation purposes it | ||
| 296 | ;; could be convenient to treat it as one. | ||
| 297 | (assoc "..."))) | ||
| 298 | |||
| 299 | (defconst octave-smie-bnf-table | ||
| 300 | '((atom) | ||
| 301 | ;; We can't distinguish the first element in a sequence with | ||
| 302 | ;; precedence grammars, so we can't distinguish the condition | ||
| 303 | ;; if the `if' from the subsequent body, for example. | ||
| 304 | ;; This has to be done later in the indentation rules. | ||
| 305 | (exp (exp "\n" exp) | ||
| 306 | ;; We need to mention at least one of the operators in this part | ||
| 307 | ;; of the grammar: if the BNF and the operator table have | ||
| 308 | ;; no overlap, SMIE can't know how they relate. | ||
| 309 | (exp ";" exp) | ||
| 310 | ("try" exp "catch" exp "end_try_catch") | ||
| 311 | ("try" exp "catch" exp "end") | ||
| 312 | ("unwind_protect" exp | ||
| 313 | "unwind_protect_cleanup" exp "end_unwind_protect") | ||
| 314 | ("unwind_protect" exp "unwind_protect_cleanup" exp "end") | ||
| 315 | ("for" exp "endfor") | ||
| 316 | ("for" exp "end") | ||
| 317 | ("parfor" exp "endparfor") | ||
| 318 | ("parfor" exp "end") | ||
| 319 | ("do" exp "until" atom) | ||
| 320 | ("while" exp "endwhile") | ||
| 321 | ("while" exp "end") | ||
| 322 | ("if" exp "endif") | ||
| 323 | ("if" exp "else" exp "endif") | ||
| 324 | ("if" exp "elseif" exp "else" exp "endif") | ||
| 325 | ("if" exp "elseif" exp "elseif" exp "else" exp "endif") | ||
| 326 | ("if" exp "elseif" exp "elseif" exp "else" exp "end") | ||
| 327 | ("switch" exp "case" exp "endswitch") | ||
| 328 | ("switch" exp "case" exp "otherwise" exp "endswitch") | ||
| 329 | ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch") | ||
| 330 | ("switch" exp "case" exp "case" exp "otherwise" exp "end") | ||
| 331 | ("function" exp "endfunction") | ||
| 332 | ("function" exp "end") | ||
| 333 | ("enumeration" exp "endenumeration") | ||
| 334 | ("enumeration" exp "end") | ||
| 335 | ("events" exp "endevents") | ||
| 336 | ("events" exp "end") | ||
| 337 | ("methods" exp "endmethods") | ||
| 338 | ("methods" exp "end") | ||
| 339 | ("properties" exp "endproperties") | ||
| 340 | ("properties" exp "end") | ||
| 341 | ("classdef" exp "endclassdef") | ||
| 342 | ("classdef" exp "end")) | ||
| 343 | ;; (fundesc (atom "=" atom)) | ||
| 344 | )) | ||
| 345 | |||
| 346 | (defconst octave-smie-grammar | ||
| 347 | (smie-prec2->grammar | ||
| 348 | (smie-merge-prec2s | ||
| 349 | (smie-bnf->prec2 octave-smie-bnf-table | ||
| 350 | '((assoc "\n" ";"))) | ||
| 351 | |||
| 352 | (smie-precs->prec2 octave-operator-table)))) | ||
| 353 | |||
| 354 | ;; Tokenizing needs to be refined so that ";;" is treated as two | ||
| 355 | ;; tokens and also so as to recognize the \n separator (and | ||
| 356 | ;; corresponding continuation lines). | ||
| 357 | |||
| 358 | (defconst octave-operator-regexp | ||
| 359 | (regexp-opt (apply 'append (mapcar 'cdr octave-operator-table)))) | ||
| 360 | |||
| 361 | (defun octave-smie-backward-token () | ||
| 362 | (let ((pos (point))) | ||
| 363 | (forward-comment (- (point))) | ||
| 364 | (cond | ||
| 365 | ((and (not (eq (char-before) ?\;)) ;Coalesce ";" and "\n". | ||
| 366 | (> pos (line-end-position)) | ||
| 367 | (if (looking-back octave-continuation-marker-regexp (- (point) 3)) | ||
| 368 | (progn | ||
| 369 | (goto-char (match-beginning 0)) | ||
| 370 | (forward-comment (- (point))) | ||
| 371 | nil) | ||
| 372 | t) | ||
| 373 | ;; Ignore it if it's within parentheses. | ||
| 374 | (let ((ppss (syntax-ppss))) | ||
| 375 | (not (and (nth 1 ppss) | ||
| 376 | (eq ?\( (char-after (nth 1 ppss))))))) | ||
| 377 | (skip-chars-forward " \t") | ||
| 378 | ;; Why bother distinguishing \n and ;? | ||
| 379 | ";") ;;"\n" | ||
| 380 | ((and (looking-back octave-operator-regexp (- (point) 3) 'greedy) | ||
| 381 | ;; Don't mistake a string quote for a transpose. | ||
| 382 | (not (looking-back "\\s\"" (1- (point))))) | ||
| 383 | (goto-char (match-beginning 0)) | ||
| 384 | (match-string-no-properties 0)) | ||
| 385 | (t | ||
| 386 | (smie-default-backward-token))))) | ||
| 387 | |||
| 388 | (defun octave-smie-forward-token () | ||
| 389 | (skip-chars-forward " \t") | ||
| 390 | (when (looking-at (eval-when-compile | ||
| 391 | (concat "\\(" octave-continuation-marker-regexp | ||
| 392 | "\\)[ \t]*\\($\\|[%#]\\)"))) | ||
| 393 | (goto-char (match-end 1)) | ||
| 394 | (forward-comment 1)) | ||
| 395 | (cond | ||
| 396 | ((and (looking-at "[%#\n]") | ||
| 397 | (not (or (save-excursion (skip-chars-backward " \t") | ||
| 398 | ;; Only add implicit ; when needed. | ||
| 399 | (or (bolp) (eq (char-before) ?\;))) | ||
| 400 | ;; Ignore it if it's within parentheses. | ||
| 401 | (let ((ppss (syntax-ppss))) | ||
| 402 | (and (nth 1 ppss) | ||
| 403 | (eq ?\( (char-after (nth 1 ppss)))))))) | ||
| 404 | (if (eolp) (forward-char 1) (forward-comment 1)) | ||
| 405 | ;; Why bother distinguishing \n and ;? | ||
| 406 | ";") ;;"\n" | ||
| 407 | ((progn (forward-comment (point-max)) nil)) | ||
| 408 | ((looking-at ";[ \t]*\\($\\|[%#]\\)") | ||
| 409 | ;; Combine the ; with the subsequent \n. | ||
| 410 | (goto-char (match-beginning 1)) | ||
| 411 | (forward-comment 1) | ||
| 412 | ";") | ||
| 413 | ((and (looking-at octave-operator-regexp) | ||
| 414 | ;; Don't mistake a string quote for a transpose. | ||
| 415 | (not (looking-at "\\s\""))) | ||
| 416 | (goto-char (match-end 0)) | ||
| 417 | (match-string-no-properties 0)) | ||
| 418 | (t | ||
| 419 | (smie-default-forward-token)))) | ||
| 420 | |||
| 421 | (defun octave-smie-rules (kind token) | ||
| 422 | (pcase (cons kind token) | ||
| 423 | ;; We could set smie-indent-basic instead, but that would have two | ||
| 424 | ;; disadvantages: | ||
| 425 | ;; - changes to octave-block-offset wouldn't take effect immediately. | ||
| 426 | ;; - edebug wouldn't show the use of this variable. | ||
| 427 | (`(:elem . basic) octave-block-offset) | ||
| 428 | ;; Since "case" is in the same BNF rules as switch..end, SMIE by default | ||
| 429 | ;; aligns it with "switch". | ||
| 430 | (`(:before . "case") (if (not (smie-rule-sibling-p)) octave-block-offset)) | ||
| 431 | (`(:after . ";") | ||
| 432 | (if (smie-rule-parent-p "classdef" "events" "enumeration" "function" "if" | ||
| 433 | "while" "else" "elseif" "for" "parfor" | ||
| 434 | "properties" "methods" "otherwise" "case" | ||
| 435 | "try" "catch" "unwind_protect" | ||
| 436 | "unwind_protect_cleanup") | ||
| 437 | (smie-rule-parent octave-block-offset) | ||
| 438 | ;; For (invalid) code between switch and case. | ||
| 439 | ;; (if (smie-parent-p "switch") 4) | ||
| 440 | nil)))) | ||
| 441 | |||
| 442 | (defun octave-indent-comment () | ||
| 443 | "A function for `smie-indent-functions' (which see)." | ||
| 444 | (save-excursion | ||
| 445 | (back-to-indentation) | ||
| 446 | (cond | ||
| 447 | ((octave-in-string-or-comment-p) nil) | ||
| 448 | ((looking-at-p "\\(\\s<\\)\\1\\{2,\\}") | ||
| 449 | 0) | ||
| 450 | ;; Exclude %{, %} and %!. | ||
| 451 | ((and (looking-at-p "\\s<\\(?:[^{}!]\\|$\\)") | ||
| 452 | (not (looking-at-p "\\(\\s<\\)\\1"))) | ||
| 453 | (comment-choose-indent))))) | ||
| 454 | |||
| 455 | |||
| 456 | (defvar octave-font-lock-keywords | ||
| 457 | (list | ||
| 458 | ;; Fontify all builtin keywords. | ||
| 459 | (cons (concat "\\_<\\(" | ||
| 460 | (regexp-opt octave-reserved-words) | ||
| 461 | "\\)\\_>") | ||
| 462 | 'font-lock-keyword-face) | ||
| 463 | ;; Note: 'end' also serves as the last index in an indexing expression. | ||
| 464 | ;; Ref: http://www.mathworks.com/help/matlab/ref/end.html | ||
| 465 | (list (lambda (limit) | ||
| 466 | (while (re-search-forward "\\_<end\\_>" limit 'move) | ||
| 467 | (let ((beg (match-beginning 0)) | ||
| 468 | (end (match-end 0))) | ||
| 469 | (unless (octave-in-string-or-comment-p) | ||
| 470 | (condition-case nil | ||
| 471 | (progn | ||
| 472 | (goto-char beg) | ||
| 473 | (backward-up-list) | ||
| 474 | (when (memq (char-after) '(?\( ?\[ ?\{)) | ||
| 475 | (put-text-property beg end 'face nil)) | ||
| 476 | (goto-char end)) | ||
| 477 | (error (goto-char end)))))) | ||
| 478 | nil)) | ||
| 479 | ;; Fontify all operators. | ||
| 480 | (cons octave-operator-regexp 'font-lock-builtin-face) | ||
| 481 | ;; Fontify all function declarations. | ||
| 482 | (list octave-function-header-regexp | ||
| 483 | '(1 font-lock-keyword-face) | ||
| 484 | '(3 font-lock-function-name-face nil t))) | ||
| 485 | "Additional Octave expressions to highlight.") | ||
| 486 | |||
| 487 | (defun octave-syntax-propertize-function (start end) | ||
| 488 | (goto-char start) | ||
| 489 | (octave-syntax-propertize-sqs end) | ||
| 490 | (funcall (syntax-propertize-rules | ||
| 491 | ("\\\\" (0 (when (eq (nth 3 (save-excursion | ||
| 492 | (syntax-ppss (match-beginning 0)))) | ||
| 493 | ?\") | ||
| 494 | (string-to-syntax "\\")))) | ||
| 495 | ;; Try to distinguish the string-quotes from the transpose-quotes. | ||
| 496 | ("\\(?:^\\|[[({,; ]\\)\\('\\)" | ||
| 497 | (1 (prog1 "\"'" (octave-syntax-propertize-sqs end))))) | ||
| 498 | (point) end)) | ||
| 499 | |||
| 500 | (defun octave-syntax-propertize-sqs (end) | ||
| 501 | "Propertize the content/end of single-quote strings." | ||
| 502 | (when (eq (nth 3 (syntax-ppss)) ?\') | ||
| 503 | ;; A '..' string. | ||
| 504 | (when (re-search-forward | ||
| 505 | "\\(?:\\=\\|[^']\\)\\(?:''\\)*\\('\\)\\($\\|[^']\\)" end 'move) | ||
| 506 | (goto-char (match-beginning 2)) | ||
| 507 | (when (eq (char-before (match-beginning 1)) ?\\) | ||
| 508 | ;; Backslash cannot escape a single quote. | ||
| 509 | (put-text-property (1- (match-beginning 1)) (match-beginning 1) | ||
| 510 | 'syntax-table (string-to-syntax "."))) | ||
| 511 | (put-text-property (match-beginning 1) (match-end 1) | ||
| 512 | 'syntax-table (string-to-syntax "\"'"))))) | ||
| 513 | |||
| 514 | (defvar electric-layout-rules) | ||
| 515 | |||
| 516 | ;;;###autoload | ||
| 517 | (define-derived-mode octave-mode prog-mode "Octave" | ||
| 518 | "Major mode for editing Octave code. | ||
| 519 | |||
| 520 | Octave is a high-level language, primarily intended for numerical | ||
| 521 | computations. It provides a convenient command line interface | ||
| 522 | for solving linear and nonlinear problems numerically. Function | ||
| 523 | definitions can also be stored in files and used in batch mode." | ||
| 524 | :abbrev-table octave-abbrev-table | ||
| 525 | |||
| 526 | (smie-setup octave-smie-grammar #'octave-smie-rules | ||
| 527 | :forward-token #'octave-smie-forward-token | ||
| 528 | :backward-token #'octave-smie-backward-token) | ||
| 529 | (setq-local smie-indent-basic 'octave-block-offset) | ||
| 530 | (add-hook 'smie-indent-functions #'octave-indent-comment nil t) | ||
| 531 | |||
| 532 | (setq-local smie-blink-matching-triggers | ||
| 533 | (cons ?\; smie-blink-matching-triggers)) | ||
| 534 | (unless octave-blink-matching-block | ||
| 535 | (remove-hook 'post-self-insert-hook #'smie-blink-matching-open 'local)) | ||
| 536 | |||
| 537 | (setq-local electric-indent-chars | ||
| 538 | (cons ?\; electric-indent-chars)) | ||
| 539 | ;; IIUC matlab-mode takes the opposite approach: it makes RET insert | ||
| 540 | ;; a ";" at those places where it's correct (i.e. outside of parens). | ||
| 541 | (setq-local electric-layout-rules '((?\; . after))) | ||
| 542 | |||
| 543 | (setq-local comment-start octave-comment-start) | ||
| 544 | (setq-local comment-end "") | ||
| 545 | (setq-local comment-start-skip octave-comment-start-skip) | ||
| 546 | (setq-local comment-add 1) | ||
| 547 | |||
| 548 | (setq-local parse-sexp-ignore-comments t) | ||
| 549 | (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter)) | ||
| 550 | (setq-local paragraph-separate paragraph-start) | ||
| 551 | (setq-local paragraph-ignore-fill-prefix t) | ||
| 552 | (setq-local fill-paragraph-function 'octave-fill-paragraph) | ||
| 553 | |||
| 554 | (setq-local fill-nobreak-predicate | ||
| 555 | (lambda () (eq (octave-in-string-p) ?'))) | ||
| 556 | (add-function :around (local 'comment-line-break-function) | ||
| 557 | #'octave--indent-new-comment-line) | ||
| 558 | |||
| 559 | (setq font-lock-defaults '(octave-font-lock-keywords)) | ||
| 560 | |||
| 561 | (setq-local syntax-propertize-function #'octave-syntax-propertize-function) | ||
| 562 | |||
| 563 | (setq-local imenu-generic-expression octave-mode-imenu-generic-expression) | ||
| 564 | (setq-local imenu-case-fold-search nil) | ||
| 565 | |||
| 566 | (add-hook 'completion-at-point-functions 'octave-completion-at-point nil t) | ||
| 567 | (add-hook 'before-save-hook 'octave-sync-function-file-names nil t) | ||
| 568 | (setq-local beginning-of-defun-function 'octave-beginning-of-defun) | ||
| 569 | (and octave-font-lock-texinfo-comment (octave-font-lock-texinfo-comment)) | ||
| 570 | (setq-local eldoc-documentation-function 'octave-eldoc-function) | ||
| 571 | |||
| 572 | (easy-menu-add octave-mode-menu)) | ||
| 573 | |||
| 574 | |||
| 575 | (defcustom inferior-octave-program "octave" | ||
| 576 | "Program invoked by `inferior-octave'." | ||
| 577 | :type 'string | ||
| 578 | :group 'octave) | ||
| 579 | |||
| 580 | (defcustom inferior-octave-buffer "*Inferior Octave*" | ||
| 581 | "Name of buffer for running an inferior Octave process." | ||
| 582 | :type 'string | ||
| 583 | :group 'octave) | ||
| 584 | |||
| 585 | (defcustom inferior-octave-prompt | ||
| 586 | "\\(^octave\\(\\|.bin\\|.exe\\)\\(-[.0-9]+\\)?\\(:[0-9]+\\)?\\|^debug\\|^\\)>+ " | ||
| 587 | "Regexp to match prompts for the inferior Octave process." | ||
| 588 | :type 'regexp | ||
| 589 | :group 'octave) | ||
| 590 | |||
| 591 | (defcustom inferior-octave-prompt-read-only comint-prompt-read-only | ||
| 592 | "If non-nil, the Octave prompt is read only. | ||
| 593 | See `comint-prompt-read-only' for details." | ||
| 594 | :type 'boolean | ||
| 595 | :group 'octave | ||
| 596 | :version "24.4") | ||
| 597 | |||
| 598 | (defcustom inferior-octave-startup-file | ||
| 599 | (convert-standard-filename | ||
| 600 | (concat "~/.emacs-" (file-name-nondirectory inferior-octave-program))) | ||
| 601 | "Name of the inferior Octave startup file. | ||
| 602 | The contents of this file are sent to the inferior Octave process on | ||
| 603 | startup." | ||
| 604 | :type '(choice (const :tag "None" nil) file) | ||
| 605 | :group 'octave | ||
| 606 | :version "24.4") | ||
| 607 | |||
| 608 | (defcustom inferior-octave-startup-args nil | ||
| 609 | "List of command line arguments for the inferior Octave process. | ||
| 610 | For example, for suppressing the startup message and using `traditional' | ||
| 611 | mode, set this to (\"-q\" \"--traditional\")." | ||
| 612 | :type '(repeat string) | ||
| 613 | :group 'octave) | ||
| 614 | |||
| 615 | (defcustom inferior-octave-mode-hook nil | ||
| 616 | "Hook to be run when Inferior Octave mode is started." | ||
| 617 | :type 'hook | ||
| 618 | :group 'octave) | ||
| 619 | |||
| 620 | (defvar inferior-octave-process nil) | ||
| 621 | |||
| 622 | (defvar inferior-octave-mode-map | ||
| 623 | (let ((map (make-sparse-keymap))) | ||
| 624 | (set-keymap-parent map comint-mode-map) | ||
| 625 | (define-key map "\M-." 'octave-find-definition) | ||
| 626 | (define-key map "\t" 'completion-at-point) | ||
| 627 | (define-key map "\C-hd" 'octave-help) | ||
| 628 | ;; Same as in `shell-mode'. | ||
| 629 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) | ||
| 630 | (define-key map "\C-c\C-l" 'inferior-octave-dynamic-list-input-ring) | ||
| 631 | (define-key map [menu-bar inout list-history] | ||
| 632 | '("List Input History" . inferior-octave-dynamic-list-input-ring)) | ||
| 633 | map) | ||
| 634 | "Keymap used in Inferior Octave mode.") | ||
| 635 | |||
| 636 | (defvar inferior-octave-mode-syntax-table | ||
| 637 | (let ((table (make-syntax-table octave-mode-syntax-table))) | ||
| 638 | table) | ||
| 639 | "Syntax table in use in inferior-octave-mode buffers.") | ||
| 640 | |||
| 641 | (defvar inferior-octave-font-lock-keywords | ||
| 642 | (list | ||
| 643 | (cons inferior-octave-prompt 'font-lock-type-face)) | ||
| 644 | ;; Could certainly do more font locking in inferior Octave ... | ||
| 645 | "Additional expressions to highlight in Inferior Octave mode.") | ||
| 646 | |||
| 647 | (defvar inferior-octave-output-list nil) | ||
| 648 | (defvar inferior-octave-output-string nil) | ||
| 649 | (defvar inferior-octave-receive-in-progress nil) | ||
| 650 | |||
| 651 | (define-obsolete-variable-alias 'inferior-octave-startup-hook | ||
| 652 | 'inferior-octave-mode-hook "24.4") | ||
| 653 | |||
| 654 | (defvar inferior-octave-dynamic-complete-functions | ||
| 655 | '(inferior-octave-completion-at-point comint-filename-completion) | ||
| 656 | "List of functions called to perform completion for inferior Octave. | ||
| 657 | This variable is used to initialize `comint-dynamic-complete-functions' | ||
| 658 | in the Inferior Octave buffer.") | ||
| 659 | |||
| 660 | (defvar info-lookup-mode) | ||
| 661 | |||
| 662 | (define-derived-mode inferior-octave-mode comint-mode "Inferior Octave" | ||
| 663 | "Major mode for interacting with an inferior Octave process." | ||
| 664 | :abbrev-table octave-abbrev-table | ||
| 665 | (setq comint-prompt-regexp inferior-octave-prompt) | ||
| 666 | |||
| 667 | (setq-local comment-start octave-comment-start) | ||
| 668 | (setq-local comment-end "") | ||
| 669 | (setq comment-column 32) | ||
| 670 | (setq-local comment-start-skip octave-comment-start-skip) | ||
| 671 | |||
| 672 | (setq font-lock-defaults '(inferior-octave-font-lock-keywords nil nil)) | ||
| 673 | |||
| 674 | (setq-local info-lookup-mode 'octave-mode) | ||
| 675 | (setq-local eldoc-documentation-function 'octave-eldoc-function) | ||
| 676 | |||
| 677 | (setq comint-input-ring-file-name | ||
| 678 | (or (getenv "OCTAVE_HISTFILE") "~/.octave_hist") | ||
| 679 | comint-input-ring-size (or (getenv "OCTAVE_HISTSIZE") 1024)) | ||
| 680 | (setq-local comint-dynamic-complete-functions | ||
| 681 | inferior-octave-dynamic-complete-functions) | ||
| 682 | (setq-local comint-prompt-read-only inferior-octave-prompt-read-only) | ||
| 683 | (add-hook 'comint-input-filter-functions | ||
| 684 | 'inferior-octave-directory-tracker nil t) | ||
| 685 | ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572 | ||
| 686 | (add-hook 'window-configuration-change-hook | ||
| 687 | 'inferior-octave-track-window-width-change nil t) | ||
| 688 | (comint-read-input-ring t)) | ||
| 689 | |||
| 690 | ;;;###autoload | ||
| 691 | (defun inferior-octave (&optional arg) | ||
| 692 | "Run an inferior Octave process, I/O via `inferior-octave-buffer'. | ||
| 693 | This buffer is put in Inferior Octave mode. See `inferior-octave-mode'. | ||
| 694 | |||
| 695 | Unless ARG is non-nil, switches to this buffer. | ||
| 696 | |||
| 697 | The elements of the list `inferior-octave-startup-args' are sent as | ||
| 698 | command line arguments to the inferior Octave process on startup. | ||
| 699 | |||
| 700 | Additional commands to be executed on startup can be provided either in | ||
| 701 | the file specified by `inferior-octave-startup-file' or by the default | ||
| 702 | startup file, `~/.emacs-octave'." | ||
| 703 | (interactive "P") | ||
| 704 | (let ((buffer (get-buffer-create inferior-octave-buffer))) | ||
| 705 | (unless arg | ||
| 706 | (pop-to-buffer buffer)) | ||
| 707 | (unless (comint-check-proc buffer) | ||
| 708 | (with-current-buffer buffer | ||
| 709 | (inferior-octave-startup) | ||
| 710 | (inferior-octave-mode))) | ||
| 711 | buffer)) | ||
| 712 | |||
| 713 | ;;;###autoload | ||
| 714 | (defalias 'run-octave 'inferior-octave) | ||
| 715 | |||
| 716 | (defun inferior-octave-startup () | ||
| 717 | "Start an inferior Octave process." | ||
| 718 | (let ((proc (comint-exec-1 | ||
| 719 | (substring inferior-octave-buffer 1 -1) | ||
| 720 | inferior-octave-buffer | ||
| 721 | inferior-octave-program | ||
| 722 | (append (list "-i" "--no-line-editing") | ||
| 723 | ;; --no-gui is introduced in Octave > 3.7 | ||
| 724 | (when (zerop (process-file inferior-octave-program | ||
| 725 | nil nil nil | ||
| 726 | "--no-gui" "--help")) | ||
| 727 | (list "--no-gui")) | ||
| 728 | inferior-octave-startup-args)))) | ||
| 729 | (set-process-filter proc 'inferior-octave-output-digest) | ||
| 730 | (setq inferior-octave-process proc | ||
| 731 | inferior-octave-output-list nil | ||
| 732 | inferior-octave-output-string nil | ||
| 733 | inferior-octave-receive-in-progress t) | ||
| 734 | |||
| 735 | ;; This may look complicated ... However, we need to make sure that | ||
| 736 | ;; we additional startup code only AFTER Octave is ready (otherwise, | ||
| 737 | ;; output may be mixed up). Hence, we need to digest the Octave | ||
| 738 | ;; output to see when it issues a prompt. | ||
| 739 | (while inferior-octave-receive-in-progress | ||
| 740 | (or (process-live-p inferior-octave-process) | ||
| 741 | (error "Process `%s' died" inferior-octave-process)) | ||
| 742 | (accept-process-output inferior-octave-process)) | ||
| 743 | (goto-char (point-max)) | ||
| 744 | (set-marker (process-mark proc) (point)) | ||
| 745 | (insert-before-markers | ||
| 746 | (concat | ||
| 747 | (if (not (bobp)) "\n") | ||
| 748 | (if inferior-octave-output-list | ||
| 749 | (concat (mapconcat | ||
| 750 | 'identity inferior-octave-output-list "\n") | ||
| 751 | "\n")))) | ||
| 752 | |||
| 753 | ;; An empty secondary prompt, as e.g. obtained by '--braindead', | ||
| 754 | ;; means trouble. | ||
| 755 | (inferior-octave-send-list-and-digest (list "PS2\n")) | ||
| 756 | (when (string-match "\\(PS2\\|ans\\) = *$" | ||
| 757 | (car inferior-octave-output-list)) | ||
| 758 | (inferior-octave-send-list-and-digest (list "PS2 (\"> \");\n"))) | ||
| 759 | |||
| 760 | (inferior-octave-send-list-and-digest | ||
| 761 | (list "disp(getenv(\"OCTAVE_SRCDIR\"))\n")) | ||
| 762 | (process-put proc 'octave-srcdir | ||
| 763 | (unless (equal (car inferior-octave-output-list) "") | ||
| 764 | (car inferior-octave-output-list))) | ||
| 765 | |||
| 766 | ;; O.K., now we are ready for the Inferior Octave startup commands. | ||
| 767 | (inferior-octave-send-list-and-digest | ||
| 768 | (list "more off;\n" | ||
| 769 | (unless (equal inferior-octave-output-string ">> ") | ||
| 770 | "PS1 (\"\\\\s> \");\n") | ||
| 771 | (when (and inferior-octave-startup-file | ||
| 772 | (file-exists-p inferior-octave-startup-file)) | ||
| 773 | (format "source (\"%s\");\n" inferior-octave-startup-file)))) | ||
| 774 | (when inferior-octave-output-list | ||
| 775 | (insert-before-markers | ||
| 776 | (mapconcat 'identity inferior-octave-output-list "\n"))) | ||
| 777 | |||
| 778 | ;; And finally, everything is back to normal. | ||
| 779 | (set-process-filter proc 'comint-output-filter) | ||
| 780 | ;; Just in case, to be sure a cd in the startup file | ||
| 781 | ;; won't have detrimental effects. | ||
| 782 | (inferior-octave-resync-dirs) | ||
| 783 | ;; Generate a proper prompt, which is critical to | ||
| 784 | ;; `comint-history-isearch-backward-regexp'. Bug#14433. | ||
| 785 | (comint-send-string proc "\n"))) | ||
| 786 | |||
| 787 | (defvar inferior-octave-completion-table | ||
| 788 | ;; | ||
| 789 | ;; Use cache to avoid repetitive computation of completions due to | ||
| 790 | ;; bug#11906 - http://debbugs.gnu.org/11906 - which may cause | ||
| 791 | ;; noticeable delay. CACHE: (CMD TIME VALUE). | ||
| 792 | (let ((cache)) | ||
| 793 | (completion-table-dynamic | ||
| 794 | (lambda (command) | ||
| 795 | (unless (and (equal (car cache) command) | ||
| 796 | (< (float-time) (+ 5 (cadr cache)))) | ||
| 797 | (inferior-octave-send-list-and-digest | ||
| 798 | (list (concat "completion_matches (\"" command "\");\n"))) | ||
| 799 | (setq cache (list command (float-time) | ||
| 800 | (delete-consecutive-dups | ||
| 801 | (sort inferior-octave-output-list 'string-lessp))))) | ||
| 802 | (car (cddr cache)))))) | ||
| 803 | |||
| 804 | (defun inferior-octave-completion-at-point () | ||
| 805 | "Return the data to complete the Octave symbol at point." | ||
| 806 | ;; http://debbugs.gnu.org/14300 | ||
| 807 | (let* ((filecomp (string-match-p | ||
| 808 | "/" (or (comint--match-partial-filename) ""))) | ||
| 809 | (end (point)) | ||
| 810 | (start | ||
| 811 | (unless filecomp | ||
| 812 | (save-excursion | ||
| 813 | (skip-syntax-backward "w_" (comint-line-beginning-position)) | ||
| 814 | (point))))) | ||
| 815 | (when (and start (> end start)) | ||
| 816 | (list start end (completion-table-in-turn | ||
| 817 | inferior-octave-completion-table | ||
| 818 | 'comint-completion-file-name-table))))) | ||
| 819 | |||
| 820 | (define-obsolete-function-alias 'inferior-octave-complete | ||
| 821 | 'completion-at-point "24.1") | ||
| 822 | |||
| 823 | (defun inferior-octave-dynamic-list-input-ring () | ||
| 824 | "List the buffer's input history in a help buffer." | ||
| 825 | ;; We cannot use `comint-dynamic-list-input-ring', because it replaces | ||
| 826 | ;; "completion" by "history reference" ... | ||
| 827 | (interactive) | ||
| 828 | (if (or (not (ring-p comint-input-ring)) | ||
| 829 | (ring-empty-p comint-input-ring)) | ||
| 830 | (message "No history") | ||
| 831 | (let ((history nil) | ||
| 832 | (history-buffer " *Input History*") | ||
| 833 | (index (1- (ring-length comint-input-ring))) | ||
| 834 | (conf (current-window-configuration))) | ||
| 835 | ;; We have to build up a list ourselves from the ring vector. | ||
| 836 | (while (>= index 0) | ||
| 837 | (setq history (cons (ring-ref comint-input-ring index) history) | ||
| 838 | index (1- index))) | ||
| 839 | ;; Change "completion" to "history reference" | ||
| 840 | ;; to make the display accurate. | ||
| 841 | (with-output-to-temp-buffer history-buffer | ||
| 842 | (display-completion-list history) | ||
| 843 | (set-buffer history-buffer)) | ||
| 844 | (message "Hit space to flush") | ||
| 845 | (let ((ch (read-event))) | ||
| 846 | (if (eq ch ?\ ) | ||
| 847 | (set-window-configuration conf) | ||
| 848 | (setq unread-command-events (list ch))))))) | ||
| 849 | |||
| 850 | (defun inferior-octave-output-digest (_proc string) | ||
| 851 | "Special output filter for the inferior Octave process. | ||
| 852 | Save all output between newlines into `inferior-octave-output-list', and | ||
| 853 | the rest to `inferior-octave-output-string'." | ||
| 854 | (setq string (concat inferior-octave-output-string string)) | ||
| 855 | (while (string-match "\n" string) | ||
| 856 | (setq inferior-octave-output-list | ||
| 857 | (append inferior-octave-output-list | ||
| 858 | (list (substring string 0 (match-beginning 0)))) | ||
| 859 | string (substring string (match-end 0)))) | ||
| 860 | (if (string-match inferior-octave-prompt string) | ||
| 861 | (setq inferior-octave-receive-in-progress nil)) | ||
| 862 | (setq inferior-octave-output-string string)) | ||
| 863 | |||
| 864 | (defun inferior-octave-check-process () | ||
| 865 | (or (and inferior-octave-process | ||
| 866 | (process-live-p inferior-octave-process)) | ||
| 867 | (error (substitute-command-keys | ||
| 868 | "No inferior octave process running. Type \\[run-octave]")))) | ||
| 869 | |||
| 870 | (defun inferior-octave-send-list-and-digest (list) | ||
| 871 | "Send LIST to the inferior Octave process and digest the output. | ||
| 872 | The elements of LIST have to be strings and are sent one by one. All | ||
| 873 | output is passed to the filter `inferior-octave-output-digest'." | ||
| 874 | (inferior-octave-check-process) | ||
| 875 | (let* ((proc inferior-octave-process) | ||
| 876 | (filter (process-filter proc)) | ||
| 877 | string) | ||
| 878 | (set-process-filter proc 'inferior-octave-output-digest) | ||
| 879 | (setq inferior-octave-output-list nil) | ||
| 880 | (unwind-protect | ||
| 881 | (while (setq string (car list)) | ||
| 882 | (setq inferior-octave-output-string nil | ||
| 883 | inferior-octave-receive-in-progress t) | ||
| 884 | (comint-send-string proc string) | ||
| 885 | (while inferior-octave-receive-in-progress | ||
| 886 | (accept-process-output proc)) | ||
| 887 | (setq list (cdr list))) | ||
| 888 | (set-process-filter proc filter)))) | ||
| 889 | |||
| 890 | (defvar inferior-octave-directory-tracker-resync nil) | ||
| 891 | (make-variable-buffer-local 'inferior-octave-directory-tracker-resync) | ||
| 892 | |||
| 893 | (defun inferior-octave-directory-tracker (string) | ||
| 894 | "Tracks `cd' commands issued to the inferior Octave process. | ||
| 895 | Use \\[inferior-octave-resync-dirs] to resync if Emacs gets confused." | ||
| 896 | (when inferior-octave-directory-tracker-resync | ||
| 897 | (setq inferior-octave-directory-tracker-resync nil) | ||
| 898 | (inferior-octave-resync-dirs)) | ||
| 899 | (cond | ||
| 900 | ((string-match "^[ \t]*cd[ \t;]*$" string) | ||
| 901 | (cd "~")) | ||
| 902 | ((string-match "^[ \t]*cd[ \t]+\\([^ \t\n;]*\\)[ \t\n;]*" string) | ||
| 903 | (condition-case err | ||
| 904 | (cd (match-string 1 string)) | ||
| 905 | (error (setq inferior-octave-directory-tracker-resync t) | ||
| 906 | (message "%s: `%s'" | ||
| 907 | (error-message-string err) | ||
| 908 | (match-string 1 string))))))) | ||
| 909 | |||
| 910 | (defun inferior-octave-resync-dirs () | ||
| 911 | "Resync the buffer's idea of the current directory. | ||
| 912 | This command queries the inferior Octave process about its current | ||
| 913 | directory and makes this the current buffer's default directory." | ||
| 914 | (interactive) | ||
| 915 | (inferior-octave-send-list-and-digest '("disp (pwd ())\n")) | ||
| 916 | (cd (car inferior-octave-output-list))) | ||
| 917 | |||
| 918 | (defcustom inferior-octave-minimal-columns 80 | ||
| 919 | "The minimal column width for the inferior Octave process." | ||
| 920 | :type 'integer | ||
| 921 | :group 'octave | ||
| 922 | :version "24.4") | ||
| 923 | |||
| 924 | (defvar inferior-octave-last-column-width nil) | ||
| 925 | |||
| 926 | (defun inferior-octave-track-window-width-change () | ||
| 927 | ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572 | ||
| 928 | (let ((width (max inferior-octave-minimal-columns (window-width)))) | ||
| 929 | (unless (eq inferior-octave-last-column-width width) | ||
| 930 | (setq-local inferior-octave-last-column-width width) | ||
| 931 | (when (and inferior-octave-process | ||
| 932 | (process-live-p inferior-octave-process)) | ||
| 933 | (inferior-octave-send-list-and-digest | ||
| 934 | (list (format "putenv(\"COLUMNS\", \"%s\");\n" width))))))) | ||
| 935 | |||
| 936 | |||
| 937 | ;;; Miscellaneous useful functions | ||
| 938 | |||
| 939 | (defun octave-in-comment-p () | ||
| 940 | "Return non-nil if point is inside an Octave comment." | ||
| 941 | (nth 4 (syntax-ppss))) | ||
| 942 | |||
| 943 | (defun octave-in-string-p () | ||
| 944 | "Return non-nil if point is inside an Octave string." | ||
| 945 | (nth 3 (syntax-ppss))) | ||
| 946 | |||
| 947 | (defun octave-in-string-or-comment-p () | ||
| 948 | "Return non-nil if point is inside an Octave string or comment." | ||
| 949 | (nth 8 (syntax-ppss))) | ||
| 950 | |||
| 951 | (defun octave-looking-at-kw (regexp) | ||
| 952 | "Like `looking-at', but sets `case-fold-search' nil." | ||
| 953 | (let ((case-fold-search nil)) | ||
| 954 | (looking-at regexp))) | ||
| 955 | |||
| 956 | (defun octave-maybe-insert-continuation-string () | ||
| 957 | (if (or (octave-in-comment-p) | ||
| 958 | (save-excursion | ||
| 959 | (beginning-of-line) | ||
| 960 | (looking-at octave-continuation-regexp))) | ||
| 961 | nil | ||
| 962 | (delete-horizontal-space) | ||
| 963 | (insert (concat " " octave-continuation-string)))) | ||
| 964 | |||
| 965 | (defun octave-completing-read () | ||
| 966 | (let ((def (or (thing-at-point 'symbol) | ||
| 967 | (save-excursion | ||
| 968 | (skip-syntax-backward "-(") | ||
| 969 | (thing-at-point 'symbol))))) | ||
| 970 | (completing-read | ||
| 971 | (format (if def "Function (default %s): " | ||
| 972 | "Function: ") def) | ||
| 973 | inferior-octave-completion-table | ||
| 974 | nil nil nil nil def))) | ||
| 975 | |||
| 976 | (defun octave-goto-function-definition (fn) | ||
| 977 | "Go to the function definition of FN in current buffer." | ||
| 978 | (goto-char (point-min)) | ||
| 979 | (let ((search | ||
| 980 | (lambda (re sub) | ||
| 981 | (let (done) | ||
| 982 | (while (and (not done) (re-search-forward re nil t)) | ||
| 983 | (when (and (equal (match-string sub) fn) | ||
| 984 | (not (nth 8 (syntax-ppss)))) | ||
| 985 | (setq done t))) | ||
| 986 | (or done (goto-char (point-min))))))) | ||
| 987 | (pcase (file-name-extension (buffer-file-name)) | ||
| 988 | (`"cc" (funcall search | ||
| 989 | "\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1)) | ||
| 990 | (t (funcall search octave-function-header-regexp 3))))) | ||
| 991 | |||
| 992 | (defun octave-function-file-p () | ||
| 993 | "Return non-nil if the first token is \"function\". | ||
| 994 | The value is (START END NAME-START NAME-END) of the function." | ||
| 995 | (save-excursion | ||
| 996 | (goto-char (point-min)) | ||
| 997 | (when (equal (funcall smie-forward-token-function) "function") | ||
| 998 | (forward-word -1) | ||
| 999 | (let* ((start (point)) | ||
| 1000 | (end (progn (forward-sexp 1) (point))) | ||
| 1001 | (name (when (progn | ||
| 1002 | (goto-char start) | ||
| 1003 | (re-search-forward octave-function-header-regexp | ||
| 1004 | end t)) | ||
| 1005 | (list (match-beginning 3) (match-end 3))))) | ||
| 1006 | (cons start (cons end name)))))) | ||
| 1007 | |||
| 1008 | ;; Like forward-comment but stop at non-comment blank | ||
| 1009 | (defun octave-skip-comment-forward (limit) | ||
| 1010 | (let ((ppss (syntax-ppss))) | ||
| 1011 | (if (nth 4 ppss) | ||
| 1012 | (goto-char (nth 8 ppss)) | ||
| 1013 | (goto-char (or (comment-search-forward limit t) (point))))) | ||
| 1014 | (while (and (< (point) limit) (looking-at-p "\\s<")) | ||
| 1015 | (forward-comment 1))) | ||
| 1016 | |||
| 1017 | ;;; First non-copyright comment block | ||
| 1018 | (defun octave-function-file-comment () | ||
| 1019 | "Beginning and end positions of the function file comment." | ||
| 1020 | (save-excursion | ||
| 1021 | (goto-char (point-min)) | ||
| 1022 | ;; Copyright block: octave/libinterp/parse-tree/lex.ll around line 1634 | ||
| 1023 | (while (save-excursion | ||
| 1024 | (when (comment-search-forward (point-max) t) | ||
| 1025 | (when (eq (char-after) ?\{) ; case of block comment | ||
| 1026 | (forward-char 1)) | ||
| 1027 | (skip-syntax-forward "-") | ||
| 1028 | (let ((case-fold-search t)) | ||
| 1029 | (looking-at-p "\\(?:copyright\\|author\\)\\_>")))) | ||
| 1030 | (octave-skip-comment-forward (point-max))) | ||
| 1031 | (let ((beg (comment-search-forward (point-max) t))) | ||
| 1032 | (when beg | ||
| 1033 | (goto-char beg) | ||
| 1034 | (octave-skip-comment-forward (point-max)) | ||
| 1035 | (list beg (point)))))) | ||
| 1036 | |||
| 1037 | (defun octave-sync-function-file-names () | ||
| 1038 | "Ensure function name agree with function file name. | ||
| 1039 | See Info node `(octave)Function Files'." | ||
| 1040 | (interactive) | ||
| 1041 | (when buffer-file-name | ||
| 1042 | (pcase-let ((`(,start ,_end ,name-start ,name-end) | ||
| 1043 | (octave-function-file-p))) | ||
| 1044 | (when (and start name-start) | ||
| 1045 | (let* ((func (buffer-substring name-start name-end)) | ||
| 1046 | (file (file-name-sans-extension | ||
| 1047 | (file-name-nondirectory buffer-file-name))) | ||
| 1048 | (help-form (format "\ | ||
| 1049 | a: Use function name `%s' | ||
| 1050 | b: Use file name `%s' | ||
| 1051 | q: Don't fix\n" func file)) | ||
| 1052 | (c (unless (equal file func) | ||
| 1053 | (save-window-excursion | ||
| 1054 | (help-form-show) | ||
| 1055 | (read-char-choice | ||
| 1056 | "Which name to use? (a/b/q) " '(?a ?b ?q)))))) | ||
| 1057 | (pcase c | ||
| 1058 | (`?a (let ((newname (expand-file-name | ||
| 1059 | (concat func (file-name-extension | ||
| 1060 | buffer-file-name t))))) | ||
| 1061 | (when (or (not (file-exists-p newname)) | ||
| 1062 | (yes-or-no-p | ||
| 1063 | (format "Target file %s exists; proceed? " newname))) | ||
| 1064 | (when (file-exists-p buffer-file-name) | ||
| 1065 | (rename-file buffer-file-name newname t)) | ||
| 1066 | (set-visited-file-name newname)))) | ||
| 1067 | (`?b (save-excursion | ||
| 1068 | (goto-char name-start) | ||
| 1069 | (delete-region name-start name-end) | ||
| 1070 | (insert file))))))))) | ||
| 1071 | |||
| 1072 | (defun octave-update-function-file-comment (beg end) | ||
| 1073 | "Query replace function names in function file comment." | ||
| 1074 | (interactive | ||
| 1075 | (progn | ||
| 1076 | (barf-if-buffer-read-only) | ||
| 1077 | (if (use-region-p) | ||
| 1078 | (list (region-beginning) (region-end)) | ||
| 1079 | (or (octave-function-file-comment) | ||
| 1080 | (error "No function file comment found"))))) | ||
| 1081 | (save-excursion | ||
| 1082 | (let* ((bounds (or (octave-function-file-p) | ||
| 1083 | (error "Not in a function file buffer"))) | ||
| 1084 | (func (if (cddr bounds) | ||
| 1085 | (apply #'buffer-substring (cddr bounds)) | ||
| 1086 | (error "Function name not found"))) | ||
| 1087 | (old-func (progn | ||
| 1088 | (goto-char beg) | ||
| 1089 | (when (re-search-forward | ||
| 1090 | "[=}]\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>" | ||
| 1091 | (min (line-end-position 4) end) | ||
| 1092 | t) | ||
| 1093 | (match-string 1)))) | ||
| 1094 | (old-func (read-string (format (if old-func | ||
| 1095 | "Name to replace (default %s): " | ||
| 1096 | "Name to replace: ") | ||
| 1097 | old-func) | ||
| 1098 | nil nil old-func))) | ||
| 1099 | (if (and func old-func (not (equal func old-func))) | ||
| 1100 | (perform-replace old-func func 'query | ||
| 1101 | nil 'delimited nil nil beg end) | ||
| 1102 | (message "Function names match"))))) | ||
| 1103 | |||
| 1104 | (defface octave-function-comment-block | ||
| 1105 | '((t (:inherit font-lock-doc-face))) | ||
| 1106 | "Face used to highlight function comment block." | ||
| 1107 | :group 'octave) | ||
| 1108 | |||
| 1109 | (eval-when-compile (require 'texinfo)) | ||
| 1110 | |||
| 1111 | (defun octave-font-lock-texinfo-comment () | ||
| 1112 | (let ((kws | ||
| 1113 | (eval-when-compile | ||
| 1114 | (delq nil (mapcar | ||
| 1115 | (lambda (kw) | ||
| 1116 | (if (numberp (nth 1 kw)) | ||
| 1117 | `(,(nth 0 kw) ,(nth 1 kw) ,(nth 2 kw) prepend) | ||
| 1118 | (message "Ignoring Texinfo highlight: %S" kw))) | ||
| 1119 | texinfo-font-lock-keywords))))) | ||
| 1120 | (font-lock-add-keywords | ||
| 1121 | nil | ||
| 1122 | `((,(lambda (limit) | ||
| 1123 | (while (and (< (point) limit) | ||
| 1124 | (search-forward "-*- texinfo -*-" limit t) | ||
| 1125 | (octave-in-comment-p)) | ||
| 1126 | (let ((beg (nth 8 (syntax-ppss))) | ||
| 1127 | (end (progn | ||
| 1128 | (octave-skip-comment-forward (point-max)) | ||
| 1129 | (point)))) | ||
| 1130 | (put-text-property beg end 'font-lock-multiline t) | ||
| 1131 | (font-lock-prepend-text-property | ||
| 1132 | beg end 'face 'octave-function-comment-block) | ||
| 1133 | (dolist (kw kws) | ||
| 1134 | (goto-char beg) | ||
| 1135 | (while (re-search-forward (car kw) end 'move) | ||
| 1136 | (font-lock-apply-highlight (cdr kw)))))) | ||
| 1137 | nil))) | ||
| 1138 | 'append))) | ||
| 1139 | |||
| 1140 | |||
| 1141 | ;;; Indentation | ||
| 1142 | |||
| 1143 | (defun octave-indent-new-comment-line (&optional soft) | ||
| 1144 | ;; FIXME: C-M-j should probably be bound globally to a function like | ||
| 1145 | ;; this one. | ||
| 1146 | "Break Octave line at point, continuing comment if within one. | ||
| 1147 | Insert `octave-continuation-string' before breaking the line | ||
| 1148 | unless inside a list. Signal an error if within a single-quoted | ||
| 1149 | string." | ||
| 1150 | (interactive) | ||
| 1151 | (funcall comment-line-break-function soft)) | ||
| 1152 | |||
| 1153 | (defun octave--indent-new-comment-line (orig &rest args) | ||
| 1154 | (cond | ||
| 1155 | ((octave-in-comment-p) nil) | ||
| 1156 | ((eq (octave-in-string-p) ?') | ||
| 1157 | (error "Cannot split a single-quoted string")) | ||
| 1158 | ((eq (octave-in-string-p) ?\") | ||
| 1159 | (insert octave-continuation-string)) | ||
| 1160 | (t | ||
| 1161 | (delete-horizontal-space) | ||
| 1162 | (unless (and (cadr (syntax-ppss)) | ||
| 1163 | (eq (char-after (cadr (syntax-ppss))) ?\()) | ||
| 1164 | (insert " " octave-continuation-string)))) | ||
| 1165 | (apply orig args) | ||
| 1166 | (indent-according-to-mode)) | ||
| 1167 | |||
| 1168 | (define-obsolete-function-alias | ||
| 1169 | 'octave-indent-defun 'prog-indent-sexp "24.4") | ||
| 1170 | |||
| 1171 | |||
| 1172 | ;;; Motion | ||
| 1173 | (defun octave-next-code-line (&optional arg) | ||
| 1174 | "Move ARG lines of Octave code forward (backward if ARG is negative). | ||
| 1175 | Skips past all empty and comment lines. Default for ARG is 1. | ||
| 1176 | |||
| 1177 | On success, return 0. Otherwise, go as far as possible and return -1." | ||
| 1178 | (interactive "p") | ||
| 1179 | (or arg (setq arg 1)) | ||
| 1180 | (beginning-of-line) | ||
| 1181 | (let ((n 0) | ||
| 1182 | (inc (if (> arg 0) 1 -1))) | ||
| 1183 | (while (and (/= arg 0) (= n 0)) | ||
| 1184 | (setq n (forward-line inc)) | ||
| 1185 | (while (and (= n 0) | ||
| 1186 | (looking-at "\\s-*\\($\\|\\s<\\)")) | ||
| 1187 | (setq n (forward-line inc))) | ||
| 1188 | (setq arg (- arg inc))) | ||
| 1189 | n)) | ||
| 1190 | |||
| 1191 | (defun octave-previous-code-line (&optional arg) | ||
| 1192 | "Move ARG lines of Octave code backward (forward if ARG is negative). | ||
| 1193 | Skips past all empty and comment lines. Default for ARG is 1. | ||
| 1194 | |||
| 1195 | On success, return 0. Otherwise, go as far as possible and return -1." | ||
| 1196 | (interactive "p") | ||
| 1197 | (or arg (setq arg 1)) | ||
| 1198 | (octave-next-code-line (- arg))) | ||
| 1199 | |||
| 1200 | (defun octave-beginning-of-line () | ||
| 1201 | "Move point to beginning of current Octave line. | ||
| 1202 | If on an empty or comment line, go to the beginning of that line. | ||
| 1203 | Otherwise, move backward to the beginning of the first Octave code line | ||
| 1204 | which is not inside a continuation statement, i.e., which does not | ||
| 1205 | follow a code line ending with `...' or is inside an open | ||
| 1206 | parenthesis list." | ||
| 1207 | (interactive) | ||
| 1208 | (beginning-of-line) | ||
| 1209 | (unless (looking-at "\\s-*\\($\\|\\s<\\)") | ||
| 1210 | (while (or (when (cadr (syntax-ppss)) | ||
| 1211 | (goto-char (cadr (syntax-ppss))) | ||
| 1212 | (beginning-of-line) | ||
| 1213 | t) | ||
| 1214 | (and (or (looking-at "\\s-*\\($\\|\\s<\\)") | ||
| 1215 | (save-excursion | ||
| 1216 | (if (zerop (octave-previous-code-line)) | ||
| 1217 | (looking-at octave-continuation-regexp)))) | ||
| 1218 | (zerop (forward-line -1))))))) | ||
| 1219 | |||
| 1220 | (defun octave-end-of-line () | ||
| 1221 | "Move point to end of current Octave line. | ||
| 1222 | If on an empty or comment line, go to the end of that line. | ||
| 1223 | Otherwise, move forward to the end of the first Octave code line which | ||
| 1224 | does not end with `...' or is inside an open parenthesis list." | ||
| 1225 | (interactive) | ||
| 1226 | (end-of-line) | ||
| 1227 | (unless (save-excursion | ||
| 1228 | (beginning-of-line) | ||
| 1229 | (looking-at "\\s-*\\($\\|\\s<\\)")) | ||
| 1230 | (while (or (when (cadr (syntax-ppss)) | ||
| 1231 | (condition-case nil | ||
| 1232 | (progn | ||
| 1233 | (up-list 1) | ||
| 1234 | (end-of-line) | ||
| 1235 | t) | ||
| 1236 | (error nil))) | ||
| 1237 | (and (save-excursion | ||
| 1238 | (beginning-of-line) | ||
| 1239 | (or (looking-at "\\s-*\\($\\|\\s<\\)") | ||
| 1240 | (looking-at octave-continuation-regexp))) | ||
| 1241 | (zerop (forward-line 1))))) | ||
| 1242 | (end-of-line))) | ||
| 1243 | |||
| 1244 | (defun octave-mark-block () | ||
| 1245 | "Put point at the beginning of this Octave block, mark at the end. | ||
| 1246 | The block marked is the one that contains point or follows point." | ||
| 1247 | (interactive) | ||
| 1248 | (if (and (looking-at "\\sw\\|\\s_") | ||
| 1249 | (looking-back "\\sw\\|\\s_" (1- (point)))) | ||
| 1250 | (skip-syntax-forward "w_")) | ||
| 1251 | (unless (or (looking-at "\\s(") | ||
| 1252 | (save-excursion | ||
| 1253 | (let* ((token (funcall smie-forward-token-function)) | ||
| 1254 | (level (assoc token smie-grammar))) | ||
| 1255 | (and level (not (numberp (cadr level))))))) | ||
| 1256 | (backward-up-list 1)) | ||
| 1257 | (mark-sexp)) | ||
| 1258 | |||
| 1259 | (defun octave-beginning-of-defun (&optional arg) | ||
| 1260 | "Octave-specific `beginning-of-defun-function' (which see)." | ||
| 1261 | (or arg (setq arg 1)) | ||
| 1262 | ;; Move out of strings or comments. | ||
| 1263 | (when (octave-in-string-or-comment-p) | ||
| 1264 | (goto-char (octave-in-string-or-comment-p))) | ||
| 1265 | (letrec ((orig (point)) | ||
| 1266 | (toplevel (lambda (pos) | ||
| 1267 | (condition-case nil | ||
| 1268 | (progn | ||
| 1269 | (backward-up-list 1) | ||
| 1270 | (funcall toplevel (point))) | ||
| 1271 | (scan-error pos))))) | ||
| 1272 | (goto-char (funcall toplevel (point))) | ||
| 1273 | (when (and (> arg 0) (/= orig (point))) | ||
| 1274 | (setq arg (1- arg))) | ||
| 1275 | (forward-sexp (- arg)) | ||
| 1276 | (and (< arg 0) (forward-sexp -1)) | ||
| 1277 | (/= orig (point)))) | ||
| 1278 | |||
| 1279 | (defun octave-fill-paragraph (&optional _arg) | ||
| 1280 | "Fill paragraph of Octave code, handling Octave comments." | ||
| 1281 | ;; FIXME: difference with generic fill-paragraph: | ||
| 1282 | ;; - code lines are only split, never joined. | ||
| 1283 | ;; - \n that end comments are never removed. | ||
| 1284 | ;; - insert continuation marker when splitting code lines. | ||
| 1285 | (interactive "P") | ||
| 1286 | (save-excursion | ||
| 1287 | (let ((end (progn (forward-paragraph) (copy-marker (point) t))) | ||
| 1288 | (beg (progn | ||
| 1289 | (forward-paragraph -1) | ||
| 1290 | (skip-chars-forward " \t\n") | ||
| 1291 | (beginning-of-line) | ||
| 1292 | (point))) | ||
| 1293 | (cfc (current-fill-column)) | ||
| 1294 | comment-prefix) | ||
| 1295 | (goto-char beg) | ||
| 1296 | (while (< (point) end) | ||
| 1297 | (condition-case nil | ||
| 1298 | (indent-according-to-mode) | ||
| 1299 | (error nil)) | ||
| 1300 | (move-to-column cfc) | ||
| 1301 | ;; First check whether we need to combine non-empty comment lines | ||
| 1302 | (if (and (< (current-column) cfc) | ||
| 1303 | (octave-in-comment-p) | ||
| 1304 | (not (save-excursion | ||
| 1305 | (beginning-of-line) | ||
| 1306 | (looking-at "^\\s-*\\s<+\\s-*$")))) | ||
| 1307 | ;; This is a nonempty comment line which does not extend | ||
| 1308 | ;; past the fill column. If it is followed by a nonempty | ||
| 1309 | ;; comment line with the same comment prefix, try to | ||
| 1310 | ;; combine them, and repeat this until either we reach the | ||
| 1311 | ;; fill-column or there is nothing more to combine. | ||
| 1312 | (progn | ||
| 1313 | ;; Get the comment prefix | ||
| 1314 | (save-excursion | ||
| 1315 | (beginning-of-line) | ||
| 1316 | (while (and (re-search-forward "\\s<+") | ||
| 1317 | (not (octave-in-comment-p)))) | ||
| 1318 | (setq comment-prefix (match-string 0))) | ||
| 1319 | ;; And keep combining ... | ||
| 1320 | (while (and (< (current-column) cfc) | ||
| 1321 | (save-excursion | ||
| 1322 | (forward-line 1) | ||
| 1323 | (and (looking-at | ||
| 1324 | (concat "^\\s-*" | ||
| 1325 | comment-prefix | ||
| 1326 | "\\S<")) | ||
| 1327 | (not (looking-at | ||
| 1328 | (concat "^\\s-*" | ||
| 1329 | comment-prefix | ||
| 1330 | "\\s-*$")))))) | ||
| 1331 | (delete-char 1) | ||
| 1332 | (re-search-forward comment-prefix) | ||
| 1333 | (delete-region (match-beginning 0) (match-end 0)) | ||
| 1334 | (fixup-whitespace) | ||
| 1335 | (move-to-column cfc)))) | ||
| 1336 | ;; We might also try to combine continued code lines> Perhaps | ||
| 1337 | ;; some other time ... | ||
| 1338 | (skip-chars-forward "^ \t\n") | ||
| 1339 | (delete-horizontal-space) | ||
| 1340 | (if (or (< (current-column) cfc) | ||
| 1341 | (and (= (current-column) cfc) (eolp))) | ||
| 1342 | (forward-line 1) | ||
| 1343 | (if (not (eolp)) (insert " ")) | ||
| 1344 | (or (funcall normal-auto-fill-function) | ||
| 1345 | (forward-line 1)))) | ||
| 1346 | t))) | ||
| 1347 | |||
| 1348 | ;;; Completions | ||
| 1349 | |||
| 1350 | (defun octave-completion-at-point () | ||
| 1351 | "Find the text to complete and the corresponding table." | ||
| 1352 | (let* ((beg (save-excursion (skip-syntax-backward "w_") (point))) | ||
| 1353 | (end (point))) | ||
| 1354 | (if (< beg (point)) | ||
| 1355 | ;; Extend region past point, if applicable. | ||
| 1356 | (save-excursion (skip-syntax-forward "w_") | ||
| 1357 | (setq end (point)))) | ||
| 1358 | (when (> end beg) | ||
| 1359 | (list beg end (or (and inferior-octave-process | ||
| 1360 | (process-live-p inferior-octave-process) | ||
| 1361 | inferior-octave-completion-table) | ||
| 1362 | octave-reserved-words))))) | ||
| 1363 | |||
| 1364 | (define-obsolete-function-alias 'octave-complete-symbol | ||
| 1365 | 'completion-at-point "24.1") | ||
| 1366 | |||
| 1367 | ;;; Electric characters && friends | ||
| 1368 | (define-skeleton octave-insert-defun | ||
| 1369 | "Insert an Octave function skeleton. | ||
| 1370 | Prompt for the function's name, arguments and return values (to be | ||
| 1371 | entered without parens)." | ||
| 1372 | (let* ((defname (file-name-sans-extension (buffer-name))) | ||
| 1373 | (name (read-string (format "Function name (default %s): " defname) | ||
| 1374 | nil nil defname)) | ||
| 1375 | (args (read-string "Arguments: ")) | ||
| 1376 | (vals (read-string "Return values: "))) | ||
| 1377 | (format "%s%s (%s)" | ||
| 1378 | (cond | ||
| 1379 | ((string-equal vals "") vals) | ||
| 1380 | ((string-match "[ ,]" vals) (concat "[" vals "] = ")) | ||
| 1381 | (t (concat vals " = "))) | ||
| 1382 | name | ||
| 1383 | args)) | ||
| 1384 | \n octave-block-comment-start "usage: " str \n | ||
| 1385 | octave-block-comment-start '(delete-horizontal-space) \n | ||
| 1386 | octave-block-comment-start '(delete-horizontal-space) \n | ||
| 1387 | "function " > str \n | ||
| 1388 | _ \n | ||
| 1389 | "endfunction" > \n) | ||
| 1390 | |||
| 1391 | ;;; Communication with the inferior Octave process | ||
| 1392 | (defun octave-kill-process () | ||
| 1393 | "Kill inferior Octave process and its buffer." | ||
| 1394 | (interactive) | ||
| 1395 | (if inferior-octave-process | ||
| 1396 | (progn | ||
| 1397 | (process-send-string inferior-octave-process "quit;\n") | ||
| 1398 | (accept-process-output inferior-octave-process))) | ||
| 1399 | (if inferior-octave-buffer | ||
| 1400 | (kill-buffer inferior-octave-buffer))) | ||
| 1401 | |||
| 1402 | (defun octave-show-process-buffer () | ||
| 1403 | "Make sure that `inferior-octave-buffer' is displayed." | ||
| 1404 | (interactive) | ||
| 1405 | (if (get-buffer inferior-octave-buffer) | ||
| 1406 | (display-buffer inferior-octave-buffer) | ||
| 1407 | (message "No buffer named %s" inferior-octave-buffer))) | ||
| 1408 | |||
| 1409 | (defun octave-hide-process-buffer () | ||
| 1410 | "Delete all windows that display `inferior-octave-buffer'." | ||
| 1411 | (interactive) | ||
| 1412 | (if (get-buffer inferior-octave-buffer) | ||
| 1413 | (delete-windows-on inferior-octave-buffer) | ||
| 1414 | (message "No buffer named %s" inferior-octave-buffer))) | ||
| 1415 | |||
| 1416 | (defun octave-send-region (beg end) | ||
| 1417 | "Send current region to the inferior Octave process." | ||
| 1418 | (interactive "r") | ||
| 1419 | (inferior-octave t) | ||
| 1420 | (let ((proc inferior-octave-process) | ||
| 1421 | (string (buffer-substring-no-properties beg end)) | ||
| 1422 | line) | ||
| 1423 | (with-current-buffer inferior-octave-buffer | ||
| 1424 | (setq inferior-octave-output-list nil) | ||
| 1425 | (while (not (string-equal string "")) | ||
| 1426 | (if (string-match "\n" string) | ||
| 1427 | (setq line (substring string 0 (match-beginning 0)) | ||
| 1428 | string (substring string (match-end 0))) | ||
| 1429 | (setq line string string "")) | ||
| 1430 | (setq inferior-octave-receive-in-progress t) | ||
| 1431 | (inferior-octave-send-list-and-digest (list (concat line "\n"))) | ||
| 1432 | (while inferior-octave-receive-in-progress | ||
| 1433 | (accept-process-output proc)) | ||
| 1434 | (insert-before-markers | ||
| 1435 | (mapconcat 'identity | ||
| 1436 | (append | ||
| 1437 | (if octave-send-echo-input (list line) (list "")) | ||
| 1438 | inferior-octave-output-list | ||
| 1439 | (list inferior-octave-output-string)) | ||
| 1440 | "\n"))))) | ||
| 1441 | (if octave-send-show-buffer | ||
| 1442 | (display-buffer inferior-octave-buffer))) | ||
| 1443 | |||
| 1444 | (defun octave-send-block () | ||
| 1445 | "Send current Octave block to the inferior Octave process." | ||
| 1446 | (interactive) | ||
| 1447 | (save-excursion | ||
| 1448 | (octave-mark-block) | ||
| 1449 | (octave-send-region (point) (mark)))) | ||
| 1450 | |||
| 1451 | (defun octave-send-defun () | ||
| 1452 | "Send current Octave function to the inferior Octave process." | ||
| 1453 | (interactive) | ||
| 1454 | (save-excursion | ||
| 1455 | (mark-defun) | ||
| 1456 | (octave-send-region (point) (mark)))) | ||
| 1457 | |||
| 1458 | (defun octave-send-line (&optional arg) | ||
| 1459 | "Send current Octave code line to the inferior Octave process. | ||
| 1460 | With positive prefix ARG, send that many lines. | ||
| 1461 | If `octave-send-line-auto-forward' is non-nil, go to the next unsent | ||
| 1462 | code line." | ||
| 1463 | (interactive "P") | ||
| 1464 | (or arg (setq arg 1)) | ||
| 1465 | (if (> arg 0) | ||
| 1466 | (let (beg end) | ||
| 1467 | (beginning-of-line) | ||
| 1468 | (setq beg (point)) | ||
| 1469 | (octave-next-code-line (- arg 1)) | ||
| 1470 | (end-of-line) | ||
| 1471 | (setq end (point)) | ||
| 1472 | (if octave-send-line-auto-forward | ||
| 1473 | (octave-next-code-line 1)) | ||
| 1474 | (octave-send-region beg end)))) | ||
| 1475 | |||
| 1476 | (defun octave-eval-print-last-sexp () | ||
| 1477 | "Evaluate Octave sexp before point and print value into current buffer." | ||
| 1478 | (interactive) | ||
| 1479 | (inferior-octave t) | ||
| 1480 | (let ((standard-output (current-buffer)) | ||
| 1481 | (print-escape-newlines nil) | ||
| 1482 | (opoint (point))) | ||
| 1483 | (terpri) | ||
| 1484 | (prin1 | ||
| 1485 | (save-excursion | ||
| 1486 | (forward-sexp -1) | ||
| 1487 | (inferior-octave-send-list-and-digest | ||
| 1488 | (list (concat (buffer-substring-no-properties (point) opoint) | ||
| 1489 | "\n"))) | ||
| 1490 | (mapconcat 'identity inferior-octave-output-list "\n"))) | ||
| 1491 | (terpri))) | ||
| 1492 | |||
| 1493 | |||
| 1494 | |||
| 1495 | (defcustom octave-eldoc-message-style 'auto | ||
| 1496 | "Octave eldoc message style: auto, oneline, multiline." | ||
| 1497 | :type '(choice (const :tag "Automatic" auto) | ||
| 1498 | (const :tag "One Line" oneline) | ||
| 1499 | (const :tag "Multi Line" multiline)) | ||
| 1500 | :group 'octave | ||
| 1501 | :version "24.4") | ||
| 1502 | |||
| 1503 | ;; (FN SIGNATURE1 SIGNATURE2 ...) | ||
| 1504 | (defvar octave-eldoc-cache nil) | ||
| 1505 | |||
| 1506 | (defun octave-eldoc-function-signatures (fn) | ||
| 1507 | (unless (equal fn (car octave-eldoc-cache)) | ||
| 1508 | (inferior-octave-send-list-and-digest | ||
| 1509 | (list (format "\ | ||
| 1510 | if ismember(exist(\"%s\"), [2 3 5 103]) print_usage(\"%s\") endif\n" | ||
| 1511 | fn fn))) | ||
| 1512 | (let (result) | ||
| 1513 | (dolist (line inferior-octave-output-list) | ||
| 1514 | (when (string-match | ||
| 1515 | "\\s-*\\(?:--[^:]+\\|usage\\):\\s-*\\(.*\\)$" | ||
| 1516 | line) | ||
| 1517 | (push (match-string 1 line) result))) | ||
| 1518 | (setq octave-eldoc-cache | ||
| 1519 | (cons (substring-no-properties fn) | ||
| 1520 | (nreverse result))))) | ||
| 1521 | (cdr octave-eldoc-cache)) | ||
| 1522 | |||
| 1523 | (defun octave-eldoc-function () | ||
| 1524 | "A function for `eldoc-documentation-function' (which see)." | ||
| 1525 | (when (and inferior-octave-process | ||
| 1526 | (process-live-p inferior-octave-process)) | ||
| 1527 | (let* ((ppss (syntax-ppss)) | ||
| 1528 | (paren-pos (cadr ppss)) | ||
| 1529 | (fn (save-excursion | ||
| 1530 | (if (and paren-pos | ||
| 1531 | ;; PAREN-POS must be after the prompt | ||
| 1532 | (>= paren-pos | ||
| 1533 | (if (eq (get-buffer-process (current-buffer)) | ||
| 1534 | inferior-octave-process) | ||
| 1535 | (process-mark inferior-octave-process) | ||
| 1536 | (point-min))) | ||
| 1537 | (or (not (eq (get-buffer-process (current-buffer)) | ||
| 1538 | inferior-octave-process)) | ||
| 1539 | (< (process-mark inferior-octave-process) | ||
| 1540 | paren-pos)) | ||
| 1541 | (eq (char-after paren-pos) ?\()) | ||
| 1542 | (goto-char paren-pos) | ||
| 1543 | (setq paren-pos nil)) | ||
| 1544 | (when (or (< (skip-syntax-backward "-") 0) paren-pos) | ||
| 1545 | (thing-at-point 'symbol)))) | ||
| 1546 | (sigs (and fn (octave-eldoc-function-signatures fn))) | ||
| 1547 | (oneline (mapconcat 'identity sigs | ||
| 1548 | (propertize " | " 'face 'warning))) | ||
| 1549 | (multiline (mapconcat (lambda (s) (concat "-- " s)) sigs "\n"))) | ||
| 1550 | ;; | ||
| 1551 | ;; Return the value according to style. | ||
| 1552 | (pcase octave-eldoc-message-style | ||
| 1553 | (`auto (if (< (length oneline) (window-width (minibuffer-window))) | ||
| 1554 | oneline | ||
| 1555 | multiline)) | ||
| 1556 | (`oneline oneline) | ||
| 1557 | (`multiline multiline))))) | ||
| 1558 | |||
| 1559 | (defcustom octave-help-buffer "*Octave Help*" | ||
| 1560 | "Buffer name for `octave-help'." | ||
| 1561 | :type 'string | ||
| 1562 | :group 'octave | ||
| 1563 | :version "24.4") | ||
| 1564 | |||
| 1565 | (define-button-type 'octave-help-file | ||
| 1566 | 'follow-link t | ||
| 1567 | 'action #'help-button-action | ||
| 1568 | 'help-function 'octave-find-definition) | ||
| 1569 | |||
| 1570 | (define-button-type 'octave-help-function | ||
| 1571 | 'follow-link t | ||
| 1572 | 'action (lambda (b) | ||
| 1573 | (octave-help | ||
| 1574 | (buffer-substring (button-start b) (button-end b))))) | ||
| 1575 | |||
| 1576 | (defvar octave-help-mode-map | ||
| 1577 | (let ((map (make-sparse-keymap))) | ||
| 1578 | (define-key map "\M-." 'octave-find-definition) | ||
| 1579 | (define-key map "\C-hd" 'octave-help) | ||
| 1580 | map)) | ||
| 1581 | |||
| 1582 | (define-derived-mode octave-help-mode help-mode "OctHelp" | ||
| 1583 | "Major mode for displaying Octave documentation." | ||
| 1584 | :abbrev-table nil | ||
| 1585 | :syntax-table octave-mode-syntax-table | ||
| 1586 | (eval-and-compile (require 'help-mode)) | ||
| 1587 | ;; Mostly stolen from `help-make-xrefs'. | ||
| 1588 | (let ((inhibit-read-only t)) | ||
| 1589 | (setq-local info-lookup-mode 'octave-mode) | ||
| 1590 | ;; Delete extraneous newlines at the end of the docstring | ||
| 1591 | (goto-char (point-max)) | ||
| 1592 | (while (and (not (bobp)) (bolp)) | ||
| 1593 | (delete-char -1)) | ||
| 1594 | (insert "\n") | ||
| 1595 | (when (or help-xref-stack help-xref-forward-stack) | ||
| 1596 | (insert "\n")) | ||
| 1597 | (when help-xref-stack | ||
| 1598 | (help-insert-xref-button help-back-label 'help-back | ||
| 1599 | (current-buffer))) | ||
| 1600 | (when help-xref-forward-stack | ||
| 1601 | (when help-xref-stack | ||
| 1602 | (insert "\t")) | ||
| 1603 | (help-insert-xref-button help-forward-label 'help-forward | ||
| 1604 | (current-buffer))) | ||
| 1605 | (when (or help-xref-stack help-xref-forward-stack) | ||
| 1606 | (insert "\n")))) | ||
| 1607 | |||
| 1608 | (defvar octave-help-mode-finish-hook nil | ||
| 1609 | "Octave specific hook for `temp-buffer-show-hook'.") | ||
| 1610 | |||
| 1611 | (defun octave-help-mode-finish () | ||
| 1612 | (when (eq major-mode 'octave-help-mode) | ||
| 1613 | (run-hooks 'octave-help-mode-finish-hook))) | ||
| 1614 | |||
| 1615 | (add-hook 'temp-buffer-show-hook 'octave-help-mode-finish) | ||
| 1616 | |||
| 1617 | (defun octave-help (fn) | ||
| 1618 | "Display the documentation of FN." | ||
| 1619 | (interactive (list (octave-completing-read))) | ||
| 1620 | (inferior-octave-send-list-and-digest | ||
| 1621 | (list (format "help \"%s\"\n" fn))) | ||
| 1622 | (let ((lines inferior-octave-output-list) | ||
| 1623 | (inhibit-read-only t)) | ||
| 1624 | (when (string-match "error: \\(.*\\)$" (car lines)) | ||
| 1625 | (error "%s" (match-string 1 (car lines)))) | ||
| 1626 | (with-help-window octave-help-buffer | ||
| 1627 | (princ (mapconcat 'identity lines "\n")) | ||
| 1628 | (with-current-buffer octave-help-buffer | ||
| 1629 | ;; Bound to t so that `help-buffer' returns current buffer for | ||
| 1630 | ;; `help-setup-xref'. | ||
| 1631 | (let ((help-xref-following t)) | ||
| 1632 | (help-setup-xref (list 'octave-help fn) | ||
| 1633 | (called-interactively-p 'interactive))) | ||
| 1634 | ;; Note: can be turned off by suppress_verbose_help_message. | ||
| 1635 | ;; | ||
| 1636 | ;; Remove boring trailing text: Additional help for built-in functions | ||
| 1637 | ;; and operators ... | ||
| 1638 | (goto-char (point-max)) | ||
| 1639 | (when (search-backward "\n\n\n" nil t) | ||
| 1640 | (goto-char (match-beginning 0)) | ||
| 1641 | (delete-region (point) (point-max))) | ||
| 1642 | ;; File name highlight | ||
| 1643 | (goto-char (point-min)) | ||
| 1644 | (when (re-search-forward "from the file \\(.*\\)$" | ||
| 1645 | (line-end-position) | ||
| 1646 | t) | ||
| 1647 | (let* ((file (match-string 1)) | ||
| 1648 | (dir (file-name-directory | ||
| 1649 | (directory-file-name (file-name-directory file))))) | ||
| 1650 | (replace-match "" nil nil nil 1) | ||
| 1651 | (insert "`") | ||
| 1652 | ;; Include the parent directory which may be regarded as | ||
| 1653 | ;; the category for the FN. | ||
| 1654 | (help-insert-xref-button (file-relative-name file dir) | ||
| 1655 | 'octave-help-file fn) | ||
| 1656 | (insert "'"))) | ||
| 1657 | ;; Make 'See also' clickable | ||
| 1658 | (with-syntax-table octave-mode-syntax-table | ||
| 1659 | (when (re-search-forward "^\\s-*See also:" nil t) | ||
| 1660 | (let ((end (save-excursion (re-search-forward "^\\s-*$" nil t)))) | ||
| 1661 | (while (re-search-forward "\\_<\\(?:\\sw\\|\\s_\\)+\\_>" end t) | ||
| 1662 | (make-text-button (match-beginning 0) (match-end 0) | ||
| 1663 | :type 'octave-help-function))))) | ||
| 1664 | (octave-help-mode))))) | ||
| 1665 | |||
| 1666 | (defcustom octave-source-directories nil | ||
| 1667 | "A list of directories for Octave sources. | ||
| 1668 | If the environment variable OCTAVE_SRCDIR is set, it is searched first." | ||
| 1669 | :type '(repeat directory) | ||
| 1670 | :group 'octave | ||
| 1671 | :version "24.4") | ||
| 1672 | |||
| 1673 | (defun octave-source-directories () | ||
| 1674 | (let ((srcdir (or (and inferior-octave-process | ||
| 1675 | (process-get inferior-octave-process 'octave-srcdir)) | ||
| 1676 | (getenv "OCTAVE_SRCDIR")))) | ||
| 1677 | (if srcdir | ||
| 1678 | (cons srcdir octave-source-directories) | ||
| 1679 | octave-source-directories))) | ||
| 1680 | |||
| 1681 | (defvar octave-find-definition-filename-function | ||
| 1682 | #'octave-find-definition-default-filename) | ||
| 1683 | |||
| 1684 | (defun octave-find-definition-default-filename (name) | ||
| 1685 | "Default value for `octave-find-definition-filename-function'." | ||
| 1686 | (pcase (file-name-extension name) | ||
| 1687 | (`"oct" | ||
| 1688 | (octave-find-definition-default-filename | ||
| 1689 | (concat "libinterp/dldfcn/" | ||
| 1690 | (file-name-sans-extension (file-name-nondirectory name)) | ||
| 1691 | ".cc"))) | ||
| 1692 | (`"cc" | ||
| 1693 | (let ((file (or (locate-file name (octave-source-directories)) | ||
| 1694 | (locate-file (file-name-nondirectory name) | ||
| 1695 | (octave-source-directories))))) | ||
| 1696 | (or (and file (file-exists-p file)) | ||
| 1697 | (error "File `%s' not found" name)) | ||
| 1698 | file)) | ||
| 1699 | (`"mex" | ||
| 1700 | (if (yes-or-no-p (format "File `%s' may be binary; open? " | ||
| 1701 | (file-name-nondirectory name))) | ||
| 1702 | name | ||
| 1703 | (user-error "Aborted"))) | ||
| 1704 | (t name))) | ||
| 1705 | |||
| 1706 | (defvar find-tag-marker-ring) | ||
| 1707 | |||
| 1708 | (defun octave-find-definition (fn) | ||
| 1709 | "Find the definition of FN. | ||
| 1710 | Functions implemented in C++ can be found if | ||
| 1711 | `octave-source-directories' is set correctly." | ||
| 1712 | (interactive (list (octave-completing-read))) | ||
| 1713 | (inferior-octave-send-list-and-digest | ||
| 1714 | ;; help NAME is more verbose | ||
| 1715 | (list (format "\ | ||
| 1716 | if iskeyword(\"%s\") disp(\"`%s' is a keyword\") else which(\"%s\") endif\n" | ||
| 1717 | fn fn fn))) | ||
| 1718 | (let* ((line (car inferior-octave-output-list)) | ||
| 1719 | (file (when (and line (string-match "from the file \\(.*\\)$" line)) | ||
| 1720 | (match-string 1 line)))) | ||
| 1721 | (if (not file) | ||
| 1722 | (user-error "%s" (or line (format "`%s' not found" fn))) | ||
| 1723 | (require 'etags) | ||
| 1724 | (ring-insert find-tag-marker-ring (point-marker)) | ||
| 1725 | (setq file (funcall octave-find-definition-filename-function file)) | ||
| 1726 | (when file | ||
| 1727 | (find-file file) | ||
| 1728 | (octave-goto-function-definition fn))))) | ||
| 1729 | |||
| 1730 | |||
| 1731 | (provide 'octave) | ||
| 1732 | ;;; octave.el ends here | ||
diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el index 5f78b770936..e608ea8af0e 100644 --- a/lisp/progmodes/opascal.el +++ b/lisp/progmodes/opascal.el | |||
| @@ -110,29 +110,6 @@ end; end;" | |||
| 110 | regardless of where in the line point is when the TAB command is used." | 110 | regardless of where in the line point is when the TAB command is used." |
| 111 | :type 'boolean) | 111 | :type 'boolean) |
| 112 | 112 | ||
| 113 | (define-obsolete-variable-alias | ||
| 114 | 'delphi-comment-face 'opascal-comment-face "24.4") | ||
| 115 | (defcustom opascal-comment-face 'font-lock-comment-face | ||
| 116 | "Face used to color OPascal comments." | ||
| 117 | :type 'face) | ||
| 118 | |||
| 119 | (define-obsolete-variable-alias | ||
| 120 | 'delphi-string-face 'opascal-string-face "24.4") | ||
| 121 | (defcustom opascal-string-face 'font-lock-string-face | ||
| 122 | "Face used to color OPascal strings." | ||
| 123 | :type 'face) | ||
| 124 | |||
| 125 | (define-obsolete-variable-alias | ||
| 126 | 'delphi-keyword-face 'opascal-keyword-face "24.4") | ||
| 127 | (defcustom opascal-keyword-face 'font-lock-keyword-face | ||
| 128 | "Face used to color OPascal keywords." | ||
| 129 | :type 'face) | ||
| 130 | |||
| 131 | (define-obsolete-variable-alias 'delphi-other-face 'opascal-other-face "24.4") | ||
| 132 | (defcustom opascal-other-face nil | ||
| 133 | "Face used to color everything else." | ||
| 134 | :type '(choice (const :tag "None" nil) face)) | ||
| 135 | |||
| 136 | (defconst opascal-directives | 113 | (defconst opascal-directives |
| 137 | '(absolute abstract assembler automated cdecl default dispid dynamic | 114 | '(absolute abstract assembler automated cdecl default dispid dynamic |
| 138 | export external far forward index inline message name near nodefault | 115 | export external far forward index inline message name near nodefault |
| @@ -274,6 +251,21 @@ routine.") | |||
| 274 | (defconst opascal-leading-spaces-re (concat "^" opascal-spaces-re)) | 251 | (defconst opascal-leading-spaces-re (concat "^" opascal-spaces-re)) |
| 275 | (defconst opascal-word-chars "a-zA-Z0-9_") | 252 | (defconst opascal-word-chars "a-zA-Z0-9_") |
| 276 | 253 | ||
| 254 | (defvar opascal-mode-syntax-table | ||
| 255 | (let ((st (make-syntax-table))) | ||
| 256 | ;; Strings. | ||
| 257 | (modify-syntax-entry ?\" "\"" st) | ||
| 258 | (modify-syntax-entry ?\' "\"" st) | ||
| 259 | ;; Comments. | ||
| 260 | (modify-syntax-entry ?\{ "<" st) | ||
| 261 | (modify-syntax-entry ?\} ">" st) | ||
| 262 | (modify-syntax-entry ?\( "()1" st) | ||
| 263 | (modify-syntax-entry ?\) ")(4" st) | ||
| 264 | (modify-syntax-entry ?* ". 23b" st) | ||
| 265 | (modify-syntax-entry ?/ ". 12c" st) | ||
| 266 | (modify-syntax-entry ?\n "> c" st) | ||
| 267 | st)) | ||
| 268 | |||
| 277 | (defmacro opascal-save-excursion (&rest forms) | 269 | (defmacro opascal-save-excursion (&rest forms) |
| 278 | ;; Executes the forms such that any movements have no effect, including | 270 | ;; Executes the forms such that any movements have no effect, including |
| 279 | ;; searches. | 271 | ;; searches. |
| @@ -283,13 +275,6 @@ routine.") | |||
| 283 | (deactivate-mark nil)) | 275 | (deactivate-mark nil)) |
| 284 | (progn ,@forms))))) | 276 | (progn ,@forms))))) |
| 285 | 277 | ||
| 286 | (defmacro opascal-save-state (&rest forms) | ||
| 287 | ;; Executes the forms such that any buffer modifications do not have any side | ||
| 288 | ;; effects beyond the buffer's actual content changes. | ||
| 289 | `(let ((opascal--ignore-changes t)) | ||
| 290 | (with-silent-modifications | ||
| 291 | ,@forms))) | ||
| 292 | |||
| 293 | (defsubst opascal-is (element in-set) | 278 | (defsubst opascal-is (element in-set) |
| 294 | ;; If the element is in the set, the element cdr is returned, otherwise nil. | 279 | ;; If the element is in the set, the element cdr is returned, otherwise nil. |
| 295 | (memq element in-set)) | 280 | (memq element in-set)) |
| @@ -347,13 +332,6 @@ routine.") | |||
| 347 | ;; Returns the column of the point p. | 332 | ;; Returns the column of the point p. |
| 348 | (save-excursion (goto-char p) (current-column))) | 333 | (save-excursion (goto-char p) (current-column))) |
| 349 | 334 | ||
| 350 | (defun opascal-face-of (token-kind) | ||
| 351 | ;; Returns the face property appropriate for the token kind. | ||
| 352 | (cond ((opascal-is token-kind opascal-comments) opascal-comment-face) | ||
| 353 | ((opascal-is token-kind opascal-strings) opascal-string-face) | ||
| 354 | ((opascal-is token-kind opascal-keywords) opascal-keyword-face) | ||
| 355 | (opascal-other-face))) | ||
| 356 | |||
| 357 | (defvar opascal-progress-last-reported-point nil | 335 | (defvar opascal-progress-last-reported-point nil |
| 358 | "The last point at which progress was reported.") | 336 | "The last point at which progress was reported.") |
| 359 | 337 | ||
| @@ -361,8 +339,6 @@ routine.") | |||
| 361 | "Number of chars to process before the next parsing progress report.") | 339 | "Number of chars to process before the next parsing progress report.") |
| 362 | (defconst opascal-scanning-progress-step 2048 | 340 | (defconst opascal-scanning-progress-step 2048 |
| 363 | "Number of chars to process before the next scanning progress report.") | 341 | "Number of chars to process before the next scanning progress report.") |
| 364 | (defconst opascal-fontifying-progress-step opascal-scanning-progress-step | ||
| 365 | "Number of chars to process before the next fontification progress report.") | ||
| 366 | 342 | ||
| 367 | (defun opascal-progress-start () | 343 | (defun opascal-progress-start () |
| 368 | ;; Initializes progress reporting. | 344 | ;; Initializes progress reporting. |
| @@ -400,22 +376,30 @@ routine.") | |||
| 400 | (goto-char curr-point) | 376 | (goto-char curr-point) |
| 401 | next)) | 377 | next)) |
| 402 | 378 | ||
| 403 | (defvar opascal--ignore-changes t | 379 | (defconst opascal--literal-start-re (regexp-opt '("//" "{" "(*" "'" "\""))) |
| 404 | "Internal flag to control if the OPascal mode responds to buffer changes. | ||
| 405 | Defaults to t in case the `opascal-after-change' function is called on a | ||
| 406 | non-OPascal buffer. Set to nil in OPascal buffers. To override, just do: | ||
| 407 | (let ((opascal--ignore-changes t)) ...)") | ||
| 408 | |||
| 409 | (defun opascal-set-text-properties (from to properties) | ||
| 410 | ;; Like `set-text-properties', except we do not consider this to be a buffer | ||
| 411 | ;; modification. | ||
| 412 | (opascal-save-state | ||
| 413 | (set-text-properties from to properties))) | ||
| 414 | 380 | ||
| 415 | (defun opascal-literal-kind (p) | 381 | (defun opascal-literal-kind (p) |
| 416 | ;; Returns the literal kind the point p is in (or nil if not in a literal). | 382 | ;; Returns the literal kind the point p is in (or nil if not in a literal). |
| 417 | (if (and (<= (point-min) p) (<= p (point-max))) | 383 | (when (and (<= (point-min) p) (<= p (point-max))) |
| 418 | (get-text-property p 'token))) | 384 | (save-excursion |
| 385 | (let ((ppss (syntax-ppss p))) | ||
| 386 | ;; We want to return non-nil when right in front | ||
| 387 | ;; of a comment/string. | ||
| 388 | (if (null (nth 8 ppss)) | ||
| 389 | (when (looking-at opascal--literal-start-re) | ||
| 390 | (pcase (char-after) | ||
| 391 | (`?/ 'comment-single-line) | ||
| 392 | (`?\{ 'comment-multi-line-1) | ||
| 393 | (`?\( 'comment-multi-line-2) | ||
| 394 | (`?\' 'string) | ||
| 395 | (`?\" 'double-quoted-string))) | ||
| 396 | (if (nth 3 ppss) ;String. | ||
| 397 | (if (eq (nth 3 ppss) ?\") | ||
| 398 | 'double-quoted-string 'string) | ||
| 399 | (pcase (nth 7 ppss) | ||
| 400 | (`2 'comment-single-line) | ||
| 401 | (`1 'comment-multi-line-2) | ||
| 402 | (_ 'comment-multi-line-1)))))))) | ||
| 419 | 403 | ||
| 420 | (defun opascal-literal-start-pattern (literal-kind) | 404 | (defun opascal-literal-start-pattern (literal-kind) |
| 421 | ;; Returns the start pattern of the literal kind. | 405 | ;; Returns the start pattern of the literal kind. |
| @@ -446,96 +430,27 @@ non-OPascal buffer. Set to nil in OPascal buffers. To override, just do: | |||
| 446 | (string . "['\n]") | 430 | (string . "['\n]") |
| 447 | (double-quoted-string . "[\"\n]"))))) | 431 | (double-quoted-string . "[\"\n]"))))) |
| 448 | 432 | ||
| 449 | (defun opascal-is-literal-start (p) | ||
| 450 | ;; True if the point p is at the start point of a (completed) literal. | ||
| 451 | (let* ((kind (opascal-literal-kind p)) | ||
| 452 | (pattern (opascal-literal-start-pattern kind))) | ||
| 453 | (or (null kind) ; Non-literals are considered as start points. | ||
| 454 | (opascal-looking-at-string p pattern)))) | ||
| 455 | |||
| 456 | (defun opascal-is-literal-end (p) | 433 | (defun opascal-is-literal-end (p) |
| 457 | ;; True if the point p is at the end point of a (completed) literal. | 434 | ;; True if the point p is at the end point of a (completed) literal. |
| 458 | (let* ((kind (opascal-literal-kind (1- p))) | 435 | (save-excursion |
| 459 | (pattern (opascal-literal-end-pattern kind))) | 436 | (and (null (nth 8 (syntax-ppss p))) |
| 460 | (or (null kind) ; Non-literals are considered as end points. | 437 | (nth 8 (syntax-ppss (1- p)))))) |
| 461 | |||
| 462 | (and (opascal-looking-at-string (- p (length pattern)) pattern) | ||
| 463 | (or (not (opascal-is kind opascal-strings)) | ||
| 464 | ;; Special case: string delimiters are start/end ambiguous. | ||
| 465 | ;; We have an end only if there is some string content (at | ||
| 466 | ;; least a starting delimiter). | ||
| 467 | (not (opascal-is-literal-end (1- p))))) | ||
| 468 | |||
| 469 | ;; Special case: strings cannot span lines. | ||
| 470 | (and (opascal-is kind opascal-strings) (eq ?\n (char-after (1- p))))))) | ||
| 471 | |||
| 472 | (defun opascal-is-stable-literal (p) | ||
| 473 | ;; True if the point p marks a stable point. That is, a point outside of a | ||
| 474 | ;; literal region, inside of a literal region, or adjacent to completed | ||
| 475 | ;; literal regions. | ||
| 476 | (let ((at-start (opascal-is-literal-start p)) | ||
| 477 | (at-end (opascal-is-literal-end p))) | ||
| 478 | (or (>= p (point-max)) | ||
| 479 | (and at-start at-end) | ||
| 480 | (and (not at-start) (not at-end) | ||
| 481 | (eq (opascal-literal-kind (1- p)) (opascal-literal-kind p)))))) | ||
| 482 | |||
| 483 | (defun opascal-complete-literal (literal-kind limit) | ||
| 484 | ;; Continues the search for a literal's true end point and returns the | ||
| 485 | ;; point past the end pattern (if found) or the limit (if not found). | ||
| 486 | (let ((pattern (opascal-literal-stop-pattern literal-kind))) | ||
| 487 | (if (not (stringp pattern)) | ||
| 488 | (error "Invalid literal kind %S" literal-kind) | ||
| 489 | ;; Search up to the limit. | ||
| 490 | (re-search-forward pattern limit 'goto-limit-on-fail) | ||
| 491 | (point)))) | ||
| 492 | |||
| 493 | (defun opascal-literal-text-properties (kind) | ||
| 494 | ;; Creates a list of text properties for the literal kind. | ||
| 495 | (if (and (boundp 'font-lock-mode) | ||
| 496 | font-lock-mode) | ||
| 497 | (list 'token kind 'face (opascal-face-of kind) 'lazy-lock t) | ||
| 498 | (list 'token kind))) | ||
| 499 | |||
| 500 | (defun opascal-parse-next-literal (limit) | ||
| 501 | ;; Searches for the next literal region (i.e. comment or string) and sets the | ||
| 502 | ;; the point to its end (or the limit, if not found). The literal region is | ||
| 503 | ;; marked as such with a text property, to speed up tokenizing during face | ||
| 504 | ;; coloring and indentation scanning. | ||
| 505 | (let ((search-start (point))) | ||
| 506 | (cond ((not (opascal-is-literal-end search-start)) | ||
| 507 | ;; We are completing an incomplete literal. | ||
| 508 | (let ((kind (opascal-literal-kind (1- search-start)))) | ||
| 509 | (opascal-complete-literal kind limit) | ||
| 510 | (opascal-set-text-properties | ||
| 511 | search-start (point) (opascal-literal-text-properties kind)))) | ||
| 512 | |||
| 513 | ((re-search-forward | ||
| 514 | "\\(//\\)\\|\\({\\)\\|\\((\\*\\)\\|\\('\\)\\|\\(\"\\)" | ||
| 515 | limit 'goto-limit-on-fail) | ||
| 516 | ;; We found the start of a new literal. Find its end and mark it. | ||
| 517 | (let ((kind (cond ((match-beginning 1) 'comment-single-line) | ||
| 518 | ((match-beginning 2) 'comment-multi-line-1) | ||
| 519 | ((match-beginning 3) 'comment-multi-line-2) | ||
| 520 | ((match-beginning 4) 'string) | ||
| 521 | ((match-beginning 5) 'double-quoted-string))) | ||
| 522 | (start (match-beginning 0))) | ||
| 523 | (opascal-set-text-properties search-start start nil) | ||
| 524 | (opascal-complete-literal kind limit) | ||
| 525 | (opascal-set-text-properties | ||
| 526 | start (point) (opascal-literal-text-properties kind)))) | ||
| 527 | |||
| 528 | ;; Nothing found. Mark it as a non-literal. | ||
| 529 | ((opascal-set-text-properties search-start limit nil))) | ||
| 530 | (opascal-step-progress (point) "Parsing" opascal-parsing-progress-step))) | ||
| 531 | 438 | ||
| 532 | (defun opascal-literal-token-at (p) | 439 | (defun opascal-literal-token-at (p) |
| 533 | ;; Returns the literal token surrounding the point p, or nil if none. | 440 | "Return the literal token surrounding the point P, or nil if none." |
| 534 | (let ((kind (opascal-literal-kind p))) | 441 | (save-excursion |
| 535 | (when kind | 442 | (let ((ppss (syntax-ppss p))) |
| 536 | (let ((start (previous-single-property-change (1+ p) 'token)) | 443 | (when (or (nth 8 ppss) (looking-at opascal--literal-start-re)) |
| 537 | (end (next-single-property-change p 'token))) | 444 | (let* ((new-start (or (nth 8 ppss) p)) |
| 538 | (opascal-token-of kind (or start (point-min)) (or end (point-max))))))) | 445 | (new-end (progn |
| 446 | (goto-char new-start) | ||
| 447 | (condition-case nil | ||
| 448 | (if (memq (char-after) '(?\' ?\")) | ||
| 449 | (forward-sexp 1) | ||
| 450 | (forward-comment 1)) | ||
| 451 | (scan-error (goto-char (point-max)))) | ||
| 452 | (point)))) | ||
| 453 | (opascal-token-of (opascal-literal-kind p) new-start new-end)))))) | ||
| 539 | 454 | ||
| 540 | (defun opascal-point-token-at (p kind) | 455 | (defun opascal-point-token-at (p kind) |
| 541 | ;; Returns the single character token at the point p. | 456 | ;; Returns the single character token at the point p. |
| @@ -645,55 +560,6 @@ non-OPascal buffer. Set to nil in OPascal buffers. To override, just do: | |||
| 645 | (opascal-is (opascal-token-kind next-token) '(space newline)))) | 560 | (opascal-is (opascal-token-kind next-token) '(space newline)))) |
| 646 | next-token)) | 561 | next-token)) |
| 647 | 562 | ||
| 648 | (defun opascal-parse-region (from to) | ||
| 649 | ;; Parses the literal tokens in the region. The point is set to "to". | ||
| 650 | (save-restriction | ||
| 651 | (widen) | ||
| 652 | (goto-char from) | ||
| 653 | (while (< (point) to) | ||
| 654 | (opascal-parse-next-literal to)))) | ||
| 655 | |||
| 656 | (defun opascal-parse-region-until-stable (from to) | ||
| 657 | ;; Parses at least the literal tokens in the region. After that, parsing | ||
| 658 | ;; continues as long as obsolete literal regions are encountered. The point | ||
| 659 | ;; is set to the encountered stable point. | ||
| 660 | (save-restriction | ||
| 661 | (widen) | ||
| 662 | (opascal-parse-region from to) | ||
| 663 | (while (not (opascal-is-stable-literal (point))) | ||
| 664 | (opascal-parse-next-literal (point-max))))) | ||
| 665 | |||
| 666 | (defun opascal-fontify-region (from to &optional verbose) | ||
| 667 | ;; Colors the text in the region according to OPascal rules. | ||
| 668 | (opascal-save-excursion | ||
| 669 | (opascal-save-state | ||
| 670 | (let ((p from) | ||
| 671 | (opascal-verbose verbose) | ||
| 672 | (token nil)) | ||
| 673 | (opascal-progress-start) | ||
| 674 | (while (< p to) | ||
| 675 | ;; Color the token and move past it. | ||
| 676 | (setq token (opascal-token-at p)) | ||
| 677 | (add-text-properties | ||
| 678 | (opascal-token-start token) (opascal-token-end token) | ||
| 679 | (list 'face (opascal-face-of (opascal-token-kind token)) 'lazy-lock t)) | ||
| 680 | (setq p (opascal-token-end token)) | ||
| 681 | (opascal-step-progress p "Fontifying" opascal-fontifying-progress-step)) | ||
| 682 | (opascal-progress-done))))) | ||
| 683 | |||
| 684 | (defun opascal-after-change (change-start change-end _old-length) | ||
| 685 | ;; Called when the buffer has changed. Reparses the changed region. | ||
| 686 | (unless opascal--ignore-changes | ||
| 687 | (let ((opascal--ignore-changes t)) ; Prevent recursive calls. | ||
| 688 | (opascal-save-excursion | ||
| 689 | (opascal-progress-start) | ||
| 690 | ;; Reparse at least from the token previous to the change to the end of | ||
| 691 | ;; line after the change. | ||
| 692 | (opascal-parse-region-until-stable | ||
| 693 | (opascal-token-start (opascal-token-at (1- change-start))) | ||
| 694 | (progn (goto-char change-end) (end-of-line) (point))) | ||
| 695 | (opascal-progress-done))))) | ||
| 696 | |||
| 697 | (defun opascal-group-start (from-token) | 563 | (defun opascal-group-start (from-token) |
| 698 | ;; Returns the token that denotes the start of the ()/[] group. | 564 | ;; Returns the token that denotes the start of the ()/[] group. |
| 699 | (let ((token (opascal-previous-token from-token)) | 565 | (let ((token (opascal-previous-token from-token)) |
| @@ -1561,41 +1427,6 @@ If before the indent, the point is moved to the indent." | |||
| 1561 | (interactive "r") | 1427 | (interactive "r") |
| 1562 | (opascal-debug-log "String: %S" (buffer-substring from to))) | 1428 | (opascal-debug-log "String: %S" (buffer-substring from to))) |
| 1563 | 1429 | ||
| 1564 | (defun opascal-debug-show-is-stable () | ||
| 1565 | (interactive) | ||
| 1566 | (opascal-debug-log "stable: %S prev: %S next: %S" | ||
| 1567 | (opascal-is-stable-literal (point)) | ||
| 1568 | (opascal-literal-kind (1- (point))) | ||
| 1569 | (opascal-literal-kind (point)))) | ||
| 1570 | |||
| 1571 | (defun opascal-debug-unparse-buffer () | ||
| 1572 | (interactive) | ||
| 1573 | (opascal-set-text-properties (point-min) (point-max) nil)) | ||
| 1574 | |||
| 1575 | (defun opascal-debug-parse-region (from to) | ||
| 1576 | (interactive "r") | ||
| 1577 | (let ((opascal-verbose t)) | ||
| 1578 | (opascal-save-excursion | ||
| 1579 | (opascal-progress-start) | ||
| 1580 | (opascal-parse-region from to) | ||
| 1581 | (opascal-progress-done "Parsing done")))) | ||
| 1582 | |||
| 1583 | (defun opascal-debug-parse-window () | ||
| 1584 | (interactive) | ||
| 1585 | (opascal-debug-parse-region (window-start) (window-end))) | ||
| 1586 | |||
| 1587 | (defun opascal-debug-parse-buffer () | ||
| 1588 | (interactive) | ||
| 1589 | (opascal-debug-parse-region (point-min) (point-max))) | ||
| 1590 | |||
| 1591 | (defun opascal-debug-fontify-window () | ||
| 1592 | (interactive) | ||
| 1593 | (opascal-fontify-region (window-start) (window-end) t)) | ||
| 1594 | |||
| 1595 | (defun opascal-debug-fontify-buffer () | ||
| 1596 | (interactive) | ||
| 1597 | (opascal-fontify-region (point-min) (point-max) t)) | ||
| 1598 | |||
| 1599 | (defun opascal-debug-tokenize-region (from to) | 1430 | (defun opascal-debug-tokenize-region (from to) |
| 1600 | (interactive) | 1431 | (interactive) |
| 1601 | (opascal-save-excursion | 1432 | (opascal-save-excursion |
| @@ -1747,6 +1578,7 @@ An error is raised if not in a comment." | |||
| 1747 | (error "Not in a comment") | 1578 | (error "Not in a comment") |
| 1748 | (let* ((start-comment (opascal-comment-block-start comment)) | 1579 | (let* ((start-comment (opascal-comment-block-start comment)) |
| 1749 | (end-comment (opascal-comment-block-end comment)) | 1580 | (end-comment (opascal-comment-block-end comment)) |
| 1581 | ;; FIXME: Don't abuse global variables like `comment-end/start'. | ||
| 1750 | (comment-start (opascal-token-start start-comment)) | 1582 | (comment-start (opascal-token-start start-comment)) |
| 1751 | (comment-end (opascal-token-end end-comment)) | 1583 | (comment-end (opascal-token-end end-comment)) |
| 1752 | (content-start (opascal-comment-content-start start-comment)) | 1584 | (content-start (opascal-comment-content-start start-comment)) |
| @@ -1814,12 +1646,7 @@ An error is raised if not in a comment." | |||
| 1814 | 1646 | ||
| 1815 | ;; Restore our position | 1647 | ;; Restore our position |
| 1816 | (goto-char marked-point) | 1648 | (goto-char marked-point) |
| 1817 | (set-marker marked-point nil) | 1649 | (set-marker marked-point nil))))))) |
| 1818 | |||
| 1819 | ;; React to the entire fill change as a whole. | ||
| 1820 | (opascal-progress-start) | ||
| 1821 | (opascal-parse-region comment-start comment-end) | ||
| 1822 | (opascal-progress-done))))))) | ||
| 1823 | 1650 | ||
| 1824 | (defun opascal-new-comment-line () | 1651 | (defun opascal-new-comment-line () |
| 1825 | "If in a // comment, do a newline, indented such that one is still in the | 1652 | "If in a // comment, do a newline, indented such that one is still in the |
| @@ -1848,16 +1675,37 @@ comment block. If not in a // comment, just does a normal newline." | |||
| 1848 | (goto-char end) | 1675 | (goto-char end) |
| 1849 | token))) | 1676 | token))) |
| 1850 | 1677 | ||
| 1678 | (defconst opascal-font-lock-keywords | ||
| 1679 | `(("\\_<\\(function\\|pro\\(cedure\\|gram\\)\\)[ \t]+\\([[:alpha:]][[:alnum:]_]*\\)" | ||
| 1680 | (1 font-lock-keyword-face) (3 font-lock-function-name-face)) | ||
| 1681 | ,(concat "\\_<" (regexp-opt (mapcar #'symbol-name opascal-keywords)) | ||
| 1682 | "\\_>"))) | ||
| 1683 | |||
| 1851 | (defconst opascal-font-lock-defaults | 1684 | (defconst opascal-font-lock-defaults |
| 1852 | '(nil ; We have our own fontify routine, so keywords don't apply. | 1685 | '(opascal-font-lock-keywords |
| 1853 | t ; Syntactic fontification doesn't apply. | 1686 | nil ; Syntactic fontification does apply. |
| 1854 | nil ; Don't care about case since we don't use regexps to find tokens. | 1687 | nil ; Don't care about case since we don't use regexps to find tokens. |
| 1855 | nil ; Syntax alists don't apply. | 1688 | nil ; Syntax alists don't apply. |
| 1856 | nil ; Syntax begin movement doesn't apply | 1689 | nil ; Syntax begin movement doesn't apply. |
| 1857 | (font-lock-fontify-region-function . opascal-fontify-region) | 1690 | ) |
| 1858 | (font-lock-verbose . opascal-fontifying-progress-step)) | ||
| 1859 | "OPascal mode font-lock defaults. Syntactic fontification is ignored.") | 1691 | "OPascal mode font-lock defaults. Syntactic fontification is ignored.") |
| 1860 | 1692 | ||
| 1693 | (defconst opascal--syntax-propertize | ||
| 1694 | (syntax-propertize-rules | ||
| 1695 | ;; The syntax-table settings are too coarse and end up treating /* and (/ | ||
| 1696 | ;; as comment starters. Fix it here by removing the "2" from the syntax | ||
| 1697 | ;; of the second char of such sequences. | ||
| 1698 | ("/\\(\\*\\)" (1 ". 3b")) | ||
| 1699 | ("(\\(\\/\\)" (1 (prog1 ". 1c" (forward-char -1) nil))) | ||
| 1700 | ;; Pascal uses '' and "" rather than \' and \" to escape quotes. | ||
| 1701 | ("''\\|\"\"" (0 (if (save-excursion | ||
| 1702 | (nth 3 (syntax-ppss (match-beginning 0)))) | ||
| 1703 | (string-to-syntax ".") | ||
| 1704 | ;; In case of 3 or more quotes in a row, only advance | ||
| 1705 | ;; one quote at a time. | ||
| 1706 | (forward-char -1) | ||
| 1707 | nil))))) | ||
| 1708 | |||
| 1861 | (defvar opascal-debug-mode-map | 1709 | (defvar opascal-debug-mode-map |
| 1862 | (let ((kmap (make-sparse-keymap))) | 1710 | (let ((kmap (make-sparse-keymap))) |
| 1863 | (dolist (binding '(("n" opascal-debug-goto-next-token) | 1711 | (dolist (binding '(("n" opascal-debug-goto-next-token) |
| @@ -1866,14 +1714,7 @@ comment block. If not in a // comment, just does a normal newline." | |||
| 1866 | ("T" opascal-debug-tokenize-buffer) | 1714 | ("T" opascal-debug-tokenize-buffer) |
| 1867 | ("W" opascal-debug-tokenize-window) | 1715 | ("W" opascal-debug-tokenize-window) |
| 1868 | ("g" opascal-debug-goto-point) | 1716 | ("g" opascal-debug-goto-point) |
| 1869 | ("s" opascal-debug-show-current-string) | 1717 | ("s" opascal-debug-show-current-string))) |
| 1870 | ("a" opascal-debug-parse-buffer) | ||
| 1871 | ("w" opascal-debug-parse-window) | ||
| 1872 | ("f" opascal-debug-fontify-window) | ||
| 1873 | ("F" opascal-debug-fontify-buffer) | ||
| 1874 | ("r" opascal-debug-parse-region) | ||
| 1875 | ("c" opascal-debug-unparse-buffer) | ||
| 1876 | ("x" opascal-debug-show-is-stable))) | ||
| 1877 | (define-key kmap (car binding) (cadr binding))) | 1718 | (define-key kmap (car binding) (cadr binding))) |
| 1878 | kmap) | 1719 | kmap) |
| 1879 | "Keystrokes for OPascal mode debug commands.") | 1720 | "Keystrokes for OPascal mode debug commands.") |
| @@ -1923,14 +1764,8 @@ Customization: | |||
| 1923 | 1764 | ||
| 1924 | Coloring: | 1765 | Coloring: |
| 1925 | 1766 | ||
| 1926 | `opascal-comment-face' (default font-lock-comment-face) | ||
| 1927 | Face used to color OPascal comments. | ||
| 1928 | `opascal-string-face' (default font-lock-string-face) | ||
| 1929 | Face used to color OPascal strings. | ||
| 1930 | `opascal-keyword-face' (default font-lock-keyword-face) | 1767 | `opascal-keyword-face' (default font-lock-keyword-face) |
| 1931 | Face used to color OPascal keywords. | 1768 | Face used to color OPascal keywords. |
| 1932 | `opascal-other-face' (default nil) | ||
| 1933 | Face used to color everything else. | ||
| 1934 | 1769 | ||
| 1935 | Turning on OPascal mode calls the value of the variable `opascal-mode-hook' | 1770 | Turning on OPascal mode calls the value of the variable `opascal-mode-hook' |
| 1936 | with no args, if that value is non-nil." | 1771 | with no args, if that value is non-nil." |
| @@ -1940,21 +1775,13 @@ with no args, if that value is non-nil." | |||
| 1940 | (setq-local comment-indent-function #'opascal-indent-line) | 1775 | (setq-local comment-indent-function #'opascal-indent-line) |
| 1941 | (setq-local case-fold-search t) | 1776 | (setq-local case-fold-search t) |
| 1942 | (setq-local opascal-progress-last-reported-point nil) | 1777 | (setq-local opascal-progress-last-reported-point nil) |
| 1943 | (setq-local opascal--ignore-changes nil) | ||
| 1944 | (setq-local font-lock-defaults opascal-font-lock-defaults) | 1778 | (setq-local font-lock-defaults opascal-font-lock-defaults) |
| 1945 | (setq-local tab-always-indent opascal-tab-always-indents) | 1779 | (setq-local tab-always-indent opascal-tab-always-indents) |
| 1780 | (setq-local syntax-propertize-function opascal--syntax-propertize) | ||
| 1946 | 1781 | ||
| 1947 | ;; FIXME: Use syntax-propertize-function to tokenize, maybe? | 1782 | (setq-local comment-start "// ") |
| 1948 | 1783 | (setq-local comment-start-skip "\\(?://\\|(\\*\\|{\\)[ \t]*") | |
| 1949 | ;; We need to keep track of changes to the buffer to determine if we need | 1784 | (setq-local comment-end-skip "[ \t]*\\(?:\n\\|\\*)\\|}\\)")) |
| 1950 | ;; to retokenize changed text. | ||
| 1951 | (add-hook 'after-change-functions #'opascal-after-change nil t) | ||
| 1952 | |||
| 1953 | (opascal-save-excursion | ||
| 1954 | (let ((opascal-verbose t)) | ||
| 1955 | (opascal-progress-start) | ||
| 1956 | (opascal-parse-region (point-min) (point-max)) | ||
| 1957 | (opascal-progress-done)))) | ||
| 1958 | 1785 | ||
| 1959 | (provide 'opascal) | 1786 | (provide 'opascal) |
| 1960 | ;;; opascal.el ends here | 1787 | ;;; opascal.el ends here |
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el index 829ecda5150..ffc8200644a 100644 --- a/lisp/progmodes/pascal.el +++ b/lisp/progmodes/pascal.el | |||
| @@ -158,31 +158,44 @@ | |||
| 158 | 158 | ||
| 159 | 159 | ||
| 160 | 160 | ||
| 161 | (defconst pascal-font-lock-keywords (purecopy | 161 | (defconst pascal-font-lock-keywords |
| 162 | (list | 162 | `(("\\_<\\(function\\|pro\\(cedure\\|gram\\)\\)[ \t]+\\([[:alpha:]][[:alnum:]_]*\\)" |
| 163 | '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\([a-z]\\)" | 163 | (1 font-lock-keyword-face) |
| 164 | (3 font-lock-function-name-face)) | ||
| 165 | ;; ("type" "const" "real" "integer" "char" "boolean" "var" | ||
| 166 | ;; "record" "array" "file") | ||
| 167 | (,(concat "\\<\\(array\\|boolean\\|c\\(har\\|onst\\)\\|file\\|" | ||
| 168 | "integer\\|re\\(al\\|cord\\)\\|type\\|var\\)\\>") | ||
| 169 | font-lock-type-face) | ||
| 170 | ("\\<\\(label\\|external\\|forward\\)\\>" . font-lock-constant-face) | ||
| 171 | ("\\<\\([0-9]+\\)[ \t]*:" 1 font-lock-function-name-face) | ||
| 172 | ;; ("of" "to" "for" "if" "then" "else" "case" "while" | ||
| 173 | ;; "do" "until" "and" "or" "not" "in" "with" "repeat" "begin" "end") | ||
| 174 | ,(concat "\\<\\(" | ||
| 175 | "and\\|begin\\|case\\|do\\|e\\(lse\\|nd\\)\\|for\\|i[fn]\\|" | ||
| 176 | "not\\|o[fr]\\|repeat\\|t\\(hen\\|o\\)\\|until\\|w\\(hile\\|ith\\)" | ||
| 177 | "\\)\\>") | ||
| 178 | ("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?" | ||
| 164 | 1 font-lock-keyword-face) | 179 | 1 font-lock-keyword-face) |
| 165 | '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\([a-z][a-z0-9_]*\\)" | 180 | ("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?" |
| 166 | 3 font-lock-function-name-face t) | 181 | 2 font-lock-keyword-face t)) |
| 167 | ; ("type" "const" "real" "integer" "char" "boolean" "var" | ||
| 168 | ; "record" "array" "file") | ||
| 169 | (cons (concat "\\<\\(array\\|boolean\\|c\\(har\\|onst\\)\\|file\\|" | ||
| 170 | "integer\\|re\\(al\\|cord\\)\\|type\\|var\\)\\>") | ||
| 171 | 'font-lock-type-face) | ||
| 172 | '("\\<\\(label\\|external\\|forward\\)\\>" . font-lock-constant-face) | ||
| 173 | '("\\<\\([0-9]+\\)[ \t]*:" 1 font-lock-function-name-face) | ||
| 174 | ; ("of" "to" "for" "if" "then" "else" "case" "while" | ||
| 175 | ; "do" "until" "and" "or" "not" "in" "with" "repeat" "begin" "end") | ||
| 176 | (concat "\\<\\(" | ||
| 177 | "and\\|begin\\|case\\|do\\|e\\(lse\\|nd\\)\\|for\\|i[fn]\\|" | ||
| 178 | "not\\|o[fr]\\|repeat\\|t\\(hen\\|o\\)\\|until\\|w\\(hile\\|ith\\)" | ||
| 179 | "\\)\\>") | ||
| 180 | '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?" | ||
| 181 | 1 font-lock-keyword-face) | ||
| 182 | '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?" | ||
| 183 | 2 font-lock-keyword-face t))) | ||
| 184 | "Additional expressions to highlight in Pascal mode.") | 182 | "Additional expressions to highlight in Pascal mode.") |
| 185 | (put 'pascal-mode 'font-lock-defaults '(pascal-font-lock-keywords nil t)) | 183 | |
| 184 | (defconst pascal--syntax-propertize | ||
| 185 | (syntax-propertize-rules | ||
| 186 | ;; The syntax-table settings are too coarse and end up treating /* and (/ | ||
| 187 | ;; as comment starters. Fix it here by removing the "2" from the syntax | ||
| 188 | ;; of the second char of such sequences. | ||
| 189 | ("/\\(\\*\\)" (1 ". 3b")) | ||
| 190 | ("(\\(\\/\\)" (1 (prog1 ". 1c" (forward-char -1) nil))) | ||
| 191 | ;; Pascal uses '' and "" rather than \' and \" to escape quotes. | ||
| 192 | ("''\\|\"\"" (0 (if (save-excursion | ||
| 193 | (nth 3 (syntax-ppss (match-beginning 0)))) | ||
| 194 | (string-to-syntax ".") | ||
| 195 | ;; In case of 3 or more quotes in a row, only advance | ||
| 196 | ;; one quote at a time. | ||
| 197 | (forward-char -1) | ||
| 198 | nil))))) | ||
| 186 | 199 | ||
| 187 | (defcustom pascal-indent-level 3 | 200 | (defcustom pascal-indent-level 3 |
| 188 | "Indentation of Pascal statements with respect to containing block." | 201 | "Indentation of Pascal statements with respect to containing block." |
| @@ -346,23 +359,22 @@ See also the user variables `pascal-type-keywords', `pascal-start-keywords' and | |||
| 346 | 359 | ||
| 347 | Turning on Pascal mode calls the value of the variable pascal-mode-hook with | 360 | Turning on Pascal mode calls the value of the variable pascal-mode-hook with |
| 348 | no args, if that value is non-nil." | 361 | no args, if that value is non-nil." |
| 349 | (set (make-local-variable 'local-abbrev-table) pascal-mode-abbrev-table) | 362 | (setq-local local-abbrev-table pascal-mode-abbrev-table) |
| 350 | (set (make-local-variable 'indent-line-function) 'pascal-indent-line) | 363 | (setq-local indent-line-function 'pascal-indent-line) |
| 351 | (set (make-local-variable 'comment-indent-function) 'pascal-indent-comment) | 364 | (setq-local comment-indent-function 'pascal-indent-comment) |
| 352 | (set (make-local-variable 'parse-sexp-ignore-comments) nil) | 365 | (setq-local parse-sexp-ignore-comments nil) |
| 353 | (set (make-local-variable 'blink-matching-paren-dont-ignore-comments) t) | 366 | (setq-local blink-matching-paren-dont-ignore-comments t) |
| 354 | (set (make-local-variable 'case-fold-search) t) | 367 | (setq-local case-fold-search t) |
| 355 | (set (make-local-variable 'comment-start) "{") | 368 | (setq-local comment-start "{") |
| 356 | (set (make-local-variable 'comment-start-skip) "(\\*+ *\\|{ *") | 369 | (setq-local comment-start-skip "(\\*+ *\\|{ *") |
| 357 | (set (make-local-variable 'comment-end) "}") | 370 | (setq-local comment-end "}") |
| 358 | (add-hook 'completion-at-point-functions 'pascal-completions-at-point nil t) | 371 | (add-hook 'completion-at-point-functions 'pascal-completions-at-point nil t) |
| 359 | ;; Font lock support | 372 | ;; Font lock support |
| 360 | (set (make-local-variable 'font-lock-defaults) | 373 | (setq-local font-lock-defaults '(pascal-font-lock-keywords nil t)) |
| 361 | '(pascal-font-lock-keywords nil t)) | 374 | (setq-local syntax-propertize-function pascal--syntax-propertize) |
| 362 | ;; Imenu support | 375 | ;; Imenu support |
| 363 | (set (make-local-variable 'imenu-generic-expression) | 376 | (setq-local imenu-generic-expression pascal-imenu-generic-expression) |
| 364 | pascal-imenu-generic-expression) | 377 | (setq-local imenu-case-fold-search t) |
| 365 | (set (make-local-variable 'imenu-case-fold-search) t) | ||
| 366 | ;; Pascal-mode's own hide/show support. | 378 | ;; Pascal-mode's own hide/show support. |
| 367 | (add-to-invisibility-spec '(pascal . t))) | 379 | (add-to-invisibility-spec '(pascal . t))) |
| 368 | 380 | ||
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index bd58a7300ec..01ac8584e19 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el | |||
| @@ -148,10 +148,10 @@ | |||
| 148 | 148 | ||
| 149 | (defvar perl-imenu-generic-expression | 149 | (defvar perl-imenu-generic-expression |
| 150 | '(;; Functions | 150 | '(;; Functions |
| 151 | (nil "^[ \t]*sub\\s-+\\([-A-Za-z0-9+_:]+\\)" 1) | 151 | (nil "^[ \t]*sub\\s-+\\([-[:alnum:]+_:]+\\)" 1) |
| 152 | ;;Variables | 152 | ;;Variables |
| 153 | ("Variables" "^\\(?:my\\|our\\)\\s-+\\([$@%][-A-Za-z0-9+_:]+\\)\\s-*=" 1) | 153 | ("Variables" "^\\(?:my\\|our\\)\\s-+\\([$@%][-[:alnum:]+_:]+\\)\\s-*=" 1) |
| 154 | ("Packages" "^[ \t]*package\\s-+\\([-A-Za-z0-9+_:]+\\);" 1) | 154 | ("Packages" "^[ \t]*package\\s-+\\([-[:alnum:]+_:]+\\);" 1) |
| 155 | ("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1)) | 155 | ("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1)) |
| 156 | "Imenu generic expression for Perl mode. See `imenu-generic-expression'.") | 156 | "Imenu generic expression for Perl mode. See `imenu-generic-expression'.") |
| 157 | 157 | ||
| @@ -160,6 +160,7 @@ | |||
| 160 | 160 | ||
| 161 | (defcustom perl-prettify-symbols t | 161 | (defcustom perl-prettify-symbols t |
| 162 | "If non-nil, some symbols will be displayed using Unicode chars." | 162 | "If non-nil, some symbols will be displayed using Unicode chars." |
| 163 | :version "24.4" | ||
| 163 | :type 'boolean) | 164 | :type 'boolean) |
| 164 | 165 | ||
| 165 | (defconst perl--prettify-symbols-alist | 166 | (defconst perl--prettify-symbols-alist |
| @@ -275,7 +276,6 @@ Regexp match data 0 points to the chars." | |||
| 275 | (let ((case-fold-search nil)) | 276 | (let ((case-fold-search nil)) |
| 276 | (goto-char start) | 277 | (goto-char start) |
| 277 | (perl-syntax-propertize-special-constructs end) | 278 | (perl-syntax-propertize-special-constructs end) |
| 278 | ;; TODO: here-documents ("<<\\(\\sw\\|['\"]\\)") | ||
| 279 | (funcall | 279 | (funcall |
| 280 | (syntax-propertize-rules | 280 | (syntax-propertize-rules |
| 281 | ;; Turn POD into b-style comments. Place the cut rule first since it's | 281 | ;; Turn POD into b-style comments. Place the cut rule first since it's |
| @@ -287,7 +287,7 @@ Regexp match data 0 points to the chars." | |||
| 287 | ;; check that it occurs inside a '..' string. | 287 | ;; check that it occurs inside a '..' string. |
| 288 | ("\\(\\$\\)[{']" (1 ". p")) | 288 | ("\\(\\$\\)[{']" (1 ". p")) |
| 289 | ;; Handle funny names like $DB'stop. | 289 | ;; Handle funny names like $DB'stop. |
| 290 | ("\\$ ?{?^?[_a-zA-Z][_a-zA-Z0-9]*\\('\\)[_a-zA-Z]" (1 "_")) | 290 | ("\\$ ?{?^?[_[:alpha:]][_[:alnum:]]*\\('\\)[_[:alpha:]]" (1 "_")) |
| 291 | ;; format statements | 291 | ;; format statements |
| 292 | ("^[ \t]*format.*=[ \t]*\\(\n\\)" | 292 | ("^[ \t]*format.*=[ \t]*\\(\n\\)" |
| 293 | (1 (prog1 "\"" (perl-syntax-propertize-special-constructs end)))) | 293 | (1 (prog1 "\"" (perl-syntax-propertize-special-constructs end)))) |
| @@ -345,7 +345,29 @@ Regexp match data 0 points to the chars." | |||
| 345 | perl-quote-like-pairs) | 345 | perl-quote-like-pairs) |
| 346 | (string-to-syntax "|") | 346 | (string-to-syntax "|") |
| 347 | (string-to-syntax "\""))) | 347 | (string-to-syntax "\""))) |
| 348 | (perl-syntax-propertize-special-constructs end)))))) | 348 | (perl-syntax-propertize-special-constructs end))))) |
| 349 | ;; Here documents. | ||
| 350 | ;; TODO: Handle <<WORD. These are trickier because you need to | ||
| 351 | ;; disambiguate with the shift operator. | ||
| 352 | ("<<[ \t]*\\('[^'\n]*'\\|\"[^\"\n]*\"\\|\\\\[[:alpha:]][[:alnum:]]*\\).*\\(\n\\)" | ||
| 353 | (2 (let* ((st (get-text-property (match-beginning 2) 'syntax-table)) | ||
| 354 | (name (match-string 1))) | ||
| 355 | (goto-char (match-end 1)) | ||
| 356 | (if (save-excursion (nth 8 (syntax-ppss (match-beginning 0)))) | ||
| 357 | ;; Leave the property of the newline unchanged. | ||
| 358 | st | ||
| 359 | (cons (car (string-to-syntax "< c")) | ||
| 360 | ;; Remember the names of heredocs found on this line. | ||
| 361 | (cons (pcase (aref name 0) | ||
| 362 | (`?\\ (substring name 1)) | ||
| 363 | (_ (substring name 1 -1))) | ||
| 364 | (cdr st))))))) | ||
| 365 | ;; We don't call perl-syntax-propertize-special-constructs directly | ||
| 366 | ;; from the << rule, because there might be other elements (between | ||
| 367 | ;; the << and the \n) that need to be propertized. | ||
| 368 | ("\\(?:$\\)\\s<" | ||
| 369 | (0 (ignore (perl-syntax-propertize-special-constructs end)))) | ||
| 370 | ) | ||
| 349 | (point) end))) | 371 | (point) end))) |
| 350 | 372 | ||
| 351 | (defvar perl-empty-syntax-table | 373 | (defvar perl-empty-syntax-table |
| @@ -370,6 +392,22 @@ Regexp match data 0 points to the chars." | |||
| 370 | (let ((state (syntax-ppss)) | 392 | (let ((state (syntax-ppss)) |
| 371 | char) | 393 | char) |
| 372 | (cond | 394 | (cond |
| 395 | ((eq 2 (nth 7 state)) | ||
| 396 | ;; A Here document. | ||
| 397 | (let ((names (cdr (get-text-property (nth 8 state) 'syntax-table)))) | ||
| 398 | (when (cdr names) | ||
| 399 | (setq names (reverse names)) | ||
| 400 | ;; Multiple heredocs on a single line, we have to search from the | ||
| 401 | ;; beginning, since we don't know which names might be | ||
| 402 | ;; before point. | ||
| 403 | (goto-char (nth 8 state))) | ||
| 404 | (while (and names | ||
| 405 | (re-search-forward | ||
| 406 | (concat "^" (regexp-quote (pop names)) "\n") | ||
| 407 | limit 'move)) | ||
| 408 | (unless names | ||
| 409 | (put-text-property (1- (point)) (point) 'syntax-table | ||
| 410 | (string-to-syntax "> c")))))) | ||
| 373 | ((or (null (setq char (nth 3 state))) | 411 | ((or (null (setq char (nth 3 state))) |
| 374 | (and (characterp char) (eq (char-syntax (nth 3 state)) ?\"))) | 412 | (and (characterp char) (eq (char-syntax (nth 3 state)) ?\"))) |
| 375 | ;; Normal text, or comment, or docstring, or normal string. | 413 | ;; Normal text, or comment, or docstring, or normal string. |
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el index 85e4172c8fe..63bd9258d69 100644 --- a/lisp/progmodes/prolog.el +++ b/lisp/progmodes/prolog.el | |||
| @@ -278,16 +278,16 @@ | |||
| 278 | 278 | ||
| 279 | ;;; Code: | 279 | ;;; Code: |
| 280 | 280 | ||
| 281 | (require 'comint) | ||
| 282 | |||
| 281 | (eval-when-compile | 283 | (eval-when-compile |
| 282 | (require 'font-lock) | 284 | (require 'font-lock) |
| 283 | ;; We need imenu everywhere because of the predicate index! | 285 | ;; We need imenu everywhere because of the predicate index! |
| 284 | (require 'imenu) | 286 | (require 'imenu) |
| 285 | ;) | 287 | ;) |
| 286 | (require 'info) | ||
| 287 | (require 'shell) | 288 | (require 'shell) |
| 288 | ) | 289 | ) |
| 289 | 290 | ||
| 290 | (require 'comint) | ||
| 291 | (require 'easymenu) | 291 | (require 'easymenu) |
| 292 | (require 'align) | 292 | (require 'align) |
| 293 | 293 | ||
| @@ -772,6 +772,8 @@ Relevant only when `prolog-imenu-flag' is non-nil." | |||
| 772 | :version "24.1" | 772 | :version "24.1" |
| 773 | :group 'prolog-other | 773 | :group 'prolog-other |
| 774 | :type 'boolean) | 774 | :type 'boolean) |
| 775 | (make-obsolete-variable 'prolog-underscore-wordchar-flag | ||
| 776 | 'superword-mode "24.4") | ||
| 775 | 777 | ||
| 776 | (defcustom prolog-use-sicstus-sd nil | 778 | (defcustom prolog-use-sicstus-sd nil |
| 777 | "If non-nil, use the source level debugger of SICStus 3#7 and later." | 779 | "If non-nil, use the source level debugger of SICStus 3#7 and later." |
| @@ -785,6 +787,7 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." | |||
| 785 | :version "24.1" | 787 | :version "24.1" |
| 786 | :group 'prolog-other | 788 | :group 'prolog-other |
| 787 | :type 'boolean) | 789 | :type 'boolean) |
| 790 | (make-obsolete-variable 'prolog-char-quote-workaround nil "24.1") | ||
| 788 | 791 | ||
| 789 | 792 | ||
| 790 | ;;------------------------------------------------------------------- | 793 | ;;------------------------------------------------------------------- |
| @@ -802,10 +805,7 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." | |||
| 802 | ;; - In atoms \x<hex> sometimes needs a terminating \ (ISO-style) | 805 | ;; - In atoms \x<hex> sometimes needs a terminating \ (ISO-style) |
| 803 | ;; and sometimes not. | 806 | ;; and sometimes not. |
| 804 | (let ((table (make-syntax-table))) | 807 | (let ((table (make-syntax-table))) |
| 805 | (if prolog-underscore-wordchar-flag | 808 | (modify-syntax-entry ?_ (if prolog-underscore-wordchar-flag "w" "_") table) |
| 806 | (modify-syntax-entry ?_ "w" table) | ||
| 807 | (modify-syntax-entry ?_ "_" table)) | ||
| 808 | |||
| 809 | (modify-syntax-entry ?+ "." table) | 809 | (modify-syntax-entry ?+ "." table) |
| 810 | (modify-syntax-entry ?- "." table) | 810 | (modify-syntax-entry ?- "." table) |
| 811 | (modify-syntax-entry ?= "." table) | 811 | (modify-syntax-entry ?= "." table) |
| @@ -815,7 +815,8 @@ This is really kludgy, and unneeded (i.e. obsolete) in Emacs>=24." | |||
| 815 | (modify-syntax-entry ?\' "\"" table) | 815 | (modify-syntax-entry ?\' "\"" table) |
| 816 | 816 | ||
| 817 | ;; Any better way to handle the 0'<char> construct?!? | 817 | ;; Any better way to handle the 0'<char> construct?!? |
| 818 | (when prolog-char-quote-workaround | 818 | (when (and prolog-char-quote-workaround |
| 819 | (not (fboundp 'syntax-propertize-rules))) | ||
| 819 | (modify-syntax-entry ?0 "\\" table)) | 820 | (modify-syntax-entry ?0 "\\" table)) |
| 820 | 821 | ||
| 821 | (modify-syntax-entry ?% "<" table) | 822 | (modify-syntax-entry ?% "<" table) |
| @@ -1770,7 +1771,8 @@ This function must be called from the source code buffer." | |||
| 1770 | real-file)) | 1771 | real-file)) |
| 1771 | (with-current-buffer buffer | 1772 | (with-current-buffer buffer |
| 1772 | (goto-char (point-max)) | 1773 | (goto-char (point-max)) |
| 1773 | (set-process-filter process 'prolog-consult-compile-filter) | 1774 | (add-function :override (process-filter process) |
| 1775 | #'prolog-consult-compile-filter) | ||
| 1774 | (process-send-string "prolog" command-string) | 1776 | (process-send-string "prolog" command-string) |
| 1775 | ;; (prolog-build-prolog-command compilep file real-file first-line)) | 1777 | ;; (prolog-build-prolog-command compilep file real-file first-line)) |
| 1776 | (while (and prolog-process-flag | 1778 | (while (and prolog-process-flag |
| @@ -1781,7 +1783,8 @@ This function must be called from the source code buffer." | |||
| 1781 | (insert (if compilep | 1783 | (insert (if compilep |
| 1782 | "\nCompilation finished.\n" | 1784 | "\nCompilation finished.\n" |
| 1783 | "\nConsulted.\n")) | 1785 | "\nConsulted.\n")) |
| 1784 | (set-process-filter process old-filter)))) | 1786 | (remove-function (process-filter process) |
| 1787 | #'prolog-consult-compile-filter)))) | ||
| 1785 | 1788 | ||
| 1786 | (defvar compilation-error-list) | 1789 | (defvar compilation-error-list) |
| 1787 | 1790 | ||
| @@ -3027,11 +3030,14 @@ The rest of the elements are undefined." | |||
| 3027 | (error "Sorry, no help method defined for this Prolog system.")))) | 3030 | (error "Sorry, no help method defined for this Prolog system.")))) |
| 3028 | )) | 3031 | )) |
| 3029 | 3032 | ||
| 3033 | |||
| 3034 | (autoload 'Info-goto-node "info" nil t) | ||
| 3035 | (declare-function Info-follow-nearest-node "info" (&optional FORK)) | ||
| 3036 | |||
| 3030 | (defun prolog-help-info (predicate) | 3037 | (defun prolog-help-info (predicate) |
| 3031 | (let ((buffer (current-buffer)) | 3038 | (let ((buffer (current-buffer)) |
| 3032 | oldp | 3039 | oldp |
| 3033 | (str (concat "^\\* " (regexp-quote predicate) " */"))) | 3040 | (str (concat "^\\* " (regexp-quote predicate) " */"))) |
| 3034 | (require 'info) | ||
| 3035 | (pop-to-buffer nil) | 3041 | (pop-to-buffer nil) |
| 3036 | (Info-goto-node prolog-info-predicate-index) | 3042 | (Info-goto-node prolog-info-predicate-index) |
| 3037 | (if (not (re-search-forward str nil t)) | 3043 | (if (not (re-search-forward str nil t)) |
| @@ -3120,7 +3126,6 @@ Only for internal use by `prolog-find-documentation'") | |||
| 3120 | (defun prolog-goto-predicate-info (predicate) | 3126 | (defun prolog-goto-predicate-info (predicate) |
| 3121 | "Go to the info page for PREDICATE, which is a PredSpec." | 3127 | "Go to the info page for PREDICATE, which is a PredSpec." |
| 3122 | (interactive) | 3128 | (interactive) |
| 3123 | (require 'info) | ||
| 3124 | (string-match "\\(.*\\)/\\([0-9]+\\).*$" predicate) | 3129 | (string-match "\\(.*\\)/\\([0-9]+\\).*$" predicate) |
| 3125 | (let ((buffer (current-buffer)) | 3130 | (let ((buffer (current-buffer)) |
| 3126 | (name (match-string 1 predicate)) | 3131 | (name (match-string 1 predicate)) |
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index f0f67d01845..ccb2dcba42e 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -157,7 +157,7 @@ | |||
| 157 | 157 | ||
| 158 | ;; Skeletons: 6 skeletons are provided for simple inserting of class, | 158 | ;; Skeletons: 6 skeletons are provided for simple inserting of class, |
| 159 | ;; def, for, if, try and while. These skeletons are integrated with | 159 | ;; def, for, if, try and while. These skeletons are integrated with |
| 160 | ;; dabbrev. If you have `dabbrev-mode' activated and | 160 | ;; abbrev. If you have `abbrev-mode' activated and |
| 161 | ;; `python-skeleton-autoinsert' is set to t, then whenever you type | 161 | ;; `python-skeleton-autoinsert' is set to t, then whenever you type |
| 162 | ;; the name of any of those defined and hit SPC, they will be | 162 | ;; the name of any of those defined and hit SPC, they will be |
| 163 | ;; automatically expanded. As an alternative you can use the defined | 163 | ;; automatically expanded. As an alternative you can use the defined |
| @@ -177,12 +177,14 @@ | |||
| 177 | ;; might guessed you should run `python-shell-send-buffer' from time | 177 | ;; might guessed you should run `python-shell-send-buffer' from time |
| 178 | ;; to time to get better results too. | 178 | ;; to time to get better results too. |
| 179 | 179 | ||
| 180 | ;; Imenu: This mode supports Imenu in its most basic form, letting it | 180 | ;; Imenu: There are two index building functions to be used as |
| 181 | ;; build the necessary alist via `imenu-default-create-index-function' | 181 | ;; `imenu-create-index-function': `python-imenu-create-index' (the |
| 182 | ;; by having set `imenu-extract-index-name-function' to | 182 | ;; default one, builds the alist in form of a tree) and |
| 183 | ;; `python-info-current-defun' and | 183 | ;; `python-imenu-create-flat-index'. See also |
| 184 | ;; `imenu-prev-index-position-function' to | 184 | ;; `python-imenu-format-item-label-function', |
| 185 | ;; `python-imenu-prev-index-position'. | 185 | ;; `python-imenu-format-parent-item-label-function', |
| 186 | ;; `python-imenu-format-parent-item-jump-label-function' variables for | ||
| 187 | ;; changing the way labels are formatted in the tree version. | ||
| 186 | 188 | ||
| 187 | ;; If you used python-mode.el you probably will miss auto-indentation | 189 | ;; If you used python-mode.el you probably will miss auto-indentation |
| 188 | ;; when inserting newlines. To achieve the same behavior you have | 190 | ;; when inserting newlines. To achieve the same behavior you have |
| @@ -368,22 +370,24 @@ This variant of `rx' supports common python named REGEXPS." | |||
| 368 | 370 | ||
| 369 | ;;; Font-lock and syntax | 371 | ;;; Font-lock and syntax |
| 370 | 372 | ||
| 373 | (eval-when-compile | ||
| 374 | (defun python-syntax--context-compiler-macro (form type &optional syntax-ppss) | ||
| 375 | (pcase type | ||
| 376 | (`'comment | ||
| 377 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) | ||
| 378 | (and (nth 4 ppss) (nth 8 ppss)))) | ||
| 379 | (`'string | ||
| 380 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) | ||
| 381 | (and (nth 3 ppss) (nth 8 ppss)))) | ||
| 382 | (`'paren | ||
| 383 | `(nth 1 (or ,syntax-ppss (syntax-ppss)))) | ||
| 384 | (_ form)))) | ||
| 385 | |||
| 371 | (defun python-syntax-context (type &optional syntax-ppss) | 386 | (defun python-syntax-context (type &optional syntax-ppss) |
| 372 | "Return non-nil if point is on TYPE using SYNTAX-PPSS. | 387 | "Return non-nil if point is on TYPE using SYNTAX-PPSS. |
| 373 | TYPE can be `comment', `string' or `paren'. It returns the start | 388 | TYPE can be `comment', `string' or `paren'. It returns the start |
| 374 | character address of the specified TYPE." | 389 | character address of the specified TYPE." |
| 375 | (declare (compiler-macro | 390 | (declare (compiler-macro python-syntax--context-compiler-macro)) |
| 376 | (lambda (form) | ||
| 377 | (pcase type | ||
| 378 | (`'comment | ||
| 379 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) | ||
| 380 | (and (nth 4 ppss) (nth 8 ppss)))) | ||
| 381 | (`'string | ||
| 382 | `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) | ||
| 383 | (and (nth 3 ppss) (nth 8 ppss)))) | ||
| 384 | (`'paren | ||
| 385 | `(nth 1 (or ,syntax-ppss (syntax-ppss)))) | ||
| 386 | (_ form))))) | ||
| 387 | (let ((ppss (or syntax-ppss (syntax-ppss)))) | 391 | (let ((ppss (or syntax-ppss (syntax-ppss)))) |
| 388 | (pcase type | 392 | (pcase type |
| 389 | (`comment (and (nth 4 ppss) (nth 8 ppss))) | 393 | (`comment (and (nth 4 ppss) (nth 8 ppss))) |
| @@ -638,6 +642,13 @@ It makes underscores and dots word constituent chars.") | |||
| 638 | These make `python-indent-calculate-indentation' subtract the value of | 642 | These make `python-indent-calculate-indentation' subtract the value of |
| 639 | `python-indent-offset'.") | 643 | `python-indent-offset'.") |
| 640 | 644 | ||
| 645 | (defvar python-indent-block-enders | ||
| 646 | '("break" "continue" "pass" "raise" "return") | ||
| 647 | "List of words that mark the end of a block. | ||
| 648 | These make `python-indent-calculate-indentation' subtract the | ||
| 649 | value of `python-indent-offset' when `python-indent-context' is | ||
| 650 | AFTER-LINE.") | ||
| 651 | |||
| 641 | (defun python-indent-guess-indent-offset () | 652 | (defun python-indent-guess-indent-offset () |
| 642 | "Guess and set `python-indent-offset' for the current buffer." | 653 | "Guess and set `python-indent-offset' for the current buffer." |
| 643 | (interactive) | 654 | (interactive) |
| @@ -763,9 +774,13 @@ START is the buffer position where the sexp starts." | |||
| 763 | (save-excursion | 774 | (save-excursion |
| 764 | (goto-char context-start) | 775 | (goto-char context-start) |
| 765 | (current-indentation)) | 776 | (current-indentation)) |
| 766 | (if (progn | 777 | (if (or (save-excursion |
| 767 | (back-to-indentation) | 778 | (back-to-indentation) |
| 768 | (looking-at (regexp-opt python-indent-dedenters))) | 779 | (looking-at (regexp-opt python-indent-dedenters))) |
| 780 | (save-excursion | ||
| 781 | (python-util-forward-comment -1) | ||
| 782 | (python-nav-beginning-of-statement) | ||
| 783 | (member (current-word) python-indent-block-enders))) | ||
| 769 | python-indent-offset | 784 | python-indent-offset |
| 770 | 0))) | 785 | 0))) |
| 771 | ;; When inside of a string, do nothing. just use the current | 786 | ;; When inside of a string, do nothing. just use the current |
| @@ -1180,6 +1195,70 @@ Returns nil if point is not in a def or class." | |||
| 1180 | ;; Ensure point moves forward. | 1195 | ;; Ensure point moves forward. |
| 1181 | (and (> beg-pos (point)) (goto-char beg-pos))))) | 1196 | (and (> beg-pos (point)) (goto-char beg-pos))))) |
| 1182 | 1197 | ||
| 1198 | (defun python-nav--syntactically (fn poscompfn &optional contextfn) | ||
| 1199 | "Move point using FN avoiding places with specific context. | ||
| 1200 | FN must take no arguments. POSCOMPFN is a two arguments function | ||
| 1201 | used to compare current and previous point after it is moved | ||
| 1202 | using FN, this is normally a less-than or greater-than | ||
| 1203 | comparison. Optional argument CONTEXTFN defaults to | ||
| 1204 | `python-syntax-context-type' and is used for checking current | ||
| 1205 | point context, it must return a non-nil value if this point must | ||
| 1206 | be skipped." | ||
| 1207 | (let ((contextfn (or contextfn 'python-syntax-context-type)) | ||
| 1208 | (start-pos (point-marker)) | ||
| 1209 | (prev-pos)) | ||
| 1210 | (catch 'found | ||
| 1211 | (while t | ||
| 1212 | (let* ((newpos | ||
| 1213 | (and (funcall fn) (point-marker))) | ||
| 1214 | (context (funcall contextfn))) | ||
| 1215 | (cond ((and (not context) newpos | ||
| 1216 | (or (and (not prev-pos) newpos) | ||
| 1217 | (and prev-pos newpos | ||
| 1218 | (funcall poscompfn newpos prev-pos)))) | ||
| 1219 | (throw 'found (point-marker))) | ||
| 1220 | ((and newpos context) | ||
| 1221 | (setq prev-pos (point))) | ||
| 1222 | (t (when (not newpos) (goto-char start-pos)) | ||
| 1223 | (throw 'found nil)))))))) | ||
| 1224 | |||
| 1225 | (defun python-nav--forward-defun (arg) | ||
| 1226 | "Internal implementation of python-nav-{backward,forward}-defun. | ||
| 1227 | Uses ARG to define which function to call, and how many times | ||
| 1228 | repeat it." | ||
| 1229 | (let ((found)) | ||
| 1230 | (while (and (> arg 0) | ||
| 1231 | (setq found | ||
| 1232 | (python-nav--syntactically | ||
| 1233 | (lambda () | ||
| 1234 | (re-search-forward | ||
| 1235 | python-nav-beginning-of-defun-regexp nil t)) | ||
| 1236 | '>))) | ||
| 1237 | (setq arg (1- arg))) | ||
| 1238 | (while (and (< arg 0) | ||
| 1239 | (setq found | ||
| 1240 | (python-nav--syntactically | ||
| 1241 | (lambda () | ||
| 1242 | (re-search-backward | ||
| 1243 | python-nav-beginning-of-defun-regexp nil t)) | ||
| 1244 | '<))) | ||
| 1245 | (setq arg (1+ arg))) | ||
| 1246 | found)) | ||
| 1247 | |||
| 1248 | (defun python-nav-backward-defun (&optional arg) | ||
| 1249 | "Navigate to closer defun backward ARG times. | ||
| 1250 | Unlikely `python-nav-beginning-of-defun' this doesn't care about | ||
| 1251 | nested definitions." | ||
| 1252 | (interactive "^p") | ||
| 1253 | (python-nav--forward-defun (- (or arg 1)))) | ||
| 1254 | |||
| 1255 | (defun python-nav-forward-defun (&optional arg) | ||
| 1256 | "Navigate to closer defun forward ARG times. | ||
| 1257 | Unlikely `python-nav-beginning-of-defun' this doesn't care about | ||
| 1258 | nested definitions." | ||
| 1259 | (interactive "^p") | ||
| 1260 | (python-nav--forward-defun (or arg 1))) | ||
| 1261 | |||
| 1183 | (defun python-nav-beginning-of-statement () | 1262 | (defun python-nav-beginning-of-statement () |
| 1184 | "Move to start of current statement." | 1263 | "Move to start of current statement." |
| 1185 | (interactive "^") | 1264 | (interactive "^") |
| @@ -1603,7 +1682,7 @@ This variable, when set to a string, makes the values stored in | |||
| 1603 | `python-shell-process-environment' and `python-shell-exec-path' | 1682 | `python-shell-process-environment' and `python-shell-exec-path' |
| 1604 | to be modified properly so shells are started with the specified | 1683 | to be modified properly so shells are started with the specified |
| 1605 | virtualenv." | 1684 | virtualenv." |
| 1606 | :type 'string | 1685 | :type '(choice (const nil) string) |
| 1607 | :group 'python | 1686 | :group 'python |
| 1608 | :safe 'stringp) | 1687 | :safe 'stringp) |
| 1609 | 1688 | ||
| @@ -2644,8 +2723,8 @@ the if condition." | |||
| 2644 | (defvar python-skeleton-available '() | 2723 | (defvar python-skeleton-available '() |
| 2645 | "Internal list of available skeletons.") | 2724 | "Internal list of available skeletons.") |
| 2646 | 2725 | ||
| 2647 | (define-abbrev-table 'python-mode-abbrev-table () | 2726 | (define-abbrev-table 'python-mode-skeleton-abbrev-table () |
| 2648 | "Abbrev table for Python mode." | 2727 | "Abbrev table for Python mode skeletons." |
| 2649 | :case-fixed t | 2728 | :case-fixed t |
| 2650 | ;; Allow / inside abbrevs. | 2729 | ;; Allow / inside abbrevs. |
| 2651 | :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*" | 2730 | :regexp "\\(?:^\\|[^/]\\)\\<\\([[:word:]/]+\\)\\W*" |
| @@ -2658,13 +2737,13 @@ the if condition." | |||
| 2658 | (defmacro python-skeleton-define (name doc &rest skel) | 2737 | (defmacro python-skeleton-define (name doc &rest skel) |
| 2659 | "Define a `python-mode' skeleton using NAME DOC and SKEL. | 2738 | "Define a `python-mode' skeleton using NAME DOC and SKEL. |
| 2660 | The skeleton will be bound to python-skeleton-NAME and will | 2739 | The skeleton will be bound to python-skeleton-NAME and will |
| 2661 | be added to `python-mode-abbrev-table'." | 2740 | be added to `python-mode-skeleton-abbrev-table'." |
| 2662 | (declare (indent 2)) | 2741 | (declare (indent 2)) |
| 2663 | (let* ((name (symbol-name name)) | 2742 | (let* ((name (symbol-name name)) |
| 2664 | (function-name (intern (concat "python-skeleton-" name)))) | 2743 | (function-name (intern (concat "python-skeleton-" name)))) |
| 2665 | `(progn | 2744 | `(progn |
| 2666 | (define-abbrev python-mode-abbrev-table ,name "" ',function-name | 2745 | (define-abbrev python-mode-skeleton-abbrev-table |
| 2667 | :system t) | 2746 | ,name "" ',function-name :system t) |
| 2668 | (setq python-skeleton-available | 2747 | (setq python-skeleton-available |
| 2669 | (cons ',function-name python-skeleton-available)) | 2748 | (cons ',function-name python-skeleton-available)) |
| 2670 | (define-skeleton ,function-name | 2749 | (define-skeleton ,function-name |
| @@ -2672,6 +2751,10 @@ be added to `python-mode-abbrev-table'." | |||
| 2672 | (format "Insert %s statement." name)) | 2751 | (format "Insert %s statement." name)) |
| 2673 | ,@skel)))) | 2752 | ,@skel)))) |
| 2674 | 2753 | ||
| 2754 | (define-abbrev-table 'python-mode-abbrev-table () | ||
| 2755 | "Abbrev table for Python mode." | ||
| 2756 | :parents (list python-mode-skeleton-abbrev-table)) | ||
| 2757 | |||
| 2675 | (defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel) | 2758 | (defmacro python-define-auxiliary-skeleton (name doc &optional &rest skel) |
| 2676 | "Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL. | 2759 | "Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL. |
| 2677 | The skeleton will be bound to python-skeleton-NAME." | 2760 | The skeleton will be bound to python-skeleton-NAME." |
| @@ -2928,15 +3011,193 @@ Interactively, prompt for symbol." | |||
| 2928 | 3011 | ||
| 2929 | ;;; Imenu | 3012 | ;;; Imenu |
| 2930 | 3013 | ||
| 2931 | (defun python-imenu-prev-index-position () | 3014 | (defvar python-imenu-format-item-label-function |
| 2932 | "Python mode's `imenu-prev-index-position-function'." | 3015 | 'python-imenu-format-item-label |
| 2933 | (let ((found)) | 3016 | "Imenu function used to format an item label. |
| 2934 | (while (and (setq found | 3017 | It must be a function with two arguments: TYPE and NAME.") |
| 2935 | (re-search-backward python-nav-beginning-of-defun-regexp nil t)) | 3018 | |
| 2936 | (not (python-info-looking-at-beginning-of-defun)))) | 3019 | (defvar python-imenu-format-parent-item-label-function |
| 2937 | (and found | 3020 | 'python-imenu-format-parent-item-label |
| 2938 | (python-info-looking-at-beginning-of-defun) | 3021 | "Imenu function used to format a parent item label. |
| 2939 | (python-info-current-defun)))) | 3022 | It must be a function with two arguments: TYPE and NAME.") |
| 3023 | |||
| 3024 | (defvar python-imenu-format-parent-item-jump-label-function | ||
| 3025 | 'python-imenu-format-parent-item-jump-label | ||
| 3026 | "Imenu function used to format a parent jump item label. | ||
| 3027 | It must be a function with two arguments: TYPE and NAME.") | ||
| 3028 | |||
| 3029 | (defun python-imenu-format-item-label (type name) | ||
| 3030 | "Return imenu label for single node using TYPE and NAME." | ||
| 3031 | (format "%s (%s)" name type)) | ||
| 3032 | |||
| 3033 | (defun python-imenu-format-parent-item-label (type name) | ||
| 3034 | "Return imenu label for parent node using TYPE and NAME." | ||
| 3035 | (format "%s..." (python-imenu-format-item-label type name))) | ||
| 3036 | |||
| 3037 | (defun python-imenu-format-parent-item-jump-label (type name) | ||
| 3038 | "Return imenu label for parent node jump using TYPE and NAME." | ||
| 3039 | (if (string= type "class") | ||
| 3040 | "*class definition*" | ||
| 3041 | "*function definition*")) | ||
| 3042 | |||
| 3043 | (defun python-imenu--put-parent (type name pos num-children tree &optional root) | ||
| 3044 | "Add the parent with TYPE, NAME, POS and NUM-CHILDREN to TREE. | ||
| 3045 | Optional Argument ROOT must be non-nil when the node being | ||
| 3046 | processed is the root of the TREE." | ||
| 3047 | (let ((label | ||
| 3048 | (funcall python-imenu-format-item-label-function type name)) | ||
| 3049 | (jump-label | ||
| 3050 | (funcall python-imenu-format-parent-item-jump-label-function type name))) | ||
| 3051 | (if root | ||
| 3052 | ;; This is the root, everything is a children. | ||
| 3053 | (cons label (cons (cons jump-label pos) tree)) | ||
| 3054 | ;; This is node a which may contain some children. | ||
| 3055 | (cons | ||
| 3056 | (cons label (cons (cons jump-label pos) | ||
| 3057 | ;; Append all the children | ||
| 3058 | (python-util-popn tree num-children))) | ||
| 3059 | ;; All previous non-children nodes. | ||
| 3060 | (nthcdr num-children tree))))) | ||
| 3061 | |||
| 3062 | (defun python-imenu--build-tree (&optional min-indent prev-indent num-children tree) | ||
| 3063 | "Recursively build the tree of nested definitions of a node. | ||
| 3064 | Arguments MIN-INDENT PREV-INDENT NUM-CHILDREN and TREE are | ||
| 3065 | internal and should not be passed explicitly unless you know what | ||
| 3066 | you are doing." | ||
| 3067 | (setq num-children (or num-children 0) | ||
| 3068 | min-indent (or min-indent 0)) | ||
| 3069 | (let* ((pos (python-nav-backward-defun)) | ||
| 3070 | (type) | ||
| 3071 | (name (when (and pos (looking-at python-nav-beginning-of-defun-regexp)) | ||
| 3072 | (let ((split (split-string (match-string-no-properties 0)))) | ||
| 3073 | (setq type (car split)) | ||
| 3074 | (cadr split)))) | ||
| 3075 | (label (when name | ||
| 3076 | (funcall python-imenu-format-item-label-function type name))) | ||
| 3077 | (indent (current-indentation))) | ||
| 3078 | (cond ((not pos) | ||
| 3079 | ;; No defun found, nothing to add. | ||
| 3080 | tree) | ||
| 3081 | ((equal indent 0) | ||
| 3082 | (if (> num-children 0) | ||
| 3083 | ;; Append it as the parent of everything collected to | ||
| 3084 | ;; this point. | ||
| 3085 | (python-imenu--put-parent type name pos num-children tree t) | ||
| 3086 | ;; There are no children, this is a lonely defun. | ||
| 3087 | (cons label pos))) | ||
| 3088 | ((equal min-indent indent) | ||
| 3089 | ;; Stop collecting nodes after moving to a position with | ||
| 3090 | ;; indentation equaling min-indent. This is specially | ||
| 3091 | ;; useful for navigating nested definitions recursively. | ||
| 3092 | tree) | ||
| 3093 | (t | ||
| 3094 | (python-imenu--build-tree | ||
| 3095 | min-indent | ||
| 3096 | indent | ||
| 3097 | ;; Add another children, either when this is the | ||
| 3098 | ;; first call or when indentation is | ||
| 3099 | ;; less-or-equal than previous. And do not | ||
| 3100 | ;; discard the number of children, because the | ||
| 3101 | ;; way code is scanned, all children are | ||
| 3102 | ;; collected until a root node yet to be found | ||
| 3103 | ;; appears. | ||
| 3104 | (if (or (not prev-indent) | ||
| 3105 | (and | ||
| 3106 | (> indent min-indent) | ||
| 3107 | (<= indent prev-indent))) | ||
| 3108 | (1+ num-children) | ||
| 3109 | num-children) | ||
| 3110 | (cond ((not prev-indent) | ||
| 3111 | ;; First call to the function: append this | ||
| 3112 | ;; defun to the index. | ||
| 3113 | (list (cons label pos))) | ||
| 3114 | ((= indent prev-indent) | ||
| 3115 | ;; Add another defun with the same depth | ||
| 3116 | ;; as the previous. | ||
| 3117 | (cons (cons label pos) tree)) | ||
| 3118 | ((and (< indent prev-indent) | ||
| 3119 | (< 0 num-children)) | ||
| 3120 | ;; There are children to be appended and | ||
| 3121 | ;; the previous defun had more | ||
| 3122 | ;; indentation, the current one must be a | ||
| 3123 | ;; parent. | ||
| 3124 | (python-imenu--put-parent type name pos num-children tree)) | ||
| 3125 | ((> indent prev-indent) | ||
| 3126 | ;; There are children defuns deeper than | ||
| 3127 | ;; current depth. Fear not, we already | ||
| 3128 | ;; know how to treat them. | ||
| 3129 | (cons | ||
| 3130 | (prog1 | ||
| 3131 | (python-imenu--build-tree | ||
| 3132 | prev-indent indent 1 (list (cons label pos))) | ||
| 3133 | ;; Adjustment: after scanning backwards | ||
| 3134 | ;; for all deeper children, we need to | ||
| 3135 | ;; continue our scan for a parent from | ||
| 3136 | ;; the current defun we are looking at. | ||
| 3137 | (python-nav-forward-defun)) | ||
| 3138 | tree)))))))) | ||
| 3139 | |||
| 3140 | (defun python-imenu-create-index () | ||
| 3141 | "Return tree Imenu alist for the current python buffer. | ||
| 3142 | Change `python-imenu-format-item-label-function', | ||
| 3143 | `python-imenu-format-parent-item-label-function', | ||
| 3144 | `python-imenu-format-parent-item-jump-label-function' to | ||
| 3145 | customize how labels are formatted." | ||
| 3146 | (goto-char (point-max)) | ||
| 3147 | (let ((index) | ||
| 3148 | (tree)) | ||
| 3149 | (while (setq tree (python-imenu--build-tree)) | ||
| 3150 | (setq index (cons tree index))) | ||
| 3151 | index)) | ||
| 3152 | |||
| 3153 | (defun python-imenu-create-flat-index (&optional alist prefix) | ||
| 3154 | "Return flat outline of the current python buffer for Imenu. | ||
| 3155 | Optional Argument ALIST is the tree to be flattened, when nil | ||
| 3156 | `python-imenu-build-index' is used with | ||
| 3157 | `python-imenu-format-parent-item-jump-label-function' | ||
| 3158 | `python-imenu-format-parent-item-label-function' | ||
| 3159 | `python-imenu-format-item-label-function' set to (lambda (type | ||
| 3160 | name) name). Optional Argument PREFIX is used in recursive calls | ||
| 3161 | and should not be passed explicitly. | ||
| 3162 | |||
| 3163 | Converts this: | ||
| 3164 | |||
| 3165 | \((\"Foo\" . 103) | ||
| 3166 | (\"Bar\" . 138) | ||
| 3167 | (\"decorator\" | ||
| 3168 | (\"decorator\" . 173) | ||
| 3169 | (\"wrap\" | ||
| 3170 | (\"wrap\" . 353) | ||
| 3171 | (\"wrapped_f\" . 393)))) | ||
| 3172 | |||
| 3173 | To this: | ||
| 3174 | |||
| 3175 | \((\"Foo\" . 103) | ||
| 3176 | (\"Bar\" . 138) | ||
| 3177 | (\"decorator\" . 173) | ||
| 3178 | (\"decorator.wrap\" . 353) | ||
| 3179 | (\"decorator.wrapped_f\" . 393))" | ||
| 3180 | ;; Inspired by imenu--flatten-index-alist removed in revno 21853. | ||
| 3181 | (apply | ||
| 3182 | 'nconc | ||
| 3183 | (mapcar | ||
| 3184 | (lambda (item) | ||
| 3185 | (let ((name (if prefix | ||
| 3186 | (concat prefix "." (car item)) | ||
| 3187 | (car item))) | ||
| 3188 | (pos (cdr item))) | ||
| 3189 | (cond ((or (numberp pos) (markerp pos)) | ||
| 3190 | (list (cons name pos))) | ||
| 3191 | ((listp pos) | ||
| 3192 | (cons | ||
| 3193 | (cons name (cdar pos)) | ||
| 3194 | (python-imenu-create-flat-index (cddr item) name)))))) | ||
| 3195 | (or alist | ||
| 3196 | (let* ((fn (lambda (type name) name)) | ||
| 3197 | (python-imenu-format-item-label-function fn) | ||
| 3198 | (python-imenu-format-parent-item-label-function fn) | ||
| 3199 | (python-imenu-format-parent-item-jump-label-function fn)) | ||
| 3200 | (python-imenu-create-index)))))) | ||
| 2940 | 3201 | ||
| 2941 | 3202 | ||
| 2942 | ;;; Misc helpers | 3203 | ;;; Misc helpers |
| @@ -3257,6 +3518,22 @@ Optional argument DIRECTION defines the direction to move to." | |||
| 3257 | (goto-char comment-start)) | 3518 | (goto-char comment-start)) |
| 3258 | (forward-comment factor))) | 3519 | (forward-comment factor))) |
| 3259 | 3520 | ||
| 3521 | (defun python-util-popn (lst n) | ||
| 3522 | "Return LST first N elements. | ||
| 3523 | N should be an integer, when it's a natural negative number its | ||
| 3524 | opposite is used. When N is bigger than the length of LST, the | ||
| 3525 | list is returned as is." | ||
| 3526 | (let* ((n (min (abs n))) | ||
| 3527 | (len (length lst)) | ||
| 3528 | (acc)) | ||
| 3529 | (if (> n len) | ||
| 3530 | lst | ||
| 3531 | (while (< 0 n) | ||
| 3532 | (setq acc (cons (car lst) acc) | ||
| 3533 | lst (cdr lst) | ||
| 3534 | n (1- n))) | ||
| 3535 | (reverse acc)))) | ||
| 3536 | |||
| 3260 | 3537 | ||
| 3261 | ;;;###autoload | 3538 | ;;;###autoload |
| 3262 | (define-derived-mode python-mode prog-mode "Python" | 3539 | (define-derived-mode python-mode prog-mode "Python" |
| @@ -3302,11 +3579,8 @@ if that value is non-nil." | |||
| 3302 | (add-hook 'post-self-insert-hook | 3579 | (add-hook 'post-self-insert-hook |
| 3303 | 'python-indent-post-self-insert-function nil 'local) | 3580 | 'python-indent-post-self-insert-function nil 'local) |
| 3304 | 3581 | ||
| 3305 | (set (make-local-variable 'imenu-extract-index-name-function) | 3582 | (set (make-local-variable 'imenu-create-index-function) |
| 3306 | #'python-info-current-defun) | 3583 | #'python-imenu-create-index) |
| 3307 | |||
| 3308 | (set (make-local-variable 'imenu-prev-index-position-function) | ||
| 3309 | #'python-imenu-prev-index-position) | ||
| 3310 | 3584 | ||
| 3311 | (set (make-local-variable 'add-log-current-defun-function) | 3585 | (set (make-local-variable 'add-log-current-defun-function) |
| 3312 | #'python-info-current-defun) | 3586 | #'python-info-current-defun) |
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 6e471d1aa2a..fa4efe49b7b 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el | |||
| @@ -113,7 +113,7 @@ | |||
| 113 | "Regexp to match the beginning of a heredoc.") | 113 | "Regexp to match the beginning of a heredoc.") |
| 114 | 114 | ||
| 115 | (defconst ruby-expression-expansion-re | 115 | (defconst ruby-expression-expansion-re |
| 116 | "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)")) | 116 | "\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)")) |
| 117 | 117 | ||
| 118 | (defun ruby-here-doc-end-match () | 118 | (defun ruby-here-doc-end-match () |
| 119 | "Return a regexp to find the end of a heredoc. | 119 | "Return a regexp to find the end of a heredoc. |
| @@ -148,13 +148,16 @@ This should only be called after matching against `ruby-here-doc-beg-re'." | |||
| 148 | (define-abbrev-table 'ruby-mode-abbrev-table () | 148 | (define-abbrev-table 'ruby-mode-abbrev-table () |
| 149 | "Abbrev table in use in Ruby mode buffers.") | 149 | "Abbrev table in use in Ruby mode buffers.") |
| 150 | 150 | ||
| 151 | (defvar ruby-use-smie nil) | ||
| 152 | |||
| 151 | (defvar ruby-mode-map | 153 | (defvar ruby-mode-map |
| 152 | (let ((map (make-sparse-keymap))) | 154 | (let ((map (make-sparse-keymap))) |
| 153 | (define-key map (kbd "M-C-b") 'ruby-backward-sexp) | 155 | (unless ruby-use-smie |
| 154 | (define-key map (kbd "M-C-f") 'ruby-forward-sexp) | 156 | (define-key map (kbd "M-C-b") 'ruby-backward-sexp) |
| 157 | (define-key map (kbd "M-C-f") 'ruby-forward-sexp) | ||
| 158 | (define-key map (kbd "M-C-q") 'ruby-indent-exp)) | ||
| 155 | (define-key map (kbd "M-C-p") 'ruby-beginning-of-block) | 159 | (define-key map (kbd "M-C-p") 'ruby-beginning-of-block) |
| 156 | (define-key map (kbd "M-C-n") 'ruby-end-of-block) | 160 | (define-key map (kbd "M-C-n") 'ruby-end-of-block) |
| 157 | (define-key map (kbd "M-C-q") 'ruby-indent-exp) | ||
| 158 | (define-key map (kbd "C-c {") 'ruby-toggle-block) | 161 | (define-key map (kbd "C-c {") 'ruby-toggle-block) |
| 159 | map) | 162 | map) |
| 160 | "Keymap used in Ruby mode.") | 163 | "Keymap used in Ruby mode.") |
| @@ -236,6 +239,111 @@ Also ignores spaces after parenthesis when 'space." | |||
| 236 | (put 'ruby-comment-column 'safe-local-variable 'integerp) | 239 | (put 'ruby-comment-column 'safe-local-variable 'integerp) |
| 237 | (put 'ruby-deep-arglist 'safe-local-variable 'booleanp) | 240 | (put 'ruby-deep-arglist 'safe-local-variable 'booleanp) |
| 238 | 241 | ||
| 242 | ;;; SMIE support | ||
| 243 | |||
| 244 | (require 'smie) | ||
| 245 | |||
| 246 | (defconst ruby-smie-grammar | ||
| 247 | ;; FIXME: Add support for Cucumber. | ||
| 248 | (smie-prec2->grammar | ||
| 249 | (smie-bnf->prec2 | ||
| 250 | '((id) | ||
| 251 | (insts (inst) (insts ";" insts)) | ||
| 252 | (inst (exp) (inst "iuwu-mod" exp)) | ||
| 253 | (exp (exp1) (exp "," exp)) | ||
| 254 | (exp1 (exp2) (exp2 "?" exp1 ":" exp1)) | ||
| 255 | (exp2 ("def" insts "end") | ||
| 256 | ("begin" insts-rescue-insts "end") | ||
| 257 | ("do" insts "end") | ||
| 258 | ("class" insts "end") ("module" insts "end") | ||
| 259 | ("for" for-body "end") | ||
| 260 | ("[" expseq "]") | ||
| 261 | ("{" hashvals "}") | ||
| 262 | ("while" insts "end") | ||
| 263 | ("until" insts "end") | ||
| 264 | ("unless" insts "end") | ||
| 265 | ("if" if-body "end") | ||
| 266 | ("case" cases "end")) | ||
| 267 | (for-body (for-head ";" insts)) | ||
| 268 | (for-head (id "in" exp)) | ||
| 269 | (cases (exp "then" insts) ;; FIXME: Ruby also allows (exp ":" insts). | ||
| 270 | (cases "when" cases) (insts "else" insts)) | ||
| 271 | (expseq (exp) );;(expseq "," expseq) | ||
| 272 | (hashvals (id "=>" exp1) (hashvals "," hashvals)) | ||
| 273 | (insts-rescue-insts (insts) | ||
| 274 | (insts-rescue-insts "rescue" insts-rescue-insts) | ||
| 275 | (insts-rescue-insts "ensure" insts-rescue-insts)) | ||
| 276 | (itheni (insts) (exp "then" insts)) | ||
| 277 | (ielsei (itheni) (itheni "else" insts)) | ||
| 278 | (if-body (ielsei) (if-body "elsif" if-body))) | ||
| 279 | '((nonassoc "in") (assoc ";") (assoc ",")) | ||
| 280 | '((assoc "when")) | ||
| 281 | '((assoc "elsif")) | ||
| 282 | '((assoc "rescue" "ensure")) | ||
| 283 | '((assoc ","))))) | ||
| 284 | |||
| 285 | (defun ruby-smie--bosp () | ||
| 286 | (save-excursion (skip-chars-backward " \t") | ||
| 287 | (or (bolp) (eq (char-before) ?\;)))) | ||
| 288 | |||
| 289 | (defun ruby-smie--implicit-semi-p () | ||
| 290 | (save-excursion | ||
| 291 | (skip-chars-backward " \t") | ||
| 292 | (not (or (bolp) | ||
| 293 | (memq (char-before) '(?\; ?- ?+ ?* ?/ ?:)) | ||
| 294 | (and (memq (char-before) '(?\? ?=)) | ||
| 295 | (not (memq (char-syntax (char-before (1- (point)))) | ||
| 296 | '(?w ?_)))))))) | ||
| 297 | |||
| 298 | (defun ruby-smie--forward-token () | ||
| 299 | (skip-chars-forward " \t") | ||
| 300 | (if (and (looking-at "[\n#]") | ||
| 301 | ;; Only add implicit ; when needed. | ||
| 302 | (ruby-smie--implicit-semi-p)) | ||
| 303 | (progn | ||
| 304 | (if (eolp) (forward-char 1) (forward-comment 1)) | ||
| 305 | ";") | ||
| 306 | (forward-comment (point-max)) | ||
| 307 | (let ((tok (smie-default-forward-token))) | ||
| 308 | (cond | ||
| 309 | ((member tok '("unless" "if" "while" "until")) | ||
| 310 | (if (save-excursion (forward-word -1) (ruby-smie--bosp)) | ||
| 311 | tok "iuwu-mod")) | ||
| 312 | (t tok))))) | ||
| 313 | |||
| 314 | (defun ruby-smie--backward-token () | ||
| 315 | (let ((pos (point))) | ||
| 316 | (forward-comment (- (point))) | ||
| 317 | (if (and (> pos (line-end-position)) | ||
| 318 | (ruby-smie--implicit-semi-p)) | ||
| 319 | (progn (skip-chars-forward " \t") | ||
| 320 | ";") | ||
| 321 | (let ((tok (smie-default-backward-token))) | ||
| 322 | (cond | ||
| 323 | ((member tok '("unless" "if" "while" "until")) | ||
| 324 | (if (ruby-smie--bosp) | ||
| 325 | tok "iuwu-mod")) | ||
| 326 | (t tok)))))) | ||
| 327 | |||
| 328 | (defun ruby-smie-rules (kind token) | ||
| 329 | (pcase (cons kind token) | ||
| 330 | (`(:elem . basic) ruby-indent-level) | ||
| 331 | (`(:after . ";") | ||
| 332 | (if (smie-rule-parent-p "def" "begin" "do" "class" "module" "for" | ||
| 333 | "[" "{" "while" "until" "unless" | ||
| 334 | "if" "then" "elsif" "else" "when" | ||
| 335 | "rescue" "ensure") | ||
| 336 | (smie-rule-parent ruby-indent-level) | ||
| 337 | ;; For (invalid) code between switch and case. | ||
| 338 | ;; (if (smie-parent-p "switch") 4) | ||
| 339 | 0)) | ||
| 340 | (`(:before . ,(or `"else" `"then" `"elsif")) 0) | ||
| 341 | (`(:before . ,(or `"when")) | ||
| 342 | (if (not (smie-rule-sibling-p)) 0)) ;; ruby-indent-level | ||
| 343 | ;; Hack attack: Since newlines are separators, don't try to align args that | ||
| 344 | ;; appear on a separate line. | ||
| 345 | (`(:list-intro . ";") t))) | ||
| 346 | |||
| 239 | (defun ruby-imenu-create-index-in-block (prefix beg end) | 347 | (defun ruby-imenu-create-index-in-block (prefix beg end) |
| 240 | "Create an imenu index of methods inside a block." | 348 | "Create an imenu index of methods inside a block." |
| 241 | (let ((index-alist '()) (case-fold-search nil) | 349 | (let ((index-alist '()) (case-fold-search nil) |
| @@ -290,7 +398,11 @@ Also ignores spaces after parenthesis when 'space." | |||
| 290 | (set-syntax-table ruby-mode-syntax-table) | 398 | (set-syntax-table ruby-mode-syntax-table) |
| 291 | (setq local-abbrev-table ruby-mode-abbrev-table) | 399 | (setq local-abbrev-table ruby-mode-abbrev-table) |
| 292 | (setq indent-tabs-mode ruby-indent-tabs-mode) | 400 | (setq indent-tabs-mode ruby-indent-tabs-mode) |
| 293 | (set (make-local-variable 'indent-line-function) 'ruby-indent-line) | 401 | (if ruby-use-smie |
| 402 | (smie-setup ruby-smie-grammar #'ruby-smie-rules | ||
| 403 | :forward-token #'ruby-smie--forward-token | ||
| 404 | :backward-token #'ruby-smie--backward-token) | ||
| 405 | (set (make-local-variable 'indent-line-function) 'ruby-indent-line)) | ||
| 294 | (set (make-local-variable 'require-final-newline) t) | 406 | (set (make-local-variable 'require-final-newline) t) |
| 295 | (set (make-local-variable 'comment-start) "# ") | 407 | (set (make-local-variable 'comment-start) "# ") |
| 296 | (set (make-local-variable 'comment-end) "") | 408 | (set (make-local-variable 'comment-end) "") |
| @@ -847,22 +959,24 @@ Can be one of `heredoc', `modifier', `expr-qstr', `expr-re'." | |||
| 847 | indent)))) | 959 | indent)))) |
| 848 | 960 | ||
| 849 | (defun ruby-beginning-of-defun (&optional arg) | 961 | (defun ruby-beginning-of-defun (&optional arg) |
| 850 | "Move backward to the beginning of the current top-level defun. | 962 | "Move backward to the beginning of the current defun. |
| 851 | With ARG, move backward multiple defuns. Negative ARG means | 963 | With ARG, move backward multiple defuns. Negative ARG means |
| 852 | move forward." | 964 | move forward." |
| 853 | (interactive "p") | 965 | (interactive "p") |
| 854 | (and (re-search-backward (concat "^\\s *" ruby-defun-beg-re "\\_>") | 966 | (let (case-fold-search) |
| 855 | nil t (or arg 1)) | 967 | (and (re-search-backward (concat "^\\s *" ruby-defun-beg-re "\\_>") |
| 856 | (beginning-of-line))) | 968 | nil t (or arg 1)) |
| 857 | 969 | (beginning-of-line)))) | |
| 858 | (defun ruby-end-of-defun (&optional arg) | 970 | |
| 859 | "Move forward to the end of the current top-level defun. | 971 | (defun ruby-end-of-defun () |
| 860 | With ARG, move forward multiple defuns. Negative ARG means | 972 | "Move point to the end of the current defun. |
| 861 | move backward." | 973 | The defun begins at or after the point. This function is called |
| 974 | by `end-of-defun'." | ||
| 862 | (interactive "p") | 975 | (interactive "p") |
| 863 | (ruby-forward-sexp) | 976 | (ruby-forward-sexp) |
| 864 | (when (looking-back (concat "^\\s *" ruby-block-end-re)) | 977 | (let (case-fold-search) |
| 865 | (forward-line 1))) | 978 | (when (looking-back (concat "^\\s *" ruby-block-end-re)) |
| 979 | (forward-line 1)))) | ||
| 866 | 980 | ||
| 867 | (defun ruby-beginning-of-indent () | 981 | (defun ruby-beginning-of-indent () |
| 868 | "Backtrack to a line which can be used as a reference for | 982 | "Backtrack to a line which can be used as a reference for |
| @@ -881,6 +995,7 @@ current block, a sibling block, or an outer block. Do that (abs N) times." | |||
| 881 | (depth (or (nth 2 (ruby-parse-region (line-beginning-position) | 995 | (depth (or (nth 2 (ruby-parse-region (line-beginning-position) |
| 882 | (line-end-position))) | 996 | (line-end-position))) |
| 883 | 0)) | 997 | 0)) |
| 998 | case-fold-search | ||
| 884 | down done) | 999 | down done) |
| 885 | (when (< (* depth signum) 0) | 1000 | (when (< (* depth signum) 0) |
| 886 | ;; Moving end -> end or beginning -> beginning. | 1001 | ;; Moving end -> end or beginning -> beginning. |
| @@ -1232,6 +1347,9 @@ If the result is do-end block, it will always be multiline." | |||
| 1232 | (declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit)) | 1347 | (declare-function ruby-syntax-propertize-heredoc "ruby-mode" (limit)) |
| 1233 | (declare-function ruby-syntax-enclosing-percent-literal "ruby-mode" (limit)) | 1348 | (declare-function ruby-syntax-enclosing-percent-literal "ruby-mode" (limit)) |
| 1234 | (declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit)) | 1349 | (declare-function ruby-syntax-propertize-percent-literal "ruby-mode" (limit)) |
| 1350 | ;; Unusual code layout confuses the byte-compiler. | ||
| 1351 | (declare-function ruby-syntax-propertize-expansion "ruby-mode" ()) | ||
| 1352 | (declare-function ruby-syntax-expansion-allowed-p "ruby-mode" (parse-state)) | ||
| 1235 | 1353 | ||
| 1236 | (if (eval-when-compile (fboundp #'syntax-propertize-rules)) | 1354 | (if (eval-when-compile (fboundp #'syntax-propertize-rules)) |
| 1237 | ;; New code that works independently from font-lock. | 1355 | ;; New code that works independently from font-lock. |
| @@ -1245,54 +1363,70 @@ If the result is do-end block, it will always be multiline." | |||
| 1245 | '("gsub" "gsub!" "sub" "sub!" "scan" "split" "split!" "index" "match" | 1363 | '("gsub" "gsub!" "sub" "sub!" "scan" "split" "split!" "index" "match" |
| 1246 | "assert_match" "Given" "Then" "When") | 1364 | "assert_match" "Given" "Then" "When") |
| 1247 | "Methods that can take regexp as the first argument. | 1365 | "Methods that can take regexp as the first argument. |
| 1248 | It will be properly highlighted even when the call omits parens.")) | 1366 | It will be properly highlighted even when the call omits parens.") |
| 1367 | |||
| 1368 | (defvar ruby-syntax-before-regexp-re | ||
| 1369 | (concat | ||
| 1370 | ;; Special tokens that can't be followed by a division operator. | ||
| 1371 | "\\(^\\|[[=(,~?:;<>]" | ||
| 1372 | ;; Control flow keywords and operators following bol or whitespace. | ||
| 1373 | "\\|\\(?:^\\|\\s \\)" | ||
| 1374 | (regexp-opt '("if" "elsif" "unless" "while" "until" "when" "and" | ||
| 1375 | "or" "not" "&&" "||")) | ||
| 1376 | ;; Method name from the list. | ||
| 1377 | "\\|\\_<" | ||
| 1378 | (regexp-opt ruby-syntax-methods-before-regexp) | ||
| 1379 | "\\)\\s *") | ||
| 1380 | "Regexp to match text that can be followed by a regular expression.")) | ||
| 1249 | 1381 | ||
| 1250 | (defun ruby-syntax-propertize-function (start end) | 1382 | (defun ruby-syntax-propertize-function (start end) |
| 1251 | "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." | 1383 | "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." |
| 1252 | (goto-char start) | 1384 | (let (case-fold-search) |
| 1253 | (ruby-syntax-propertize-heredoc end) | 1385 | (goto-char start) |
| 1254 | (ruby-syntax-enclosing-percent-literal end) | 1386 | (remove-text-properties start end '(ruby-expansion-match-data)) |
| 1255 | (funcall | 1387 | (ruby-syntax-propertize-heredoc end) |
| 1256 | (syntax-propertize-rules | 1388 | (ruby-syntax-enclosing-percent-literal end) |
| 1257 | ;; $' $" $` .... are variables. | 1389 | (funcall |
| 1258 | ;; ?' ?" ?` are ascii codes. | 1390 | (syntax-propertize-rules |
| 1259 | ("\\([?$]\\)[#\"'`]" | 1391 | ;; $' $" $` .... are variables. |
| 1260 | (1 (unless (save-excursion | 1392 | ;; ?' ?" ?` are ascii codes. |
| 1261 | ;; Not within a string. | 1393 | ("\\([?$]\\)[#\"'`]" |
| 1262 | (nth 3 (syntax-ppss (match-beginning 0)))) | 1394 | (1 (unless (save-excursion |
| 1263 | (string-to-syntax "\\")))) | 1395 | ;; Not within a string. |
| 1264 | ;; Regexps: regexps are distinguished from division because | 1396 | (nth 3 (syntax-ppss (match-beginning 0)))) |
| 1265 | ;; of the keyword, symbol, or method name before them. | 1397 | (string-to-syntax "\\")))) |
| 1266 | ((concat | 1398 | ;; Regular expressions. Start with matching unescaped slash. |
| 1267 | ;; Special tokens that can't be followed by a division operator. | 1399 | ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)" |
| 1268 | "\\(^\\|[[=(,~?:;<>]" | 1400 | (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1))))) |
| 1269 | ;; Control flow keywords and operators following bol or whitespace. | 1401 | (when (or |
| 1270 | "\\|\\(?:^\\|\\s \\)" | 1402 | ;; Beginning of a regexp. |
| 1271 | (regexp-opt '("if" "elsif" "unless" "while" "until" "when" "and" | 1403 | (and (null (nth 8 state)) |
| 1272 | "or" "not" "&&" "||")) | 1404 | (save-excursion |
| 1273 | ;; Method name from the list. | 1405 | (forward-char -1) |
| 1274 | "\\|\\_<" | 1406 | (looking-back ruby-syntax-before-regexp-re |
| 1275 | (regexp-opt ruby-syntax-methods-before-regexp) | 1407 | (point-at-bol)))) |
| 1276 | "\\)\\s *" | 1408 | ;; End of regexp. We don't match the whole |
| 1277 | ;; The regular expression itself. | 1409 | ;; regexp at once because it can have |
| 1278 | "\\(/\\)[^/\n\\\\]*\\(?:\\\\.[^/\n\\\\]*\\)*\\(/\\)") | 1410 | ;; string interpolation inside, or span |
| 1279 | (3 (unless (nth 3 (syntax-ppss (match-beginning 2))) | 1411 | ;; several lines. |
| 1280 | (put-text-property (match-beginning 2) (match-end 2) | 1412 | (eq ?/ (nth 3 state))) |
| 1281 | 'syntax-table (string-to-syntax "\"/")) | 1413 | (string-to-syntax "\"/"))))) |
| 1282 | (string-to-syntax "\"/")))) | 1414 | ;; Expression expansions in strings. We're handling them |
| 1283 | ("^=en\\(d\\)\\_>" (1 "!")) | 1415 | ;; here, so that the regexp rule never matches inside them. |
| 1284 | ("^\\(=\\)begin\\_>" (1 "!")) | 1416 | (ruby-expression-expansion-re |
| 1285 | ;; Handle here documents. | 1417 | (0 (ignore (ruby-syntax-propertize-expansion)))) |
| 1286 | ((concat ruby-here-doc-beg-re ".*\\(\n\\)") | 1418 | ("^=en\\(d\\)\\_>" (1 "!")) |
| 1287 | (7 (unless (ruby-singleton-class-p (match-beginning 0)) | 1419 | ("^\\(=\\)begin\\_>" (1 "!")) |
| 1288 | (put-text-property (match-beginning 7) (match-end 7) | 1420 | ;; Handle here documents. |
| 1289 | 'syntax-table (string-to-syntax "\"")) | 1421 | ((concat ruby-here-doc-beg-re ".*\\(\n\\)") |
| 1290 | (ruby-syntax-propertize-heredoc end)))) | 1422 | (7 (unless (ruby-singleton-class-p (match-beginning 0)) |
| 1291 | ;; Handle percent literals: %w(), %q{}, etc. | 1423 | (put-text-property (match-beginning 7) (match-end 7) |
| 1292 | ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re) | 1424 | 'syntax-table (string-to-syntax "\"")) |
| 1293 | (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) | 1425 | (ruby-syntax-propertize-heredoc end)))) |
| 1294 | (point) end) | 1426 | ;; Handle percent literals: %w(), %q{}, etc. |
| 1295 | (ruby-syntax-propertize-expansions start end)) | 1427 | ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re) |
| 1428 | (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) | ||
| 1429 | (point) end))) | ||
| 1296 | 1430 | ||
| 1297 | (defun ruby-syntax-propertize-heredoc (limit) | 1431 | (defun ruby-syntax-propertize-heredoc (limit) |
| 1298 | (let ((ppss (syntax-ppss)) | 1432 | (let ((ppss (syntax-ppss)) |
| @@ -1305,7 +1439,7 @@ It will be properly highlighted even when the call omits parens.")) | |||
| 1305 | (line-end-position) t) | 1439 | (line-end-position) t) |
| 1306 | (unless (ruby-singleton-class-p (match-beginning 0)) | 1440 | (unless (ruby-singleton-class-p (match-beginning 0)) |
| 1307 | (push (concat (ruby-here-doc-end-match) "\n") res)))) | 1441 | (push (concat (ruby-here-doc-end-match) "\n") res)))) |
| 1308 | (let ((start (point))) | 1442 | (save-excursion |
| 1309 | ;; With multiple openers on the same line, we don't know in which | 1443 | ;; With multiple openers on the same line, we don't know in which |
| 1310 | ;; part `start' is, so we have to go back to the beginning. | 1444 | ;; part `start' is, so we have to go back to the beginning. |
| 1311 | (when (cdr res) | 1445 | (when (cdr res) |
| @@ -1315,9 +1449,9 @@ It will be properly highlighted even when the call omits parens.")) | |||
| 1315 | (if (null res) | 1449 | (if (null res) |
| 1316 | (put-text-property (1- (point)) (point) | 1450 | (put-text-property (1- (point)) (point) |
| 1317 | 'syntax-table (string-to-syntax "\"")))) | 1451 | 'syntax-table (string-to-syntax "\"")))) |
| 1318 | ;; Make extra sure we don't move back, lest we could fall into an | 1452 | ;; End up at bol following the heredoc openers. |
| 1319 | ;; inf-loop. | 1453 | ;; Propertize expression expansions from this point forward. |
| 1320 | (if (< (point) start) (goto-char start)))))) | 1454 | )))) |
| 1321 | 1455 | ||
| 1322 | (defun ruby-syntax-enclosing-percent-literal (limit) | 1456 | (defun ruby-syntax-enclosing-percent-literal (limit) |
| 1323 | (let ((state (syntax-ppss)) | 1457 | (let ((state (syntax-ppss)) |
| @@ -1338,44 +1472,59 @@ It will be properly highlighted even when the call omits parens.")) | |||
| 1338 | (cl (or (cdr (aref (syntax-table) op)) | 1472 | (cl (or (cdr (aref (syntax-table) op)) |
| 1339 | (cdr (assoc op '((?< . ?>)))))) | 1473 | (cdr (assoc op '((?< . ?>)))))) |
| 1340 | parse-sexp-lookup-properties) | 1474 | parse-sexp-lookup-properties) |
| 1341 | (condition-case nil | 1475 | (save-excursion |
| 1342 | (progn | 1476 | (condition-case nil |
| 1343 | (if cl ; Paired delimiters. | 1477 | (progn |
| 1344 | ;; Delimiter pairs of the same kind can be nested | 1478 | (if cl ; Paired delimiters. |
| 1345 | ;; inside the literal, as long as they are balanced. | 1479 | ;; Delimiter pairs of the same kind can be nested |
| 1346 | ;; Create syntax table that ignores other characters. | 1480 | ;; inside the literal, as long as they are balanced. |
| 1347 | (with-syntax-table (make-char-table 'syntax-table nil) | 1481 | ;; Create syntax table that ignores other characters. |
| 1348 | (modify-syntax-entry op (concat "(" (char-to-string cl))) | 1482 | (with-syntax-table (make-char-table 'syntax-table nil) |
| 1349 | (modify-syntax-entry cl (concat ")" ops)) | 1483 | (modify-syntax-entry op (concat "(" (char-to-string cl))) |
| 1350 | (modify-syntax-entry ?\\ "\\") | 1484 | (modify-syntax-entry cl (concat ")" ops)) |
| 1351 | (save-restriction | 1485 | (modify-syntax-entry ?\\ "\\") |
| 1352 | (narrow-to-region (point) limit) | 1486 | (save-restriction |
| 1353 | (forward-list))) ; skip to the paired character | 1487 | (narrow-to-region (point) limit) |
| 1354 | ;; Single character delimiter. | 1488 | (forward-list))) ; skip to the paired character |
| 1355 | (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*" | 1489 | ;; Single character delimiter. |
| 1356 | (regexp-quote ops)) limit nil)) | 1490 | (re-search-forward (concat "[^\\]\\(?:\\\\\\\\\\)*" |
| 1357 | ;; Found the closing delimiter. | 1491 | (regexp-quote ops)) limit nil)) |
| 1358 | (put-text-property (1- (point)) (point) 'syntax-table | 1492 | ;; Found the closing delimiter. |
| 1359 | (string-to-syntax "|"))) | 1493 | (put-text-property (1- (point)) (point) 'syntax-table |
| 1360 | ;; Unclosed literal, leave the following text unpropertized. | 1494 | (string-to-syntax "|"))) |
| 1361 | ((scan-error search-failed) (goto-char limit)))))) | 1495 | ;; Unclosed literal, do nothing. |
| 1496 | ((scan-error search-failed))))))) | ||
| 1497 | |||
| 1498 | (defun ruby-syntax-propertize-expansion () | ||
| 1499 | ;; Save the match data to a text property, for font-locking later. | ||
| 1500 | ;; Set the syntax of all double quotes and backticks to punctuation. | ||
| 1501 | (let* ((beg (match-beginning 2)) | ||
| 1502 | (end (match-end 2)) | ||
| 1503 | (state (and beg (save-excursion (syntax-ppss beg))))) | ||
| 1504 | (when (ruby-syntax-expansion-allowed-p state) | ||
| 1505 | (put-text-property beg (1+ beg) 'ruby-expansion-match-data | ||
| 1506 | (match-data)) | ||
| 1507 | (goto-char beg) | ||
| 1508 | (while (re-search-forward "[\"`]" end 'move) | ||
| 1509 | (put-text-property (match-beginning 0) (match-end 0) | ||
| 1510 | 'syntax-table (string-to-syntax ".")))))) | ||
| 1511 | |||
| 1512 | (defun ruby-syntax-expansion-allowed-p (parse-state) | ||
| 1513 | "Return non-nil if expression expansion is allowed." | ||
| 1514 | (let ((term (nth 3 parse-state))) | ||
| 1515 | (cond | ||
| 1516 | ((memq term '(?\" ?` ?\n ?/))) | ||
| 1517 | ((eq term t) | ||
| 1518 | (save-match-data | ||
| 1519 | (save-excursion | ||
| 1520 | (goto-char (nth 8 parse-state)) | ||
| 1521 | (looking-at "%\\(?:[QWrx]\\|\\W\\)"))))))) | ||
| 1362 | 1522 | ||
| 1363 | (defun ruby-syntax-propertize-expansions (start end) | 1523 | (defun ruby-syntax-propertize-expansions (start end) |
| 1364 | (remove-text-properties start end '(ruby-expansion-match-data)) | 1524 | (save-excursion |
| 1365 | (goto-char start) | 1525 | (goto-char start) |
| 1366 | ;; Find all expression expansions and | 1526 | (while (re-search-forward ruby-expression-expansion-re end 'move) |
| 1367 | ;; - save the match data to a text property, for font-locking later, | 1527 | (ruby-syntax-propertize-expansion)))) |
| 1368 | ;; - set the syntax of all double quotes and backticks to punctuation. | ||
| 1369 | (while (re-search-forward ruby-expression-expansion-re end 'move) | ||
| 1370 | (let ((beg (match-beginning 2)) | ||
| 1371 | (end (match-end 2))) | ||
| 1372 | (when (and beg (save-excursion (nth 3 (syntax-ppss beg)))) | ||
| 1373 | (put-text-property beg (1+ beg) 'ruby-expansion-match-data | ||
| 1374 | (match-data)) | ||
| 1375 | (goto-char beg) | ||
| 1376 | (while (re-search-forward "[\"`]" end 'move) | ||
| 1377 | (put-text-property (match-beginning 0) (match-end 0) | ||
| 1378 | 'syntax-table (string-to-syntax "."))))))) | ||
| 1379 | ) | 1528 | ) |
| 1380 | 1529 | ||
| 1381 | ;; For Emacsen where syntax-propertize-rules is not (yet) available, | 1530 | ;; For Emacsen where syntax-propertize-rules is not (yet) available, |
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 8f1954402e5..07e9bb85c4e 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el | |||
| @@ -335,11 +335,11 @@ shell it really is." | |||
| 335 | . ((nil | 335 | . ((nil |
| 336 | ;; function FOO | 336 | ;; function FOO |
| 337 | ;; function FOO() | 337 | ;; function FOO() |
| 338 | "^\\s-*function\\s-+\\\([[:alpha:]_][[:alnum:]_]+\\)\\s-*\\(?:()\\)?" | 338 | "^\\s-*function\\s-+\\\([[:alpha:]_][[:alnum:]_]*\\)\\s-*\\(?:()\\)?" |
| 339 | 1) | 339 | 1) |
| 340 | ;; FOO() | 340 | ;; FOO() |
| 341 | (nil | 341 | (nil |
| 342 | "^\\s-*\\([[:alpha:]_][[:alnum:]_]+\\)\\s-*()" | 342 | "^\\s-*\\([[:alpha:]_][[:alnum:]_]*\\)\\s-*()" |
| 343 | 1) | 343 | 1) |
| 344 | ))) | 344 | ))) |
| 345 | "Alist of regular expressions for recognizing shell function definitions. | 345 | "Alist of regular expressions for recognizing shell function definitions. |
| @@ -353,6 +353,28 @@ See `sh-feature' and `imenu-generic-expression'." | |||
| 353 | :group 'sh-script | 353 | :group 'sh-script |
| 354 | :version "20.4") | 354 | :version "20.4") |
| 355 | 355 | ||
| 356 | (defun sh-current-defun-name () | ||
| 357 | "Find the name of function or variable at point. | ||
| 358 | For use in `add-log-current-defun-function'." | ||
| 359 | (save-excursion | ||
| 360 | (end-of-line) | ||
| 361 | (when (re-search-backward | ||
| 362 | (concat "\\(?:" | ||
| 363 | ;; function FOO | ||
| 364 | ;; function FOO() | ||
| 365 | "^\\s-*function\\s-+\\\([[:alpha:]_][[:alnum:]_]*\\)\\s-*\\(?:()\\)?" | ||
| 366 | "\\)\\|\\(?:" | ||
| 367 | ;; FOO() | ||
| 368 | "^\\s-*\\([[:alpha:]_][[:alnum:]_]*\\)\\s-*()" | ||
| 369 | "\\)\\|\\(?:" | ||
| 370 | ;; FOO= | ||
| 371 | "^\\([[:alpha:]_][[:alnum:]_]*\\)=" | ||
| 372 | "\\)") | ||
| 373 | nil t) | ||
| 374 | (or (match-string-no-properties 1) | ||
| 375 | (match-string-no-properties 2) | ||
| 376 | (match-string-no-properties 3))))) | ||
| 377 | |||
| 356 | (defvar sh-shell-variables nil | 378 | (defvar sh-shell-variables nil |
| 357 | "Alist of shell variable names that should be included in completion. | 379 | "Alist of shell variable names that should be included in completion. |
| 358 | These are used for completion in addition to all the variables named | 380 | These are used for completion in addition to all the variables named |
| @@ -1533,6 +1555,7 @@ with your script for an edit-interpret-debug cycle." | |||
| 1533 | (setq-local skeleton-newline-indent-rigidly t) | 1555 | (setq-local skeleton-newline-indent-rigidly t) |
| 1534 | (setq-local defun-prompt-regexp | 1556 | (setq-local defun-prompt-regexp |
| 1535 | (concat "^\\(function[ \t]\\|[[:alnum:]]+[ \t]+()[ \t]+\\)")) | 1557 | (concat "^\\(function[ \t]\\|[[:alnum:]]+[ \t]+()[ \t]+\\)")) |
| 1558 | (setq-local add-log-current-defun-function #'sh-current-defun-name) | ||
| 1536 | ;; Parse or insert magic number for exec, and set all variables depending | 1559 | ;; Parse or insert magic number for exec, and set all variables depending |
| 1537 | ;; on the shell thus determined. | 1560 | ;; on the shell thus determined. |
| 1538 | (sh-set-shell | 1561 | (sh-set-shell |
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 3cf6757d5ec..940afc3d5f4 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el | |||
| @@ -285,36 +285,49 @@ file. Since that is a plaintext file, this could be dangerous." | |||
| 285 | 285 | ||
| 286 | (define-widget 'sql-login-params 'lazy | 286 | (define-widget 'sql-login-params 'lazy |
| 287 | "Widget definition of the login parameters list" | 287 | "Widget definition of the login parameters list" |
| 288 | ;; FIXME: does not implement :default property for the user, | ||
| 289 | ;; database and server options. Anybody have some guidance on how to | ||
| 290 | ;; do this. | ||
| 291 | :tag "Login Parameters" | 288 | :tag "Login Parameters" |
| 292 | :type '(repeat (choice | 289 | :type '(set :tag "Login Parameters" |
| 293 | (const user) | 290 | (choice :tag "user" |
| 294 | (const password) | 291 | :value user |
| 295 | (choice :tag "server" | 292 | (const user) |
| 296 | (const server) | 293 | (list :tag "Specify a default" |
| 297 | (list :tag "file" | 294 | (const user) |
| 298 | (const :format "" server) | 295 | (list :tag "Default" |
| 299 | (const :format "" :file) | 296 | :inline t (const :default) string))) |
| 300 | regexp) | 297 | (const password) |
| 301 | (list :tag "completion" | 298 | (choice :tag "server" |
| 302 | (const :format "" server) | 299 | :value server |
| 300 | (const server) | ||
| 301 | (list :tag "Specify a default" | ||
| 302 | (const server) | ||
| 303 | (list :tag "Default" | ||
| 304 | :inline t (const :default) string)) | ||
| 305 | (list :tag "file" | ||
| 306 | (const :format "" server) | ||
| 307 | (const :format "" :file) | ||
| 308 | regexp) | ||
| 309 | (list :tag "completion" | ||
| 310 | (const :format "" server) | ||
| 311 | (const :format "" :completion) | ||
| 312 | (restricted-sexp | ||
| 313 | :match-alternatives (listp stringp)))) | ||
| 314 | (choice :tag "database" | ||
| 315 | :value database | ||
| 316 | (const database) | ||
| 317 | (list :tag "Specify a default" | ||
| 318 | (const database) | ||
| 319 | (list :tag "Default" | ||
| 320 | :inline t (const :default) string)) | ||
| 321 | (list :tag "file" | ||
| 322 | (const :format "" database) | ||
| 323 | (const :format "" :file) | ||
| 324 | regexp) | ||
| 325 | (list :tag "completion" | ||
| 326 | (const :format "" database) | ||
| 303 | (const :format "" :completion) | 327 | (const :format "" :completion) |
| 304 | (restricted-sexp | 328 | (restricted-sexp |
| 305 | :match-alternatives (listp stringp)))) | 329 | :match-alternatives (listp stringp)))) |
| 306 | (choice :tag "database" | 330 | (const port))) |
| 307 | (const database) | ||
| 308 | (list :tag "file" | ||
| 309 | (const :format "" database) | ||
| 310 | (const :format "" :file) | ||
| 311 | regexp) | ||
| 312 | (list :tag "completion" | ||
| 313 | (const :format "" database) | ||
| 314 | (const :format "" :completion) | ||
| 315 | (restricted-sexp | ||
| 316 | :match-alternatives (listp stringp)))) | ||
| 317 | (const port)))) | ||
| 318 | 331 | ||
| 319 | ;; SQL Product support | 332 | ;; SQL Product support |
| 320 | 333 | ||
diff --git a/lisp/progmodes/subword.el b/lisp/progmodes/subword.el index 80e632c6ef6..a75bdff27bd 100644 --- a/lisp/progmodes/subword.el +++ b/lisp/progmodes/subword.el | |||
| @@ -26,7 +26,8 @@ | |||
| 26 | 26 | ||
| 27 | ;; This package provides `subword' oriented commands and a minor mode | 27 | ;; This package provides `subword' oriented commands and a minor mode |
| 28 | ;; (`subword-mode') that substitutes the common word handling | 28 | ;; (`subword-mode') that substitutes the common word handling |
| 29 | ;; functions with them. | 29 | ;; functions with them. It also provides the `superword-mode' minor |
| 30 | ;; mode that treats symbols as words, the opposite of `subword-mode'. | ||
| 30 | 31 | ||
| 31 | ;; In spite of GNU Coding Standards, it is popular to name a symbol by | 32 | ;; In spite of GNU Coding Standards, it is popular to name a symbol by |
| 32 | ;; mixing uppercase and lowercase letters, e.g. "GtkWidget", | 33 | ;; mixing uppercase and lowercase letters, e.g. "GtkWidget", |
| @@ -43,12 +44,13 @@ | |||
| 43 | 44 | ||
| 44 | ;; The subword oriented commands defined in this package recognize | 45 | ;; The subword oriented commands defined in this package recognize |
| 45 | ;; subwords in a nomenclature to move between them and to edit them as | 46 | ;; subwords in a nomenclature to move between them and to edit them as |
| 46 | ;; words. | 47 | ;; words. You also get a mode to treat symbols as words instead, |
| 48 | ;; called `superword-mode' (the opposite of `subword-mode'). | ||
| 47 | 49 | ||
| 48 | ;; In the minor mode, all common key bindings for word oriented | 50 | ;; In the minor mode, all common key bindings for word oriented |
| 49 | ;; commands are overridden by the subword oriented commands: | 51 | ;; commands are overridden by the subword oriented commands: |
| 50 | 52 | ||
| 51 | ;; Key Word oriented command Subword oriented command | 53 | ;; Key Word oriented command Subword oriented command (also superword) |
| 52 | ;; ============================================================ | 54 | ;; ============================================================ |
| 53 | ;; M-f `forward-word' `subword-forward' | 55 | ;; M-f `forward-word' `subword-forward' |
| 54 | ;; M-b `backward-word' `subword-backward' | 56 | ;; M-b `backward-word' `subword-backward' |
| @@ -67,8 +69,13 @@ | |||
| 67 | ;; To make the mode turn on automatically, put the following code in | 69 | ;; To make the mode turn on automatically, put the following code in |
| 68 | ;; your .emacs: | 70 | ;; your .emacs: |
| 69 | ;; | 71 | ;; |
| 70 | ;; (add-hook 'c-mode-common-hook | 72 | ;; (add-hook 'c-mode-common-hook 'subword-mode) |
| 71 | ;; (lambda () (subword-mode 1))) | 73 | ;; |
| 74 | |||
| 75 | ;; To make the mode turn `superword-mode' on automatically for | ||
| 76 | ;; only some modes, put the following code in your .emacs: | ||
| 77 | ;; | ||
| 78 | ;; (add-hook 'c-mode-common-hook 'superword-mode) | ||
| 72 | ;; | 79 | ;; |
| 73 | 80 | ||
| 74 | ;; Acknowledgment: | 81 | ;; Acknowledgment: |
| @@ -98,7 +105,8 @@ | |||
| 98 | (let ((map (make-sparse-keymap))) | 105 | (let ((map (make-sparse-keymap))) |
| 99 | (dolist (cmd '(forward-word backward-word mark-word kill-word | 106 | (dolist (cmd '(forward-word backward-word mark-word kill-word |
| 100 | backward-kill-word transpose-words | 107 | backward-kill-word transpose-words |
| 101 | capitalize-word upcase-word downcase-word)) | 108 | capitalize-word upcase-word downcase-word |
| 109 | left-word right-word)) | ||
| 102 | (let ((othercmd (let ((name (symbol-name cmd))) | 110 | (let ((othercmd (let ((name (symbol-name cmd))) |
| 103 | (string-match "\\([[:alpha:]-]+\\)-word[s]?" name) | 111 | (string-match "\\([[:alpha:]-]+\\)-word[s]?" name) |
| 104 | (intern (concat "subword-" (match-string 1 name)))))) | 112 | (intern (concat "subword-" (match-string 1 name)))))) |
| @@ -133,21 +141,21 @@ subwords in a nomenclature to move between subwords and to edit them | |||
| 133 | as words. | 141 | as words. |
| 134 | 142 | ||
| 135 | \\{subword-mode-map}" | 143 | \\{subword-mode-map}" |
| 136 | nil | 144 | :lighter " ," |
| 137 | nil | 145 | (when subword-mode (superword-mode -1))) |
| 138 | subword-mode-map) | ||
| 139 | 146 | ||
| 140 | (define-obsolete-function-alias 'c-subword-mode 'subword-mode "23.2") | 147 | (define-obsolete-function-alias 'c-subword-mode 'subword-mode "23.2") |
| 141 | 148 | ||
| 142 | ;;;###autoload | 149 | ;;;###autoload |
| 143 | (define-global-minor-mode global-subword-mode subword-mode | 150 | (define-global-minor-mode global-subword-mode subword-mode |
| 144 | (lambda () (subword-mode 1))) | 151 | (lambda () (subword-mode 1)) |
| 152 | :group 'convenience) | ||
| 145 | 153 | ||
| 146 | (defun subword-forward (&optional arg) | 154 | (defun subword-forward (&optional arg) |
| 147 | "Do the same as `forward-word' but on subwords. | 155 | "Do the same as `forward-word' but on subwords. |
| 148 | See the command `subword-mode' for a description of subwords. | 156 | See the command `subword-mode' for a description of subwords. |
| 149 | Optional argument ARG is the same as for `forward-word'." | 157 | Optional argument ARG is the same as for `forward-word'." |
| 150 | (interactive "p") | 158 | (interactive "^p") |
| 151 | (unless arg (setq arg 1)) | 159 | (unless arg (setq arg 1)) |
| 152 | (cond | 160 | (cond |
| 153 | ((< 0 arg) | 161 | ((< 0 arg) |
| @@ -165,9 +173,23 @@ Optional argument ARG is the same as for `forward-word'." | |||
| 165 | "Do the same as `backward-word' but on subwords. | 173 | "Do the same as `backward-word' but on subwords. |
| 166 | See the command `subword-mode' for a description of subwords. | 174 | See the command `subword-mode' for a description of subwords. |
| 167 | Optional argument ARG is the same as for `backward-word'." | 175 | Optional argument ARG is the same as for `backward-word'." |
| 168 | (interactive "p") | 176 | (interactive "^p") |
| 169 | (subword-forward (- (or arg 1)))) | 177 | (subword-forward (- (or arg 1)))) |
| 170 | 178 | ||
| 179 | (defun subword-right (&optional arg) | ||
| 180 | "Do the same as `right-word' but on subwords." | ||
| 181 | (interactive "^p") | ||
| 182 | (if (eq (current-bidi-paragraph-direction) 'left-to-right) | ||
| 183 | (subword-forward arg) | ||
| 184 | (subword-backward arg))) | ||
| 185 | |||
| 186 | (defun subword-left (&optional arg) | ||
| 187 | "Do the same as `left-word' but on subwords." | ||
| 188 | (interactive "^p") | ||
| 189 | (if (eq (current-bidi-paragraph-direction) 'left-to-right) | ||
| 190 | (subword-backward arg) | ||
| 191 | (subword-forward arg))) | ||
| 192 | |||
| 171 | (defun subword-mark (arg) | 193 | (defun subword-mark (arg) |
| 172 | "Do the same as `mark-word' but on subwords. | 194 | "Do the same as `mark-word' but on subwords. |
| 173 | See the command `subword-mode' for a description of subwords. | 195 | See the command `subword-mode' for a description of subwords. |
| @@ -254,41 +276,74 @@ Optional argument ARG is the same as for `capitalize-word'." | |||
| 254 | (unless advance | 276 | (unless advance |
| 255 | (goto-char start)))) | 277 | (goto-char start)))) |
| 256 | 278 | ||
| 279 | |||
| 280 | |||
| 281 | (defvar superword-mode-map subword-mode-map | ||
| 282 | "Keymap used in `superword-mode' minor mode.") | ||
| 283 | |||
| 284 | ;;;###autoload | ||
| 285 | (define-minor-mode superword-mode | ||
| 286 | "Toggle superword movement and editing (Superword mode). | ||
| 287 | With a prefix argument ARG, enable Superword mode if ARG is | ||
| 288 | positive, and disable it otherwise. If called from Lisp, enable | ||
| 289 | the mode if ARG is omitted or nil. | ||
| 290 | |||
| 291 | Superword mode is a buffer-local minor mode. Enabling it remaps | ||
| 292 | word-based editing commands to superword-based commands that | ||
| 293 | treat symbols as words, e.g. \"this_is_a_symbol\". | ||
| 294 | |||
| 295 | The superword oriented commands activated in this minor mode | ||
| 296 | recognize symbols as superwords to move between superwords and to | ||
| 297 | edit them as words. | ||
| 298 | |||
| 299 | \\{superword-mode-map}" | ||
| 300 | :lighter " ²" | ||
| 301 | (when superword-mode (subword-mode -1))) | ||
| 302 | |||
| 303 | ;;;###autoload | ||
| 304 | (define-global-minor-mode global-superword-mode superword-mode | ||
| 305 | (lambda () (superword-mode 1)) | ||
| 306 | :group 'convenience) | ||
| 257 | 307 | ||
| 258 | 308 | ||
| 259 | ;; | 309 | ;; |
| 260 | ;; Internal functions | 310 | ;; Internal functions |
| 261 | ;; | 311 | ;; |
| 262 | (defun subword-forward-internal () | 312 | (defun subword-forward-internal () |
| 263 | (if (and | 313 | (if superword-mode |
| 264 | (save-excursion | 314 | (forward-symbol 1) |
| 265 | (let ((case-fold-search nil)) | 315 | (if (and |
| 266 | (re-search-forward subword-forward-regexp nil t))) | 316 | (save-excursion |
| 267 | (> (match-end 0) (point))) | 317 | (let ((case-fold-search nil)) |
| 268 | (goto-char | 318 | (re-search-forward subword-forward-regexp nil t))) |
| 269 | (cond | 319 | (> (match-end 0) (point))) |
| 270 | ((< 1 (- (match-end 2) (match-beginning 2))) | 320 | (goto-char |
| 271 | (1- (match-end 2))) | 321 | (cond |
| 272 | (t | 322 | ((< 1 (- (match-end 2) (match-beginning 2))) |
| 273 | (match-end 0)))) | 323 | (1- (match-end 2))) |
| 274 | (forward-word 1))) | 324 | (t |
| 275 | 325 | (match-end 0)))) | |
| 326 | (forward-word 1)))) | ||
| 276 | 327 | ||
| 277 | (defun subword-backward-internal () | 328 | (defun subword-backward-internal () |
| 278 | (if (save-excursion | 329 | (if superword-mode |
| 279 | (let ((case-fold-search nil)) | 330 | (forward-symbol -1) |
| 280 | (re-search-backward subword-backward-regexp nil t))) | 331 | (if (save-excursion |
| 281 | (goto-char | 332 | (let ((case-fold-search nil)) |
| 282 | (cond | 333 | (re-search-backward subword-backward-regexp nil t))) |
| 283 | ((and (match-end 3) | 334 | (goto-char |
| 284 | (< 1 (- (match-end 3) (match-beginning 3))) | 335 | (cond |
| 285 | (not (eq (point) (match-end 3)))) | 336 | ((and (match-end 3) |
| 286 | (1- (match-end 3))) | 337 | (< 1 (- (match-end 3) (match-beginning 3))) |
| 287 | (t | 338 | (not (eq (point) (match-end 3)))) |
| 288 | (1+ (match-beginning 0))))) | 339 | (1- (match-end 3))) |
| 289 | (backward-word 1))) | 340 | (t |
| 341 | (1+ (match-beginning 0))))) | ||
| 342 | (backward-word 1)))) | ||
| 290 | 343 | ||
| 291 | 344 | ||
| 345 | |||
| 292 | (provide 'subword) | 346 | (provide 'subword) |
| 347 | (provide 'superword) | ||
| 293 | 348 | ||
| 294 | ;;; subword.el ends here | 349 | ;;; subword.el ends here |
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el index 9169a433015..3e91aeba9a1 100644 --- a/lisp/progmodes/tcl.el +++ b/lisp/progmodes/tcl.el | |||
| @@ -266,7 +266,7 @@ quoted for Tcl." | |||
| 266 | ;; Maybe someone has a better set? | 266 | ;; Maybe someone has a better set? |
| 267 | (let ((map (make-sparse-keymap))) | 267 | (let ((map (make-sparse-keymap))) |
| 268 | ;; Will inherit from `comint-mode-map' thanks to define-derived-mode. | 268 | ;; Will inherit from `comint-mode-map' thanks to define-derived-mode. |
| 269 | (define-key map "\t" 'comint-dynamic-complete) | 269 | (define-key map "\t" 'completion-at-point) |
| 270 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) | 270 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) |
| 271 | (define-key map "\177" 'backward-delete-char-untabify) | 271 | (define-key map "\177" 'backward-delete-char-untabify) |
| 272 | (define-key map "\M-\C-x" 'tcl-eval-defun) | 272 | (define-key map "\M-\C-x" 'tcl-eval-defun) |
diff --git a/lisp/progmodes/vera-mode.el b/lisp/progmodes/vera-mode.el index 7b59faca261..443472192be 100644 --- a/lisp/progmodes/vera-mode.el +++ b/lisp/progmodes/vera-mode.el | |||
| @@ -101,6 +101,8 @@ select and move operations. All parts of an identifier separated by underscore | |||
| 101 | are treated as single words otherwise." | 101 | are treated as single words otherwise." |
| 102 | :type 'boolean | 102 | :type 'boolean |
| 103 | :group 'vera) | 103 | :group 'vera) |
| 104 | (make-obsolete-variable 'vera-underscore-is-part-of-word | ||
| 105 | 'superword-mode "24.4") | ||
| 104 | 106 | ||
| 105 | (defcustom vera-intelligent-tab t | 107 | (defcustom vera-intelligent-tab t |
| 106 | "Non-nil means `TAB' does indentation, word completion and tab insertion. | 108 | "Non-nil means `TAB' does indentation, word completion and tab insertion. |
| @@ -1353,6 +1355,11 @@ If `vera-intelligent-tab' is nil, always indent line." | |||
| 1353 | (defvar vera-expand-upper-case nil) | 1355 | (defvar vera-expand-upper-case nil) |
| 1354 | 1356 | ||
| 1355 | (eval-when-compile (require 'hippie-exp)) | 1357 | (eval-when-compile (require 'hippie-exp)) |
| 1358 | (declare-function he-init-string "hippie-exp" (beg end)) | ||
| 1359 | (declare-function he-dabbrev-beg "hippie-exp" ()) | ||
| 1360 | (declare-function he-string-member "hippie-exp" (str lst &optional trans-case)) | ||
| 1361 | (declare-function he-reset-string "hippie-exp" ()) | ||
| 1362 | (declare-function he-substitute-string "hippie-exp" (str &optional trans-case)) | ||
| 1356 | 1363 | ||
| 1357 | (defun vera-try-expand-abbrev (old) | 1364 | (defun vera-try-expand-abbrev (old) |
| 1358 | "Try expanding abbreviations from `vera-abbrev-list'." | 1365 | "Try expanding abbreviations from `vera-abbrev-list'." |
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el index 5571a905f85..ed911fcbba2 100644 --- a/lisp/progmodes/verilog-mode.el +++ b/lisp/progmodes/verilog-mode.el | |||
| @@ -123,9 +123,9 @@ | |||
| 123 | ;;; Code: | 123 | ;;; Code: |
| 124 | 124 | ||
| 125 | ;; This variable will always hold the version number of the mode | 125 | ;; This variable will always hold the version number of the mode |
| 126 | (defconst verilog-mode-version (substring "$$Revision: 820 $$" 12 -3) | 126 | (defconst verilog-mode-version (substring "$$Revision: 840 $$" 12 -3) |
| 127 | "Version of this Verilog mode.") | 127 | "Version of this Verilog mode.") |
| 128 | (defconst verilog-mode-release-date (substring "$$Date: 2012-09-17 20:43:10 -0400 (Mon, 17 Sep 2012) $$" 8 -3) | 128 | (defconst verilog-mode-release-date (substring "$$Date: 2013-01-03 05:29:05 -0800 (Thu, 03 Jan 2013) $$" 8 -3) |
| 129 | "Release date of this Verilog mode.") | 129 | "Release date of this Verilog mode.") |
| 130 | (defconst verilog-mode-release-emacs t | 130 | (defconst verilog-mode-release-emacs t |
| 131 | "If non-nil, this version of Verilog mode was released with Emacs itself.") | 131 | "If non-nil, this version of Verilog mode was released with Emacs itself.") |
| @@ -501,7 +501,7 @@ entry \"Fontify Buffer\"). XEmacs: turn off and on font locking." | |||
| 501 | "Type of statements to lineup across multiple lines. | 501 | "Type of statements to lineup across multiple lines. |
| 502 | If 'all' is selected, then all line ups described below are done. | 502 | If 'all' is selected, then all line ups described below are done. |
| 503 | 503 | ||
| 504 | If 'declaration', then just declarations are lined up with any | 504 | If 'declarations', then just declarations are lined up with any |
| 505 | preceding declarations, taking into account widths and the like, | 505 | preceding declarations, taking into account widths and the like, |
| 506 | so or example the code: | 506 | so or example the code: |
| 507 | reg [31:0] a; | 507 | reg [31:0] a; |
| @@ -964,7 +964,7 @@ See also `verilog-library-flags', `verilog-library-directories'." | |||
| 964 | This is used for AUTORESET and AUTOTIEOFF. For proper behavior, | 964 | This is used for AUTORESET and AUTOTIEOFF. For proper behavior, |
| 965 | you will probably also need `verilog-auto-reset-widths' set." | 965 | you will probably also need `verilog-auto-reset-widths' set." |
| 966 | :group 'verilog-mode-auto | 966 | :group 'verilog-mode-auto |
| 967 | :type 'string) | 967 | :type '(choice (const nil) regexp)) |
| 968 | (put 'verilog-active-low-regexp 'safe-local-variable 'stringp) | 968 | (put 'verilog-active-low-regexp 'safe-local-variable 'stringp) |
| 969 | 969 | ||
| 970 | (defcustom verilog-auto-sense-include-inputs nil | 970 | (defcustom verilog-auto-sense-include-inputs nil |
| @@ -1129,37 +1129,37 @@ won't merge conflict." | |||
| 1129 | 1129 | ||
| 1130 | (defcustom verilog-auto-inst-interfaced-ports nil | 1130 | (defcustom verilog-auto-inst-interfaced-ports nil |
| 1131 | "Non-nil means include interfaced ports in AUTOINST expansions." | 1131 | "Non-nil means include interfaced ports in AUTOINST expansions." |
| 1132 | :version "24.3" ;; rev773, default change rev815 | ||
| 1132 | :group 'verilog-mode-auto | 1133 | :group 'verilog-mode-auto |
| 1133 | :type 'boolean | 1134 | :type 'boolean) |
| 1134 | :version "24.3") | ||
| 1135 | (put 'verilog-auto-inst-interfaced-ports 'safe-local-variable 'verilog-booleanp) | 1135 | (put 'verilog-auto-inst-interfaced-ports 'safe-local-variable 'verilog-booleanp) |
| 1136 | 1136 | ||
| 1137 | (defcustom verilog-auto-input-ignore-regexp nil | 1137 | (defcustom verilog-auto-input-ignore-regexp nil |
| 1138 | "If set, when creating AUTOINPUT list, ignore signals matching this regexp. | 1138 | "If set, when creating AUTOINPUT list, ignore signals matching this regexp. |
| 1139 | See the \\[verilog-faq] for examples on using this." | 1139 | See the \\[verilog-faq] for examples on using this." |
| 1140 | :group 'verilog-mode-auto | 1140 | :group 'verilog-mode-auto |
| 1141 | :type 'string) | 1141 | :type '(choice (const nil) regexp)) |
| 1142 | (put 'verilog-auto-input-ignore-regexp 'safe-local-variable 'stringp) | 1142 | (put 'verilog-auto-input-ignore-regexp 'safe-local-variable 'stringp) |
| 1143 | 1143 | ||
| 1144 | (defcustom verilog-auto-inout-ignore-regexp nil | 1144 | (defcustom verilog-auto-inout-ignore-regexp nil |
| 1145 | "If set, when creating AUTOINOUT list, ignore signals matching this regexp. | 1145 | "If set, when creating AUTOINOUT list, ignore signals matching this regexp. |
| 1146 | See the \\[verilog-faq] for examples on using this." | 1146 | See the \\[verilog-faq] for examples on using this." |
| 1147 | :group 'verilog-mode-auto | 1147 | :group 'verilog-mode-auto |
| 1148 | :type 'string) | 1148 | :type '(choice (const nil) regexp)) |
| 1149 | (put 'verilog-auto-inout-ignore-regexp 'safe-local-variable 'stringp) | 1149 | (put 'verilog-auto-inout-ignore-regexp 'safe-local-variable 'stringp) |
| 1150 | 1150 | ||
| 1151 | (defcustom verilog-auto-output-ignore-regexp nil | 1151 | (defcustom verilog-auto-output-ignore-regexp nil |
| 1152 | "If set, when creating AUTOOUTPUT list, ignore signals matching this regexp. | 1152 | "If set, when creating AUTOOUTPUT list, ignore signals matching this regexp. |
| 1153 | See the \\[verilog-faq] for examples on using this." | 1153 | See the \\[verilog-faq] for examples on using this." |
| 1154 | :group 'verilog-mode-auto | 1154 | :group 'verilog-mode-auto |
| 1155 | :type 'string) | 1155 | :type '(choice (const nil) regexp)) |
| 1156 | (put 'verilog-auto-output-ignore-regexp 'safe-local-variable 'stringp) | 1156 | (put 'verilog-auto-output-ignore-regexp 'safe-local-variable 'stringp) |
| 1157 | 1157 | ||
| 1158 | (defcustom verilog-auto-template-warn-unused nil | 1158 | (defcustom verilog-auto-template-warn-unused nil |
| 1159 | "Non-nil means report warning if an AUTO_TEMPLATE line is not used. | 1159 | "Non-nil means report warning if an AUTO_TEMPLATE line is not used. |
| 1160 | This feature is not supported before Emacs 21.1 or XEmacs 21.4." | 1160 | This feature is not supported before Emacs 21.1 or XEmacs 21.4." |
| 1161 | :version "24.3" ;;rev787 | ||
| 1161 | :group 'verilog-mode-auto | 1162 | :group 'verilog-mode-auto |
| 1162 | :version "24.3" | ||
| 1163 | :type 'boolean) | 1163 | :type 'boolean) |
| 1164 | (put 'verilog-auto-template-warn-unused 'safe-local-variable 'verilog-booleanp) | 1164 | (put 'verilog-auto-template-warn-unused 'safe-local-variable 'verilog-booleanp) |
| 1165 | 1165 | ||
| @@ -1176,21 +1176,21 @@ assignment, else the data type for variable creation." | |||
| 1176 | "If set, when creating AUTOTIEOFF list, ignore signals matching this regexp. | 1176 | "If set, when creating AUTOTIEOFF list, ignore signals matching this regexp. |
| 1177 | See the \\[verilog-faq] for examples on using this." | 1177 | See the \\[verilog-faq] for examples on using this." |
| 1178 | :group 'verilog-mode-auto | 1178 | :group 'verilog-mode-auto |
| 1179 | :type 'string) | 1179 | :type '(choice (const nil) regexp)) |
| 1180 | (put 'verilog-auto-tieoff-ignore-regexp 'safe-local-variable 'stringp) | 1180 | (put 'verilog-auto-tieoff-ignore-regexp 'safe-local-variable 'stringp) |
| 1181 | 1181 | ||
| 1182 | (defcustom verilog-auto-unused-ignore-regexp nil | 1182 | (defcustom verilog-auto-unused-ignore-regexp nil |
| 1183 | "If set, when creating AUTOUNUSED list, ignore signals matching this regexp. | 1183 | "If set, when creating AUTOUNUSED list, ignore signals matching this regexp. |
| 1184 | See the \\[verilog-faq] for examples on using this." | 1184 | See the \\[verilog-faq] for examples on using this." |
| 1185 | :group 'verilog-mode-auto | 1185 | :group 'verilog-mode-auto |
| 1186 | :type 'string) | 1186 | :type '(choice (const nil) regexp)) |
| 1187 | (put 'verilog-auto-unused-ignore-regexp 'safe-local-variable 'stringp) | 1187 | (put 'verilog-auto-unused-ignore-regexp 'safe-local-variable 'stringp) |
| 1188 | 1188 | ||
| 1189 | (defcustom verilog-typedef-regexp nil | 1189 | (defcustom verilog-typedef-regexp nil |
| 1190 | "If non-nil, regular expression that matches Verilog-2001 typedef names. | 1190 | "If non-nil, regular expression that matches Verilog-2001 typedef names. |
| 1191 | For example, \"_t$\" matches typedefs named with _t, as in the C language." | 1191 | For example, \"_t$\" matches typedefs named with _t, as in the C language." |
| 1192 | :group 'verilog-mode-auto | 1192 | :group 'verilog-mode-auto |
| 1193 | :type 'string) | 1193 | :type '(choice (const nil) regexp)) |
| 1194 | (put 'verilog-typedef-regexp 'safe-local-variable 'stringp) | 1194 | (put 'verilog-typedef-regexp 'safe-local-variable 'stringp) |
| 1195 | 1195 | ||
| 1196 | (defcustom verilog-mode-hook 'verilog-set-compile-command | 1196 | (defcustom verilog-mode-hook 'verilog-set-compile-command |
| @@ -1230,14 +1230,14 @@ For example, \"_t$\" matches typedefs named with _t, as in the C language." | |||
| 1230 | 1230 | ||
| 1231 | (defcustom verilog-before-save-font-hook nil | 1231 | (defcustom verilog-before-save-font-hook nil |
| 1232 | "Hook run before `verilog-save-font-mods' removes highlighting." | 1232 | "Hook run before `verilog-save-font-mods' removes highlighting." |
| 1233 | :version "24.3" ;;rev735 | ||
| 1233 | :group 'verilog-mode-auto | 1234 | :group 'verilog-mode-auto |
| 1234 | :version "24.3" | ||
| 1235 | :type 'hook) | 1235 | :type 'hook) |
| 1236 | 1236 | ||
| 1237 | (defcustom verilog-after-save-font-hook nil | 1237 | (defcustom verilog-after-save-font-hook nil |
| 1238 | "Hook run after `verilog-save-font-mods' restores highlighting." | 1238 | "Hook run after `verilog-save-font-mods' restores highlighting." |
| 1239 | :version "24.3" ;;rev735 | ||
| 1239 | :group 'verilog-mode-auto | 1240 | :group 'verilog-mode-auto |
| 1240 | :version "24.3" | ||
| 1241 | :type 'hook) | 1241 | :type 'hook) |
| 1242 | 1242 | ||
| 1243 | (defvar verilog-imenu-generic-expression | 1243 | (defvar verilog-imenu-generic-expression |
| @@ -2784,6 +2784,8 @@ find the errors." | |||
| 2784 | (modify-syntax-entry ?> "." table) | 2784 | (modify-syntax-entry ?> "." table) |
| 2785 | (modify-syntax-entry ?& "." table) | 2785 | (modify-syntax-entry ?& "." table) |
| 2786 | (modify-syntax-entry ?| "." table) | 2786 | (modify-syntax-entry ?| "." table) |
| 2787 | ;; FIXME: This goes against Emacs conventions. Use "_" syntax instead and | ||
| 2788 | ;; then use regexps with things like "\\_<...\\_>". | ||
| 2787 | (modify-syntax-entry ?` "w" table) | 2789 | (modify-syntax-entry ?` "w" table) |
| 2788 | (modify-syntax-entry ?_ "w" table) | 2790 | (modify-syntax-entry ?_ "w" table) |
| 2789 | (modify-syntax-entry ?\' "." table) | 2791 | (modify-syntax-entry ?\' "." table) |
| @@ -7771,9 +7773,12 @@ Tieoff value uses `verilog-active-low-regexp' and | |||
| 7771 | ;; Else presume verilog-auto-reset-widths is true | 7773 | ;; Else presume verilog-auto-reset-widths is true |
| 7772 | (t | 7774 | (t |
| 7773 | (let* ((width (verilog-sig-width sig))) | 7775 | (let* ((width (verilog-sig-width sig))) |
| 7774 | (if (string-match "^[0-9]+$" width) | 7776 | (cond ((not width) |
| 7775 | (concat width (if (verilog-sig-signed sig) "'sh0" "'h0")) | 7777 | "`0/*NOWIDTH*/") |
| 7776 | (concat "{" width "{1'b0}}"))))))) | 7778 | ((string-match "^[0-9]+$" width) |
| 7779 | (concat width (if (verilog-sig-signed sig) "'sh0" "'h0"))) | ||
| 7780 | (t | ||
| 7781 | (concat "{" width "{1'b0}}")))))))) | ||
| 7777 | 7782 | ||
| 7778 | ;; | 7783 | ;; |
| 7779 | ;; Dumping | 7784 | ;; Dumping |
| @@ -7954,6 +7959,7 @@ Return an array of [outputs inouts inputs wire reg assign const]." | |||
| 7954 | vec expect-signal keywd newsig rvalue enum io signed typedefed multidim | 7959 | vec expect-signal keywd newsig rvalue enum io signed typedefed multidim |
| 7955 | modport | 7960 | modport |
| 7956 | varstack tmp) | 7961 | varstack tmp) |
| 7962 | ;;(if dbg (setq dbg (concat dbg (format "\n\nverilog-read-decls START PT %s END %s\n" (point) end-mod-point)))) | ||
| 7957 | (save-excursion | 7963 | (save-excursion |
| 7958 | (verilog-beg-of-defun-quick) | 7964 | (verilog-beg-of-defun-quick) |
| 7959 | (setq sigs-const (verilog-read-auto-constants (point) end-mod-point)) | 7965 | (setq sigs-const (verilog-read-auto-constants (point) end-mod-point)) |
| @@ -8008,7 +8014,7 @@ Return an array of [outputs inouts inputs wire reg assign const]." | |||
| 8008 | (setq paren (1- paren)) | 8014 | (setq paren (1- paren)) |
| 8009 | (forward-char 1) | 8015 | (forward-char 1) |
| 8010 | (when (< paren sig-paren) | 8016 | (when (< paren sig-paren) |
| 8011 | (setq expect-signal nil))) ; ) that ends variables inside v2k arg list | 8017 | (setq expect-signal nil rvalue nil))) ; ) that ends variables inside v2k arg list |
| 8012 | ((looking-at "\\s-*\\(\\[[^]]+\\]\\)") | 8018 | ((looking-at "\\s-*\\(\\[[^]]+\\]\\)") |
| 8013 | (goto-char (match-end 0)) | 8019 | (goto-char (match-end 0)) |
| 8014 | (cond (newsig ; Memory, not just width. Patch last signal added's memory (nth 3) | 8020 | (cond (newsig ; Memory, not just width. Patch last signal added's memory (nth 3) |
| @@ -12456,12 +12462,20 @@ used on the right hand side of assignments. | |||
| 12456 | 12462 | ||
| 12457 | By default, AUTORESET will include the width of the signal in the | 12463 | By default, AUTORESET will include the width of the signal in the |
| 12458 | autos, SystemVerilog designs may want to change this. To control | 12464 | autos, SystemVerilog designs may want to change this. To control |
| 12459 | this behavior, see `verilog-auto-reset-widths'. | 12465 | this behavior, see `verilog-auto-reset-widths'. In some cases |
| 12466 | AUTORESET must use a '0 assignment and it will print NOWIDTH; use | ||
| 12467 | `verilog-auto-reset-widths' unbased to prevent this. | ||
| 12460 | 12468 | ||
| 12461 | AUTORESET ties signals to deasserted, which is presumed to be zero. | 12469 | AUTORESET ties signals to deasserted, which is presumed to be zero. |
| 12462 | Signals that match `verilog-active-low-regexp' will be deasserted by tying | 12470 | Signals that match `verilog-active-low-regexp' will be deasserted by tying |
| 12463 | them to a one. | 12471 | them to a one. |
| 12464 | 12472 | ||
| 12473 | AUTORESET may try to reset arrays or structures that cannot be | ||
| 12474 | reset by a simple assignment, resulting in compile errors. This | ||
| 12475 | is a feature to be taken as a hint that you need to reset these | ||
| 12476 | signals manually (or put them into a \"`ifdef NEVER signal<=`0; | ||
| 12477 | `endif\" so Verilog-Mode ignores them.) | ||
| 12478 | |||
| 12465 | An example: | 12479 | An example: |
| 12466 | 12480 | ||
| 12467 | always @(posedge clk or negedge reset_l) begin | 12481 | always @(posedge clk or negedge reset_l) begin |
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el index e3b421efbe1..0050a94513a 100644 --- a/lisp/progmodes/vhdl-mode.el +++ b/lisp/progmodes/vhdl-mode.el | |||
| @@ -13,10 +13,10 @@ | |||
| 13 | ;; filed in the Emacs bug reporting system against this file, a copy | 13 | ;; filed in the Emacs bug reporting system against this file, a copy |
| 14 | ;; of the bug report be sent to the maintainer's email address. | 14 | ;; of the bug report be sent to the maintainer's email address. |
| 15 | 15 | ||
| 16 | (defconst vhdl-version "3.33.28" | 16 | (defconst vhdl-version "3.34.2" |
| 17 | "VHDL Mode version number.") | 17 | "VHDL Mode version number.") |
| 18 | 18 | ||
| 19 | (defconst vhdl-time-stamp "2010-09-22" | 19 | (defconst vhdl-time-stamp "2012-11-21" |
| 20 | "VHDL Mode time stamp for last update.") | 20 | "VHDL Mode time stamp for last update.") |
| 21 | 21 | ||
| 22 | ;; This file is part of GNU Emacs. | 22 | ;; This file is part of GNU Emacs. |
| @@ -72,8 +72,7 @@ | |||
| 72 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 72 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 73 | ;; Emacs Versions | 73 | ;; Emacs Versions |
| 74 | 74 | ||
| 75 | ;; supported: GNU Emacs 20.X/21.X/22.X,23.X, XEmacs 20.X/21.X | 75 | ;; this updated version was only tested on: GNU Emacs 20.4 |
| 76 | ;; tested on: GNU Emacs 20.4/21.3/22.1,23.X, XEmacs 21.1 (marginally) | ||
| 77 | 76 | ||
| 78 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 77 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 79 | ;; Installation | 78 | ;; Installation |
| @@ -84,7 +83,7 @@ | |||
| 84 | ;; or into an arbitrary directory that is added to the load path by the | 83 | ;; or into an arbitrary directory that is added to the load path by the |
| 85 | ;; following line in your Emacs start-up file `.emacs': | 84 | ;; following line in your Emacs start-up file `.emacs': |
| 86 | 85 | ||
| 87 | ;; (setq load-path (cons (expand-file-name "<directory-name>") load-path)) | 86 | ;; (push (expand-file-name "<directory-name>") load-path) |
| 88 | 87 | ||
| 89 | ;; If you already have the compiled `vhdl-mode.elc' file, put it in the same | 88 | ;; If you already have the compiled `vhdl-mode.elc' file, put it in the same |
| 90 | ;; directory. Otherwise, byte-compile the source file: | 89 | ;; directory. Otherwise, byte-compile the source file: |
| @@ -96,7 +95,7 @@ | |||
| 96 | ;; (not required in Emacs 20 and higher): | 95 | ;; (not required in Emacs 20 and higher): |
| 97 | 96 | ||
| 98 | ;; (autoload 'vhdl-mode "vhdl-mode" "VHDL Mode" t) | 97 | ;; (autoload 'vhdl-mode "vhdl-mode" "VHDL Mode" t) |
| 99 | ;; (setq auto-mode-alist (cons '("\\.vhdl?\\'" . vhdl-mode) auto-mode-alist)) | 98 | ;; (push '("\\.vhdl?\\'" . vhdl-mode) auto-mode-alist) |
| 100 | 99 | ||
| 101 | ;; More detailed installation instructions are included in the official | 100 | ;; More detailed installation instructions are included in the official |
| 102 | ;; VHDL Mode distribution. | 101 | ;; VHDL Mode distribution. |
| @@ -130,6 +129,7 @@ | |||
| 130 | ;; Emacs 21+ handling | 129 | ;; Emacs 21+ handling |
| 131 | (defconst vhdl-emacs-21 (and (<= 21 emacs-major-version) (not (featurep 'xemacs))) | 130 | (defconst vhdl-emacs-21 (and (<= 21 emacs-major-version) (not (featurep 'xemacs))) |
| 132 | "Non-nil if GNU Emacs 21, 22, ... is used.") | 131 | "Non-nil if GNU Emacs 21, 22, ... is used.") |
| 132 | ;; Emacs 22+ handling | ||
| 133 | (defconst vhdl-emacs-22 (and (<= 22 emacs-major-version) (not (featurep 'xemacs))) | 133 | (defconst vhdl-emacs-22 (and (<= 22 emacs-major-version) (not (featurep 'xemacs))) |
| 134 | "Non-nil if GNU Emacs 22, ... is used.") | 134 | "Non-nil if GNU Emacs 22, ... is used.") |
| 135 | 135 | ||
| @@ -210,22 +210,25 @@ Overrides local variable `indent-tabs-mode'." | |||
| 210 | 210 | ||
| 211 | (defcustom vhdl-compiler-alist | 211 | (defcustom vhdl-compiler-alist |
| 212 | '( | 212 | '( |
| 213 | ;; 60: docal <= false; | ||
| 214 | ;; ^^^^^ | ||
| 215 | ;; [Error] Assignment error: variable is illegal target of signal assignment | ||
| 213 | ("ADVance MS" "vacom" "-work \\1" "make" "-f \\1" | 216 | ("ADVance MS" "vacom" "-work \\1" "make" "-f \\1" |
| 214 | nil "valib \\1; vamap \\2 \\1" "./" "work/" "Makefile" "adms" | 217 | nil "valib \\1; vamap \\2 \\1" "./" "work/" "Makefile" "adms" |
| 215 | ("\\s-\\([0-9]+\\):" 0 1 0) ("Compiling file \\(.+\\)" 1) | 218 | ("^\\s-+\\([0-9]+\\):\\s-+" nil 1 nil) ("Compiling file \\(.+\\)" 1) |
| 216 | ("ENTI/\\1.vif" "ARCH/\\1-\\2.vif" "CONF/\\1.vif" | 219 | ("ENTI/\\1.vif" "ARCH/\\1-\\2.vif" "CONF/\\1.vif" |
| 217 | "PACK/\\1.vif" "BODY/\\1.vif" upcase)) | 220 | "PACK/\\1.vif" "BODY/\\1.vif" upcase)) |
| 218 | ;; Aldec | 221 | ;; Aldec |
| 219 | ;; COMP96 ERROR COMP96_0078: "Unknown identifier "Addr_Bits"." "<filename>" 40 30 | 222 | ;; COMP96 ERROR COMP96_0018: "Identifier expected." "test.vhd" 66 3 |
| 220 | ("Aldec" "vcom" "-93 -work \\1" "make" "-f \\1" | 223 | ("Aldec" "vcom" "-work \\1" "make" "-f \\1" |
| 221 | nil "vlib \\1; vmap \\2 \\1" "./" "work/" "Makefile" "aldec" | 224 | nil "vlib \\1; vmap \\2 \\1" "./" "work/" "Makefile" "aldec" |
| 222 | (".+?[ \t]+\\(?:ERROR\\)[^:]+:.+?\\(?:.+\"\\(.+?\\)\"[ \t]+\\([0-9]+\\)\\)" 1 2 0) ("" 0) | 225 | (".* ERROR [^:]+: \".*\" \"\\([^ \\t\\n]+\\)\" \\([0-9]+\\) \\([0-9]+\\)" 1 2 3) ("" 0) |
| 223 | nil) | 226 | nil) |
| 224 | ;; Cadence Leapfrog: cv -file test.vhd | 227 | ;; Cadence Leapfrog: cv -file test.vhd |
| 225 | ;; duluth: *E,430 (test.vhd,13): identifier (POSITIV) is not declared | 228 | ;; duluth: *E,430 (test.vhd,13): identifier (POSITIV) is not declared |
| 226 | ("Cadence Leapfrog" "cv" "-work \\1 -file" "make" "-f \\1" | 229 | ("Cadence Leapfrog" "cv" "-work \\1 -file" "make" "-f \\1" |
| 227 | nil "mkdir \\1" "./" "work/" "Makefile" "leapfrog" | 230 | nil "mkdir \\1" "./" "work/" "Makefile" "leapfrog" |
| 228 | ("duluth: \\*E,[0-9]+ (\\(.+\\),\\([0-9]+\\)):" 1 2 0) ("" 0) | 231 | ("duluth: \\*E,[0-9]+ (\\([^ \\t\\n]+\\),\\([0-9]+\\)):" 1 2 nil) ("" 0) |
| 229 | ("\\1/entity" "\\2/\\1" "\\1/configuration" | 232 | ("\\1/entity" "\\2/\\1" "\\1/configuration" |
| 230 | "\\1/package" "\\1/body" downcase)) | 233 | "\\1/package" "\\1/body" downcase)) |
| 231 | ;; Cadence Affirma NC vhdl: ncvhdl test.vhd | 234 | ;; Cadence Affirma NC vhdl: ncvhdl test.vhd |
| @@ -233,21 +236,27 @@ Overrides local variable `indent-tabs-mode'." | |||
| 233 | ;; (PLL_400X_TOP) is not declared [10.3]. | 236 | ;; (PLL_400X_TOP) is not declared [10.3]. |
| 234 | ("Cadence NC" "ncvhdl" "-work \\1" "make" "-f \\1" | 237 | ("Cadence NC" "ncvhdl" "-work \\1" "make" "-f \\1" |
| 235 | nil "mkdir \\1" "./" "work/" "Makefile" "ncvhdl" | 238 | nil "mkdir \\1" "./" "work/" "Makefile" "ncvhdl" |
| 236 | ("ncvhdl_p: \\*E,\\w+ (\\(.+\\),\\([0-9]+\\)|\\([0-9]+\\)):" 1 2 3) ("" 0) | 239 | ("ncvhdl_p: \\*E,\\w+ (\\([^ \\t\\n]+\\),\\([0-9]+\\)|\\([0-9]+\\)):" 1 2 3) ("" 0) |
| 237 | ("\\1/entity/pc.db" "\\2/\\1/pc.db" "\\1/configuration/pc.db" | 240 | ("\\1/entity/pc.db" "\\2/\\1/pc.db" "\\1/configuration/pc.db" |
| 238 | "\\1/package/pc.db" "\\1/body/pc.db" downcase)) | 241 | "\\1/package/pc.db" "\\1/body/pc.db" downcase)) |
| 239 | ;; ghdl vhdl: ghdl test.vhd | 242 | ;; ghdl vhdl: ghdl test.vhd |
| 240 | ("GHDL" "ghdl" "-i --workdir=\\1 --ieee=synopsys -fexplicit " "make" "-f \\1" | 243 | ("GHDL" "ghdl" "-i --workdir=\\1 --ieee=synopsys -fexplicit " "make" "-f \\1" |
| 241 | nil "mkdir \\1" "./" "work/" "Makefile" "ghdl" | 244 | nil "mkdir \\1" "./" "work/" "Makefile" "ghdl" |
| 242 | ("ghdl_p: \\*E,\\w+ (\\(.+\\),\\([0-9]+\\)|\\([0-9]+\\)):" 1 2 3) ("" 0) | 245 | ("ghdl_p: \\*E,\\w+ (\\([^ \\t\\n]+\\),\\([0-9]+\\)|\\([0-9]+\\)):" 1 2 3) ("" 0) |
| 243 | ("\\1/entity" "\\2/\\1" "\\1/configuration" | 246 | ("\\1/entity" "\\2/\\1" "\\1/configuration" |
| 244 | "\\1/package" "\\1/body" downcase)) | 247 | "\\1/package" "\\1/body" downcase)) |
| 248 | ;; IBM Compiler | ||
| 249 | ;; 00 COACHDL* | [CCHDL-1]: File: adder.vhd, line.column: 120.6 | ||
| 250 | ("IBM Compiler" "g2tvc" "-src" "precomp" "\\1" | ||
| 251 | nil "mkdir \\1" "./" "work/" "Makefile" "ibm" | ||
| 252 | ("[0-9]+ COACHDL.*: File: \\([^ \\t\\n]+\\), line.column: \\([0-9]+\\).\\([0-9]+\\)" 1 2 3) (" " 0) | ||
| 253 | nil) | ||
| 245 | ;; Ikos Voyager: analyze test.vhd | 254 | ;; Ikos Voyager: analyze test.vhd |
| 246 | ;; analyze test.vhd | 255 | ;; analyze test.vhd |
| 247 | ;; E L4/C5: this library unit is inaccessible | 256 | ;; E L4/C5: this library unit is inaccessible |
| 248 | ("Ikos" "analyze" "-l \\1" "make" "-f \\1" | 257 | ("Ikos" "analyze" "-l \\1" "make" "-f \\1" |
| 249 | nil "mkdir \\1" "./" "work/" "Makefile" "ikos" | 258 | nil "mkdir \\1" "./" "work/" "Makefile" "ikos" |
| 250 | ("E L\\([0-9]+\\)/C\\([0-9]+\\):" 0 1 2) | 259 | ("E L\\([0-9]+\\)/C\\([0-9]+\\):" nil 1 2) |
| 251 | ("^analyze +\\(.+ +\\)*\\(.+\\)$" 2) | 260 | ("^analyze +\\(.+ +\\)*\\(.+\\)$" 2) |
| 252 | nil) | 261 | nil) |
| 253 | ;; ModelSim, Model Technology: vcom test.vhd | 262 | ;; ModelSim, Model Technology: vcom test.vhd |
| @@ -257,29 +266,39 @@ Overrides local variable `indent-tabs-mode'." | |||
| 257 | ;; ** Error: adder.vhd(190): Unknown identifier: ctl_numb | 266 | ;; ** Error: adder.vhd(190): Unknown identifier: ctl_numb |
| 258 | ("ModelSim" "vcom" "-93 -work \\1" "make" "-f \\1" | 267 | ("ModelSim" "vcom" "-93 -work \\1" "make" "-f \\1" |
| 259 | nil "vlib \\1; vmap \\2 \\1" "./" "work/" "Makefile" "modelsim" | 268 | nil "vlib \\1; vmap \\2 \\1" "./" "work/" "Makefile" "modelsim" |
| 260 | ("\\(ERROR\\|WARNING\\|\\*\\* Error\\|\\*\\* Warning\\)[^:]*:\\( *\[[0-9]+\]\\)? \\(.+\\)(\\([0-9]+\\)):" 3 4 0) ("" 0) | 269 | ("\\(ERROR\\|WARNING\\|\\*\\* Error\\|\\*\\* Warning\\)[^:]*:\\( *\[[0-9]+\]\\)? \\([^ \\t\\n]+\\)(\\([0-9]+\\)):" 3 4 nil) ("" 0) |
| 261 | ("\\1/_primary.dat" "\\2/\\1.dat" "\\1/_primary.dat" | 270 | ("\\1/_primary.dat" "\\2/\\1.dat" "\\1/_primary.dat" |
| 262 | "\\1/_primary.dat" "\\1/body.dat" downcase)) | 271 | "\\1/_primary.dat" "\\1/body.dat" downcase)) |
| 263 | ;; ProVHDL, Synopsys LEDA: provhdl -w work -f test.vhd | 272 | ;; ProVHDL, Synopsys LEDA: provhdl -w work -f test.vhd |
| 264 | ;; test.vhd:34: error message | 273 | ;; test.vhd:34: error message |
| 265 | ("LEDA ProVHDL" "provhdl" "-w \\1 -f" "make" "-f \\1" | 274 | ("LEDA ProVHDL" "provhdl" "-w \\1 -f" "make" "-f \\1" |
| 266 | nil "mkdir \\1" "./" "work/" "Makefile" "provhdl" | 275 | nil "mkdir \\1" "./" "work/" "Makefile" "provhdl" |
| 267 | ("\\([^ \t\n]+\\):\\([0-9]+\\): " 1 2 0) ("" 0) | 276 | ("\\([^ \\t\\n]+\\):\\([0-9]+\\): " 1 2 nil) ("" 0) |
| 268 | ("ENTI/\\1.vif" "ARCH/\\1-\\2.vif" "CONF/\\1.vif" | 277 | ("ENTI/\\1.vif" "ARCH/\\1-\\2.vif" "CONF/\\1.vif" |
| 269 | "PACK/\\1.vif" "BODY/BODY-\\1.vif" upcase)) | 278 | "PACK/\\1.vif" "BODY/BODY-\\1.vif" upcase)) |
| 279 | ;; Quartus compiler | ||
| 280 | ;; Error: VHDL error at dvi2sdi.vhd(473): object k2_alto_out_lvl is used | ||
| 281 | ;; Error: Verilog HDL syntax error at otsuif_v1_top.vhd(147) near text | ||
| 282 | ;; Error: VHDL syntax error at otsuif_v1_top.vhd(147): clk_ is an illegal | ||
| 283 | ;; Error: VHDL Use Clause error at otsuif_v1_top.vhd(455): design library | ||
| 284 | ;; Warning: VHDL Process Statement warning at dvi2sdi_tst.vhd(172): ... | ||
| 285 | ("Quartus" "make" "-work \\1" "make" "-f \\1" | ||
| 286 | nil "mkdir \\1" "./" "work/" "Makefile" "quartus" | ||
| 287 | ("\\(Error\\|Warning\\): .* \\([^ \\t\\n]+\\)(\\([0-9]+\\))" 2 3 nil) ("" 0) | ||
| 288 | nil) | ||
| 270 | ;; QuickHDL, Mentor Graphics: qvhcom test.vhd | 289 | ;; QuickHDL, Mentor Graphics: qvhcom test.vhd |
| 271 | ;; ERROR: test.vhd(24): near "dnd": expecting: END | 290 | ;; ERROR: test.vhd(24): near "dnd": expecting: END |
| 272 | ;; WARNING[4]: test.vhd(30): A space is required between ... | 291 | ;; WARNING[4]: test.vhd(30): A space is required between ... |
| 273 | ("QuickHDL" "qvhcom" "-work \\1" "make" "-f \\1" | 292 | ("QuickHDL" "qvhcom" "-work \\1" "make" "-f \\1" |
| 274 | nil "mkdir \\1" "./" "work/" "Makefile" "quickhdl" | 293 | nil "mkdir \\1" "./" "work/" "Makefile" "quickhdl" |
| 275 | ("\\(ERROR\\|WARNING\\)[^:]*: \\(.+\\)(\\([0-9]+\\)):" 2 3 0) ("" 0) | 294 | ("\\(ERROR\\|WARNING\\)[^:]*: \\([^ \\t\\n]+\\)(\\([0-9]+\\)):" 2 3 nil) ("" 0) |
| 276 | ("\\1/_primary.dat" "\\2/\\1.dat" "\\1/_primary.dat" | 295 | ("\\1/_primary.dat" "\\2/\\1.dat" "\\1/_primary.dat" |
| 277 | "\\1/_primary.dat" "\\1/body.dat" downcase)) | 296 | "\\1/_primary.dat" "\\1/body.dat" downcase)) |
| 278 | ;; Savant: scram -publish-cc test.vhd | 297 | ;; Savant: scram -publish-cc test.vhd |
| 279 | ;; test.vhd:87: _set_passed_through_out_port(IIR_Boolean) not defined for | 298 | ;; test.vhd:87: _set_passed_through_out_port(IIR_Boolean) not defined for |
| 280 | ("Savant" "scram" "-publish-cc -design-library-name \\1" "make" "-f \\1" | 299 | ("Savant" "scram" "-publish-cc -design-library-name \\1" "make" "-f \\1" |
| 281 | nil "mkdir \\1" "./" "work._savant_lib/" "Makefile" "savant" | 300 | nil "mkdir \\1" "./" "work._savant_lib/" "Makefile" "savant" |
| 282 | ("\\([^ \t\n]+\\):\\([0-9]+\\): " 1 2 0) ("" 0) | 301 | ("\\([^ \\t\\n]+\\):\\([0-9]+\\): " 1 2 nil) ("" 0) |
| 283 | ("\\1_entity.vhdl" "\\2_secondary_units._savant_lib/\\2_\\1.vhdl" | 302 | ("\\1_entity.vhdl" "\\2_secondary_units._savant_lib/\\2_\\1.vhdl" |
| 284 | "\\1_config.vhdl" "\\1_package.vhdl" | 303 | "\\1_config.vhdl" "\\1_package.vhdl" |
| 285 | "\\1_secondary_units._savant_lib/\\1_package_body.vhdl" downcase)) | 304 | "\\1_secondary_units._savant_lib/\\1_package_body.vhdl" downcase)) |
| @@ -287,39 +306,39 @@ Overrides local variable `indent-tabs-mode'." | |||
| 287 | ;; Error: CSVHDL0002: test.vhd: (line 97): Invalid prefix | 306 | ;; Error: CSVHDL0002: test.vhd: (line 97): Invalid prefix |
| 288 | ("Simili" "vhdlp" "-work \\1" "make" "-f \\1" | 307 | ("Simili" "vhdlp" "-work \\1" "make" "-f \\1" |
| 289 | nil "mkdir \\1" "./" "work/" "Makefile" "simili" | 308 | nil "mkdir \\1" "./" "work/" "Makefile" "simili" |
| 290 | ("\\(Error\\|Warning\\): \\w+: \\(.+\\): (line \\([0-9]+\\)): " 2 3 0) ("" 0) | 309 | ("\\(Error\\|Warning\\): \\w+: \\([^ \\t\\n]+\\): (line \\([0-9]+\\)): " 2 3 nil) ("" 0) |
| 291 | ("\\1/prim.var" "\\2/_\\1.var" "\\1/prim.var" | 310 | ("\\1/prim.var" "\\2/_\\1.var" "\\1/prim.var" |
| 292 | "\\1/prim.var" "\\1/_body.var" downcase)) | 311 | "\\1/prim.var" "\\1/_body.var" downcase)) |
| 293 | ;; Speedwave (Innoveda): analyze -libfile vsslib.ini -src test.vhd | 312 | ;; Speedwave (Innoveda): analyze -libfile vsslib.ini -src test.vhd |
| 294 | ;; ERROR[11]::File test.vhd Line 100: Use of undeclared identifier | 313 | ;; ERROR[11]::File test.vhd Line 100: Use of undeclared identifier |
| 295 | ("Speedwave" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1" | 314 | ("Speedwave" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1" |
| 296 | nil "mkdir \\1" "./" "work/" "Makefile" "speedwave" | 315 | nil "mkdir \\1" "./" "work/" "Makefile" "speedwave" |
| 297 | ("^ *ERROR\[[0-9]+\]::File \\(.+\\) Line \\([0-9]+\\):" 1 2 0) ("" 0) | 316 | ("^ *ERROR\[[0-9]+\]::File \\([^ \\t\\n]+\\) Line \\([0-9]+\\):" 1 2 nil) ("" 0) |
| 298 | nil) | 317 | nil) |
| 299 | ;; Synopsys, VHDL Analyzer (sim): vhdlan -nc test.vhd | 318 | ;; Synopsys, VHDL Analyzer (sim): vhdlan -nc test.vhd |
| 300 | ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context. | 319 | ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context. |
| 301 | ("Synopsys" "vhdlan" "-nc -work \\1" "make" "-f \\1" | 320 | ("Synopsys" "vhdlan" "-nc -work \\1" "make" "-f \\1" |
| 302 | nil "mkdir \\1" "./" "work/" "Makefile" "synopsys" | 321 | nil "mkdir \\1" "./" "work/" "Makefile" "synopsys" |
| 303 | ("\\*\\*Error: vhdlan,[0-9]+ \\(.+\\)(\\([0-9]+\\)):" 1 2 0) ("" 0) | 322 | ("\\*\\*Error: vhdlan,[0-9]+ \\([^ \\t\\n]+\\)(\\([0-9]+\\)):" 1 2 nil) ("" 0) |
| 304 | ("\\1.sim" "\\2__\\1.sim" "\\1.sim" "\\1.sim" "\\1__.sim" upcase)) | 323 | ("\\1.sim" "\\2__\\1.sim" "\\1.sim" "\\1.sim" "\\1__.sim" upcase)) |
| 305 | ;; Synopsys, VHDL Analyzer (syn): vhdlan -nc -spc test.vhd | 324 | ;; Synopsys, VHDL Analyzer (syn): vhdlan -nc -spc test.vhd |
| 306 | ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context. | 325 | ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context. |
| 307 | ("Synopsys Design Compiler" "vhdlan" "-nc -spc -work \\1" "make" "-f \\1" | 326 | ("Synopsys Design Compiler" "vhdlan" "-nc -spc -work \\1" "make" "-f \\1" |
| 308 | nil "mkdir \\1" "./" "work/" "Makefile" "synopsys_dc" | 327 | nil "mkdir \\1" "./" "work/" "Makefile" "synopsys_dc" |
| 309 | ("\\*\\*Error: vhdlan,[0-9]+ \\(.+\\)(\\([0-9]+\\)):" 1 2 0) ("" 0) | 328 | ("\\*\\*Error: vhdlan,[0-9]+ \\([^ \\t\\n]+\\)(\\([0-9]+\\)):" 1 2 nil) ("" 0) |
| 310 | ("\\1.syn" "\\2__\\1.syn" "\\1.syn" "\\1.syn" "\\1__.syn" upcase)) | 329 | ("\\1.syn" "\\2__\\1.syn" "\\1.syn" "\\1.syn" "\\1__.syn" upcase)) |
| 311 | ;; Synplify: | 330 | ;; Synplify: |
| 312 | ;; @W:"test.vhd":57:8:57:9|Optimizing register bit count_x(5) to a constant 0 | 331 | ;; @W:"test.vhd":57:8:57:9|Optimizing register bit count_x(5) to a constant 0 |
| 313 | ("Synplify" "n/a" "n/a" "make" "-f \\1" | 332 | ("Synplify" "n/a" "n/a" "make" "-f \\1" |
| 314 | nil "mkdir \\1" "./" "work/" "Makefile" "synplify" | 333 | nil "mkdir \\1" "./" "work/" "Makefile" "synplify" |
| 315 | ("@[EWN]:\"\\(.+\\)\":\\([0-9]+\\):\\([0-9]+\\):" 1 2 3) ("" 0) | 334 | ("@[EWN]:\"\\([^ \\t\\n]+\\)\":\\([0-9]+\\):\\([0-9]+\\):" 1 2 3) ("" 0) |
| 316 | nil) | 335 | nil) |
| 317 | ;; Vantage: analyze -libfile vsslib.ini -src test.vhd | 336 | ;; Vantage: analyze -libfile vsslib.ini -src test.vhd |
| 318 | ;; Compiling "test.vhd" line 1... | 337 | ;; Compiling "test.vhd" line 1... |
| 319 | ;; **Error: LINE 49 *** No aggregate value is valid in this context. | 338 | ;; **Error: LINE 49 *** No aggregate value is valid in this context. |
| 320 | ("Vantage" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1" | 339 | ("Vantage" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1" |
| 321 | nil "mkdir \\1" "./" "work/" "Makefile" "vantage" | 340 | nil "mkdir \\1" "./" "work/" "Makefile" "vantage" |
| 322 | ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1 0) | 341 | ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" nil 1 nil) |
| 323 | ("^ *Compiling \"\\(.+\\)\" " 1) | 342 | ("^ *Compiling \"\\(.+\\)\" " 1) |
| 324 | nil) | 343 | nil) |
| 325 | ;; VeriBest: vc vhdl test.vhd | 344 | ;; VeriBest: vc vhdl test.vhd |
| @@ -329,21 +348,21 @@ Overrides local variable `indent-tabs-mode'." | |||
| 329 | ;; [Error] Name BITA is unknown | 348 | ;; [Error] Name BITA is unknown |
| 330 | ("VeriBest" "vc" "vhdl" "make" "-f \\1" | 349 | ("VeriBest" "vc" "vhdl" "make" "-f \\1" |
| 331 | nil "mkdir \\1" "./" "work/" "Makefile" "veribest" | 350 | nil "mkdir \\1" "./" "work/" "Makefile" "veribest" |
| 332 | ("^ +\\([0-9]+\\): +[^ ]" 0 1 0) ("" 0) | 351 | ("^ +\\([0-9]+\\): +[^ ]" nil 1 nil) ("" 0) |
| 333 | nil) | 352 | nil) |
| 334 | ;; Viewlogic: analyze -libfile vsslib.ini -src test.vhd | 353 | ;; Viewlogic: analyze -libfile vsslib.ini -src test.vhd |
| 335 | ;; Compiling "test.vhd" line 1... | 354 | ;; Compiling "test.vhd" line 1... |
| 336 | ;; **Error: LINE 49 *** No aggregate value is valid in this context. | 355 | ;; **Error: LINE 49 *** No aggregate value is valid in this context. |
| 337 | ("Viewlogic" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1" | 356 | ("Viewlogic" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1" |
| 338 | nil "mkdir \\1" "./" "work/" "Makefile" "viewlogic" | 357 | nil "mkdir \\1" "./" "work/" "Makefile" "viewlogic" |
| 339 | ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1 0) | 358 | ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" nil 1 nil) |
| 340 | ("^ *Compiling \"\\(.+\\)\" " 1) | 359 | ("^ *Compiling \"\\(.+\\)\" " 1) |
| 341 | nil) | 360 | nil) |
| 342 | ;; Xilinx XST: | 361 | ;; Xilinx XST: |
| 343 | ;; ERROR:HDLParsers:164 - "test.vhd" Line 3. parse error | 362 | ;; ERROR:HDLParsers:164 - "test.vhd" Line 3. parse error |
| 344 | ("Xilinx XST" "xflow" "" "make" "-f \\1" | 363 | ("Xilinx XST" "xflow" "" "make" "-f \\1" |
| 345 | nil "mkdir \\1" "./" "work/" "Makefile" "xilinx" | 364 | nil "mkdir \\1" "./" "work/" "Makefile" "xilinx" |
| 346 | ("^ERROR:HDLParsers:[0-9]+ - \"\\(.+\\)\" Line \\([0-9]+\\)\." 1 2 0) ("" 0) | 365 | ("^ERROR:HDLParsers:[0-9]+ - \"\\([^ \\t\\n]+\\)\" Line \\([0-9]+\\)\." 1 2 nil) ("" 0) |
| 347 | nil) | 366 | nil) |
| 348 | ) | 367 | ) |
| 349 | "List of available VHDL compilers and their properties. | 368 | "List of available VHDL compilers and their properties. |
| @@ -429,9 +448,13 @@ NOTE: Activate new error and file message regexps and reflect the new setting | |||
| 429 | (string :tag "ID string ") | 448 | (string :tag "ID string ") |
| 430 | (list :tag "Error message" :indent 4 | 449 | (list :tag "Error message" :indent 4 |
| 431 | (regexp :tag "Regexp ") | 450 | (regexp :tag "Regexp ") |
| 432 | (integer :tag "File subexp index") | 451 | (choice :tag "File subexp " |
| 452 | (integer :tag "Index") | ||
| 453 | (const :tag "No file name" nil)) | ||
| 433 | (integer :tag "Line subexp index") | 454 | (integer :tag "Line subexp index") |
| 434 | (integer :tag "Column subexp idx")) | 455 | (choice :tag "Column subexp " |
| 456 | (integer :tag "Index") | ||
| 457 | (const :tag "No column number" nil))) | ||
| 435 | (list :tag "File message" :indent 4 | 458 | (list :tag "File message" :indent 4 |
| 436 | (regexp :tag "Regexp ") | 459 | (regexp :tag "Regexp ") |
| 437 | (integer :tag "File subexp index")) | 460 | (integer :tag "File subexp index")) |
| @@ -450,6 +473,7 @@ NOTE: Activate new error and file message regexps and reflect the new setting | |||
| 450 | (const :tag "Downcase" downcase)))))) | 473 | (const :tag "Downcase" downcase)))))) |
| 451 | :set (lambda (variable value) | 474 | :set (lambda (variable value) |
| 452 | (vhdl-custom-set variable value 'vhdl-update-mode-menu)) | 475 | (vhdl-custom-set variable value 'vhdl-update-mode-menu)) |
| 476 | :version "24.4" | ||
| 453 | :group 'vhdl-compile) | 477 | :group 'vhdl-compile) |
| 454 | 478 | ||
| 455 | (defcustom vhdl-compiler "GHDL" | 479 | (defcustom vhdl-compiler "GHDL" |
| @@ -457,7 +481,7 @@ NOTE: Activate new error and file message regexps and reflect the new setting | |||
| 457 | Select a compiler name from the ones defined in option `vhdl-compiler-alist'." | 481 | Select a compiler name from the ones defined in option `vhdl-compiler-alist'." |
| 458 | :type (let ((alist vhdl-compiler-alist) list) | 482 | :type (let ((alist vhdl-compiler-alist) list) |
| 459 | (while alist | 483 | (while alist |
| 460 | (setq list (cons (list 'const (caar alist)) list)) | 484 | (push (list 'const (caar alist)) list) |
| 461 | (setq alist (cdr alist))) | 485 | (setq alist (cdr alist))) |
| 462 | (append '(choice) (nreverse list))) | 486 | (append '(choice) (nreverse list))) |
| 463 | :group 'vhdl-compile) | 487 | :group 'vhdl-compile) |
| @@ -602,7 +626,7 @@ NOTE: Reflect the new setting in the choice list of option `vhdl-project' | |||
| 602 | (list :tag "Compiler" :indent 6 | 626 | (list :tag "Compiler" :indent 6 |
| 603 | ,(let ((alist vhdl-compiler-alist) list) | 627 | ,(let ((alist vhdl-compiler-alist) list) |
| 604 | (while alist | 628 | (while alist |
| 605 | (setq list (cons (list 'const (caar alist)) list)) | 629 | (push (list 'const (caar alist)) list) |
| 606 | (setq alist (cdr alist))) | 630 | (setq alist (cdr alist))) |
| 607 | (append '(choice :tag "Compiler name") | 631 | (append '(choice :tag "Compiler name") |
| 608 | (nreverse list))) | 632 | (nreverse list))) |
| @@ -637,7 +661,7 @@ headers and the source files/directories to be scanned in the hierarchy | |||
| 637 | browser. The current project can also be changed temporarily in the menu." | 661 | browser. The current project can also be changed temporarily in the menu." |
| 638 | :type (let ((alist vhdl-project-alist) list) | 662 | :type (let ((alist vhdl-project-alist) list) |
| 639 | (while alist | 663 | (while alist |
| 640 | (setq list (cons (list 'const (caar alist)) list)) | 664 | (push (list 'const (caar alist)) list) |
| 641 | (setq alist (cdr alist))) | 665 | (setq alist (cdr alist))) |
| 642 | (append '(choice (const :tag "None" nil) (const :tag "--")) | 666 | (append '(choice (const :tag "None" nil) (const :tag "--")) |
| 643 | (nreverse list))) | 667 | (nreverse list))) |
| @@ -1268,6 +1292,18 @@ The comments and empty lines between groups of ports are pasted: | |||
| 1268 | (const :tag "Always" always)) | 1292 | (const :tag "Always" always)) |
| 1269 | :group 'vhdl-port) | 1293 | :group 'vhdl-port) |
| 1270 | 1294 | ||
| 1295 | (defcustom vhdl-actual-generic-name '(".*" . "\\&") | ||
| 1296 | (concat | ||
| 1297 | "Specifies how actual generic names are obtained from formal generic names. | ||
| 1298 | In a component instantiation, an actual generic name can be | ||
| 1299 | obtained by modifying the formal generic name (e.g. attaching or stripping | ||
| 1300 | off a substring)." | ||
| 1301 | vhdl-name-doc-string) | ||
| 1302 | :type '(cons (regexp :tag "From regexp") | ||
| 1303 | (string :tag "To string ")) | ||
| 1304 | :group 'vhdl-port | ||
| 1305 | :version "24.4") | ||
| 1306 | |||
| 1271 | (defcustom vhdl-actual-port-name '(".*" . "\\&") | 1307 | (defcustom vhdl-actual-port-name '(".*" . "\\&") |
| 1272 | (concat | 1308 | (concat |
| 1273 | "Specifies how actual port names are obtained from formal port names. | 1309 | "Specifies how actual port names are obtained from formal port names. |
| @@ -1469,21 +1505,21 @@ NOTE: Activate the new setting in a VHDL buffer by using the menu entry | |||
| 1469 | (defvar end-comment-column) | 1505 | (defvar end-comment-column) |
| 1470 | 1506 | ||
| 1471 | 1507 | ||
| 1472 | (defgroup vhdl-align nil | 1508 | (defgroup vhdl-beautify nil |
| 1473 | "Customizations for alignment." | 1509 | "Customizations for beautification." |
| 1474 | :group 'vhdl) | 1510 | :group 'vhdl) |
| 1475 | 1511 | ||
| 1476 | (defcustom vhdl-auto-align t | 1512 | (defcustom vhdl-auto-align t |
| 1477 | "Non-nil means align some templates automatically after generation." | 1513 | "Non-nil means align some templates automatically after generation." |
| 1478 | :type 'boolean | 1514 | :type 'boolean |
| 1479 | :group 'vhdl-align) | 1515 | :group 'vhdl-beautify) |
| 1480 | 1516 | ||
| 1481 | (defcustom vhdl-align-groups t | 1517 | (defcustom vhdl-align-groups t |
| 1482 | "Non-nil means align groups of code lines separately. | 1518 | "Non-nil means align groups of code lines separately. |
| 1483 | A group of code lines is a region of consecutive lines between two lines that | 1519 | A group of code lines is a region of consecutive lines between two lines that |
| 1484 | match the regexp in option `vhdl-align-group-separate'." | 1520 | match the regexp in option `vhdl-align-group-separate'." |
| 1485 | :type 'boolean | 1521 | :type 'boolean |
| 1486 | :group 'vhdl-align) | 1522 | :group 'vhdl-beautify) |
| 1487 | 1523 | ||
| 1488 | (defcustom vhdl-align-group-separate "^\\s-*$" | 1524 | (defcustom vhdl-align-group-separate "^\\s-*$" |
| 1489 | "Regexp for matching a line that separates groups of lines for alignment. | 1525 | "Regexp for matching a line that separates groups of lines for alignment. |
| @@ -1491,7 +1527,7 @@ Examples: | |||
| 1491 | \"^\\s-*$\": matches an empty line | 1527 | \"^\\s-*$\": matches an empty line |
| 1492 | \"^\\s-*\\(--.*\\)?$\": matches an empty line or a comment-only line" | 1528 | \"^\\s-*\\(--.*\\)?$\": matches an empty line or a comment-only line" |
| 1493 | :type 'regexp | 1529 | :type 'regexp |
| 1494 | :group 'vhdl-align) | 1530 | :group 'vhdl-beautify) |
| 1495 | 1531 | ||
| 1496 | (defcustom vhdl-align-same-indent t | 1532 | (defcustom vhdl-align-same-indent t |
| 1497 | "Non-nil means align blocks with same indent separately. | 1533 | "Non-nil means align blocks with same indent separately. |
| @@ -1500,7 +1536,18 @@ blocks of same indent which are aligned separately (except for argument/port | |||
| 1500 | lists). This gives nicer alignment in most cases. | 1536 | lists). This gives nicer alignment in most cases. |
| 1501 | Option `vhdl-align-groups' still applies within these blocks." | 1537 | Option `vhdl-align-groups' still applies within these blocks." |
| 1502 | :type 'boolean | 1538 | :type 'boolean |
| 1503 | :group 'vhdl-align) | 1539 | :group 'vhdl-beautify) |
| 1540 | |||
| 1541 | (defcustom vhdl-beautify-options '(t t t t t) | ||
| 1542 | "List of options for beautifying code. Allows to disable individual | ||
| 1543 | features of code beautification." | ||
| 1544 | :type '(list (boolean :tag "Whitespace cleanup ") | ||
| 1545 | (boolean :tag "Single statement per line") | ||
| 1546 | (boolean :tag "Indentation ") | ||
| 1547 | (boolean :tag "Alignment ") | ||
| 1548 | (boolean :tag "Case fixing ")) | ||
| 1549 | :group 'vhdl-beautify | ||
| 1550 | :version "24.4") | ||
| 1504 | 1551 | ||
| 1505 | 1552 | ||
| 1506 | (defgroup vhdl-highlight nil | 1553 | (defgroup vhdl-highlight nil |
| @@ -1846,7 +1893,7 @@ useful in large files where syntax-based indentation gets very slow." | |||
| 1846 | :group 'vhdl-misc) | 1893 | :group 'vhdl-misc) |
| 1847 | 1894 | ||
| 1848 | (defcustom vhdl-indent-comment-like-next-code-line t | 1895 | (defcustom vhdl-indent-comment-like-next-code-line t |
| 1849 | "*Non-nil means comment lines are indented like the following code line. | 1896 | "Non-nil means comment lines are indented like the following code line. |
| 1850 | Otherwise, comment lines are indented like the preceding code line. | 1897 | Otherwise, comment lines are indented like the preceding code line. |
| 1851 | Indenting comment lines like the following code line gives nicer indentation | 1898 | Indenting comment lines like the following code line gives nicer indentation |
| 1852 | when comments precede the code that they refer to." | 1899 | when comments precede the code that they refer to." |
| @@ -1872,14 +1919,11 @@ NOTE: Activate the new setting by restarting Emacs." | |||
| 1872 | "Non-nil means consider the underscore character `_' as part of word. | 1919 | "Non-nil means consider the underscore character `_' as part of word. |
| 1873 | An identifier containing underscores is then treated as a single word in | 1920 | An identifier containing underscores is then treated as a single word in |
| 1874 | select and move operations. All parts of an identifier separated by underscore | 1921 | select and move operations. All parts of an identifier separated by underscore |
| 1875 | are treated as single words otherwise. | 1922 | are treated as single words otherwise." |
| 1876 | |||
| 1877 | NOTE: Activate the new setting in a VHDL buffer by using the menu entry | ||
| 1878 | \"Activate Options\"." | ||
| 1879 | :type 'boolean | 1923 | :type 'boolean |
| 1880 | :set (lambda (variable value) | ||
| 1881 | (vhdl-custom-set variable value 'vhdl-mode-syntax-table-init)) | ||
| 1882 | :group 'vhdl-misc) | 1924 | :group 'vhdl-misc) |
| 1925 | (make-obsolete-variable 'vhdl-underscore-is-part-of-word | ||
| 1926 | 'superword-mode "24.4") | ||
| 1883 | 1927 | ||
| 1884 | 1928 | ||
| 1885 | (defgroup vhdl-related nil | 1929 | (defgroup vhdl-related nil |
| @@ -2070,7 +2114,7 @@ your style, only those that are different from the default.") | |||
| 2070 | (lambda (var) | 2114 | (lambda (var) |
| 2071 | (cons var (symbol-value var)))) | 2115 | (cons var (symbol-value var)))) |
| 2072 | varlist)))) | 2116 | varlist)))) |
| 2073 | (setq vhdl-style-alist (cons default vhdl-style-alist)))) | 2117 | (push default vhdl-style-alist))) |
| 2074 | 2118 | ||
| 2075 | (defvar vhdl-mode-hook nil | 2119 | (defvar vhdl-mode-hook nil |
| 2076 | "Hook called by `vhdl-mode'.") | 2120 | "Hook called by `vhdl-mode'.") |
| @@ -2087,10 +2131,11 @@ your style, only those that are different from the default.") | |||
| 2087 | (require 'hippie-exp) | 2131 | (require 'hippie-exp) |
| 2088 | 2132 | ||
| 2089 | ;; optional (minimize warning messages during compile) | 2133 | ;; optional (minimize warning messages during compile) |
| 2134 | (unless (featurep 'xemacs) | ||
| 2090 | (eval-when-compile | 2135 | (eval-when-compile |
| 2091 | (require 'font-lock) | 2136 | (require 'font-lock) |
| 2092 | (require 'ps-print) | 2137 | (require 'ps-print) |
| 2093 | (require 'speedbar)) | 2138 | (require 'speedbar))) ; for speedbar-with-writable |
| 2094 | 2139 | ||
| 2095 | 2140 | ||
| 2096 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 2141 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| @@ -2190,6 +2235,17 @@ Ignore byte-compiler warnings you might see." | |||
| 2190 | (unless (fboundp 'member-ignore-case) | 2235 | (unless (fboundp 'member-ignore-case) |
| 2191 | (defalias 'member-ignore-case 'member)) | 2236 | (defalias 'member-ignore-case 'member)) |
| 2192 | 2237 | ||
| 2238 | ;; `last-input-char' obsolete in Emacs 24, `last-input-event' different | ||
| 2239 | ;; behavior in XEmacs | ||
| 2240 | (defvar vhdl-last-input-event) | ||
| 2241 | (if (featurep 'xemacs) | ||
| 2242 | (defvaralias 'vhdl-last-input-event 'last-input-char) | ||
| 2243 | (defvaralias 'vhdl-last-input-event 'last-input-event)) | ||
| 2244 | |||
| 2245 | ;; `help-print-return-message' changed to `print-help-return-message' in Emacs | ||
| 2246 | ;;;(unless (fboundp 'help-print-return-message) | ||
| 2247 | ;;; (defalias 'help-print-return-message 'print-help-return-message)) | ||
| 2248 | |||
| 2193 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 2249 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 2194 | ;; Compatibility with older VHDL Mode versions | 2250 | ;; Compatibility with older VHDL Mode versions |
| 2195 | 2251 | ||
| @@ -2210,7 +2266,7 @@ Ignore byte-compiler warnings you might see." | |||
| 2210 | (vhdl-warning (apply 'format args) t) | 2266 | (vhdl-warning (apply 'format args) t) |
| 2211 | (unless vhdl-warnings | 2267 | (unless vhdl-warnings |
| 2212 | (vhdl-run-when-idle .1 nil 'vhdl-print-warnings)) | 2268 | (vhdl-run-when-idle .1 nil 'vhdl-print-warnings)) |
| 2213 | (setq vhdl-warnings (cons (apply 'format args) vhdl-warnings)))) | 2269 | (push (apply 'format args) vhdl-warnings))) |
| 2214 | 2270 | ||
| 2215 | (defun vhdl-warning (string &optional nobeep) | 2271 | (defun vhdl-warning (string &optional nobeep) |
| 2216 | "Print out warning STRING and beep." | 2272 | "Print out warning STRING and beep." |
| @@ -2244,7 +2300,7 @@ Ignore byte-compiler warnings you might see." | |||
| 2244 | (let ((old-alist vhdl-model-alist) | 2300 | (let ((old-alist vhdl-model-alist) |
| 2245 | new-alist) | 2301 | new-alist) |
| 2246 | (while old-alist | 2302 | (while old-alist |
| 2247 | (setq new-alist (cons (append (car old-alist) '("")) new-alist)) | 2303 | (push (append (car old-alist) '("")) new-alist) |
| 2248 | (setq old-alist (cdr old-alist))) | 2304 | (setq old-alist (cdr old-alist))) |
| 2249 | (setq vhdl-model-alist (nreverse new-alist))) | 2305 | (setq vhdl-model-alist (nreverse new-alist))) |
| 2250 | (customize-save-variable 'vhdl-model-alist vhdl-model-alist)) | 2306 | (customize-save-variable 'vhdl-model-alist vhdl-model-alist)) |
| @@ -2254,7 +2310,7 @@ Ignore byte-compiler warnings you might see." | |||
| 2254 | (let ((old-alist vhdl-project-alist) | 2310 | (let ((old-alist vhdl-project-alist) |
| 2255 | new-alist) | 2311 | new-alist) |
| 2256 | (while old-alist | 2312 | (while old-alist |
| 2257 | (setq new-alist (cons (append (car old-alist) '("")) new-alist)) | 2313 | (push (append (car old-alist) '("")) new-alist) |
| 2258 | (setq old-alist (cdr old-alist))) | 2314 | (setq old-alist (cdr old-alist))) |
| 2259 | (setq vhdl-project-alist (nreverse new-alist))) | 2315 | (setq vhdl-project-alist (nreverse new-alist))) |
| 2260 | (customize-save-variable 'vhdl-project-alist vhdl-project-alist)) | 2316 | (customize-save-variable 'vhdl-project-alist vhdl-project-alist)) |
| @@ -2342,7 +2398,6 @@ Ignore byte-compiler warnings you might see." | |||
| 2342 | (unless (get 'speedbar-indentation-width 'saved-value) | 2398 | (unless (get 'speedbar-indentation-width 'saved-value) |
| 2343 | (setq speedbar-indentation-width 2))) | 2399 | (setq speedbar-indentation-width 2))) |
| 2344 | 2400 | ||
| 2345 | |||
| 2346 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 2401 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 2347 | ;;; Help functions / inline substitutions / macros | 2402 | ;;; Help functions / inline substitutions / macros |
| 2348 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 2403 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| @@ -2433,6 +2488,7 @@ old environment. Used for consistent searching." | |||
| 2433 | (progn (set-buffer (create-file-buffer ,file-name)) | 2488 | (progn (set-buffer (create-file-buffer ,file-name)) |
| 2434 | (setq file-opened t) | 2489 | (setq file-opened t) |
| 2435 | (vhdl-insert-file-contents ,file-name) | 2490 | (vhdl-insert-file-contents ,file-name) |
| 2491 | ;; FIXME: This modifies a global syntax-table! | ||
| 2436 | (modify-syntax-entry ?\- ". 12" (syntax-table)) | 2492 | (modify-syntax-entry ?\- ". 12" (syntax-table)) |
| 2437 | (modify-syntax-entry ?\n ">" (syntax-table)) | 2493 | (modify-syntax-entry ?\n ">" (syntax-table)) |
| 2438 | (modify-syntax-entry ?\^M ">" (syntax-table)) | 2494 | (modify-syntax-entry ?\^M ">" (syntax-table)) |
| @@ -2489,7 +2545,7 @@ conversion." | |||
| 2489 | 2545 | ||
| 2490 | (defun vhdl-delete (elt list) | 2546 | (defun vhdl-delete (elt list) |
| 2491 | "Delete by side effect the first occurrence of ELT as a member of LIST." | 2547 | "Delete by side effect the first occurrence of ELT as a member of LIST." |
| 2492 | (setq list (cons nil list)) | 2548 | (push nil list) |
| 2493 | (let ((list1 list)) | 2549 | (let ((list1 list)) |
| 2494 | (while (and (cdr list1) (not (equal elt (cadr list1)))) | 2550 | (while (and (cdr list1) (not (equal elt (cadr list1)))) |
| 2495 | (setq list1 (cdr list1))) | 2551 | (setq list1 (cdr list1))) |
| @@ -2497,6 +2553,9 @@ conversion." | |||
| 2497 | (setcdr list1 (cddr list1)))) | 2553 | (setcdr list1 (cddr list1)))) |
| 2498 | (cdr list)) | 2554 | (cdr list)) |
| 2499 | 2555 | ||
| 2556 | (declare-function speedbar-refresh "speedbar" (&optional arg)) | ||
| 2557 | (declare-function speedbar-do-function-pointer "speedbar" ()) | ||
| 2558 | |||
| 2500 | (defun vhdl-speedbar-refresh (&optional key) | 2559 | (defun vhdl-speedbar-refresh (&optional key) |
| 2501 | "Refresh directory or project with name KEY." | 2560 | "Refresh directory or project with name KEY." |
| 2502 | (when (and (boundp 'speedbar-frame) | 2561 | (when (and (boundp 'speedbar-frame) |
| @@ -2537,6 +2596,11 @@ conversion." | |||
| 2537 | (set-buffer (marker-buffer marker))) | 2596 | (set-buffer (marker-buffer marker))) |
| 2538 | (goto-char marker)) | 2597 | (goto-char marker)) |
| 2539 | 2598 | ||
| 2599 | (defun vhdl-goto-line (line) | ||
| 2600 | "Use this instead of calling user level function `goto-line'." | ||
| 2601 | (goto-char (point-min)) | ||
| 2602 | (forward-line (1- line))) | ||
| 2603 | |||
| 2540 | (defun vhdl-menu-split (list title) | 2604 | (defun vhdl-menu-split (list title) |
| 2541 | "Split menu LIST into several submenus, if number of | 2605 | "Split menu LIST into several submenus, if number of |
| 2542 | elements > `vhdl-menu-max-size'." | 2606 | elements > `vhdl-menu-max-size'." |
| @@ -2547,19 +2611,19 @@ elements > `vhdl-menu-max-size'." | |||
| 2547 | (menuno 1) | 2611 | (menuno 1) |
| 2548 | (i 0)) | 2612 | (i 0)) |
| 2549 | (while remain | 2613 | (while remain |
| 2550 | (setq sublist (cons (car remain) sublist)) | 2614 | (push (car remain) sublist) |
| 2551 | (setq remain (cdr remain)) | 2615 | (setq remain (cdr remain)) |
| 2552 | (setq i (+ i 1)) | 2616 | (setq i (+ i 1)) |
| 2553 | (if (= i vhdl-menu-max-size) | 2617 | (if (= i vhdl-menu-max-size) |
| 2554 | (progn | 2618 | (progn |
| 2555 | (setq result (cons (cons (format "%s %s" title menuno) | 2619 | (push (cons (format "%s %s" title menuno) |
| 2556 | (nreverse sublist)) result)) | 2620 | (nreverse sublist)) result) |
| 2557 | (setq i 0) | 2621 | (setq i 0) |
| 2558 | (setq menuno (+ menuno 1)) | 2622 | (setq menuno (+ menuno 1)) |
| 2559 | (setq sublist '())))) | 2623 | (setq sublist '())))) |
| 2560 | (and sublist | 2624 | (and sublist |
| 2561 | (setq result (cons (cons (format "%s %s" title menuno) | 2625 | (push (cons (format "%s %s" title menuno) |
| 2562 | (nreverse sublist)) result))) | 2626 | (nreverse sublist)) result)) |
| 2563 | (nreverse result)) | 2627 | (nreverse result)) |
| 2564 | list)) | 2628 | list)) |
| 2565 | 2629 | ||
| @@ -2723,11 +2787,6 @@ STRING are replaced by `-' and substrings are converted to lower case." | |||
| 2723 | (define-key vhdl-mode-map "\M-\C-h" 'vhdl-mark-defun)) | 2787 | (define-key vhdl-mode-map "\M-\C-h" 'vhdl-mark-defun)) |
| 2724 | (define-key vhdl-mode-map "\M-\C-q" 'vhdl-indent-sexp) | 2788 | (define-key vhdl-mode-map "\M-\C-q" 'vhdl-indent-sexp) |
| 2725 | (define-key vhdl-mode-map "\M-^" 'vhdl-delete-indentation) | 2789 | (define-key vhdl-mode-map "\M-^" 'vhdl-delete-indentation) |
| 2726 | ;; backspace/delete key bindings | ||
| 2727 | (define-key vhdl-mode-map [backspace] 'backward-delete-char-untabify) | ||
| 2728 | (unless (boundp 'delete-key-deletes-forward) ; XEmacs variable | ||
| 2729 | (define-key vhdl-mode-map [delete] 'delete-char) | ||
| 2730 | (define-key vhdl-mode-map [(meta delete)] 'kill-word)) | ||
| 2731 | ;; mode specific key bindings | 2790 | ;; mode specific key bindings |
| 2732 | (define-key vhdl-mode-map "\C-c\C-m\C-e" 'vhdl-electric-mode) | 2791 | (define-key vhdl-mode-map "\C-c\C-m\C-e" 'vhdl-electric-mode) |
| 2733 | (define-key vhdl-mode-map "\C-c\C-m\C-s" 'vhdl-stutter-mode) | 2792 | (define-key vhdl-mode-map "\C-c\C-m\C-s" 'vhdl-stutter-mode) |
| @@ -2794,6 +2853,8 @@ STRING are replaced by `-' and substrings are converted to lower case." | |||
| 2794 | (define-key vhdl-mode-map "\C-c\C-l\C-o" 'vhdl-line-open) | 2853 | (define-key vhdl-mode-map "\C-c\C-l\C-o" 'vhdl-line-open) |
| 2795 | (define-key vhdl-mode-map "\C-c\C-l\C-g" 'goto-line) | 2854 | (define-key vhdl-mode-map "\C-c\C-l\C-g" 'goto-line) |
| 2796 | (define-key vhdl-mode-map "\C-c\C-l\C-c" 'vhdl-comment-uncomment-line) | 2855 | (define-key vhdl-mode-map "\C-c\C-l\C-c" 'vhdl-comment-uncomment-line) |
| 2856 | (define-key vhdl-mode-map "\C-c\C-x\C-s" 'vhdl-fix-statement-region) | ||
| 2857 | (define-key vhdl-mode-map "\C-c\C-x\M-s" 'vhdl-fix-statement-buffer) | ||
| 2797 | (define-key vhdl-mode-map "\C-c\C-x\C-p" 'vhdl-fix-clause) | 2858 | (define-key vhdl-mode-map "\C-c\C-x\C-p" 'vhdl-fix-clause) |
| 2798 | (define-key vhdl-mode-map "\C-c\C-x\M-c" 'vhdl-fix-case-region) | 2859 | (define-key vhdl-mode-map "\C-c\C-x\M-c" 'vhdl-fix-case-region) |
| 2799 | (define-key vhdl-mode-map "\C-c\C-x\C-c" 'vhdl-fix-case-buffer) | 2860 | (define-key vhdl-mode-map "\C-c\C-x\C-c" 'vhdl-fix-case-buffer) |
| @@ -2864,56 +2925,51 @@ STRING are replaced by `-' and substrings are converted to lower case." | |||
| 2864 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 2925 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 2865 | ;; Syntax table | 2926 | ;; Syntax table |
| 2866 | 2927 | ||
| 2867 | (defvar vhdl-mode-syntax-table nil | 2928 | (defvar vhdl-mode-syntax-table |
| 2929 | (let ((st (make-syntax-table))) | ||
| 2930 | ;; define punctuation | ||
| 2931 | (modify-syntax-entry ?\# "." st) | ||
| 2932 | (modify-syntax-entry ?\$ "." st) | ||
| 2933 | (modify-syntax-entry ?\% "." st) | ||
| 2934 | (modify-syntax-entry ?\& "." st) | ||
| 2935 | (modify-syntax-entry ?\' "." st) | ||
| 2936 | (modify-syntax-entry ?\* "." st) | ||
| 2937 | (modify-syntax-entry ?\+ "." st) | ||
| 2938 | (modify-syntax-entry ?\. "." st) | ||
| 2939 | (modify-syntax-entry ?\/ "." st) | ||
| 2940 | (modify-syntax-entry ?\: "." st) | ||
| 2941 | (modify-syntax-entry ?\; "." st) | ||
| 2942 | (modify-syntax-entry ?\< "." st) | ||
| 2943 | (modify-syntax-entry ?\= "." st) | ||
| 2944 | (modify-syntax-entry ?\> "." st) | ||
| 2945 | (modify-syntax-entry ?\\ "." st) | ||
| 2946 | (modify-syntax-entry ?\| "." st) | ||
| 2947 | ;; define string | ||
| 2948 | (modify-syntax-entry ?\" "\"" st) | ||
| 2949 | ;; define underscore | ||
| 2950 | (modify-syntax-entry ?\_ (if vhdl-underscore-is-part-of-word "w" "_") st) | ||
| 2951 | ;; a single hyphen is punctuation, but a double hyphen starts a comment | ||
| 2952 | (modify-syntax-entry ?\- ". 12" st) | ||
| 2953 | ;; and \n and \^M end a comment | ||
| 2954 | (modify-syntax-entry ?\n ">" st) | ||
| 2955 | (modify-syntax-entry ?\^M ">" st) | ||
| 2956 | ;; define parentheses to match | ||
| 2957 | (modify-syntax-entry ?\( "()" st) | ||
| 2958 | (modify-syntax-entry ?\) ")(" st) | ||
| 2959 | (modify-syntax-entry ?\[ "(]" st) | ||
| 2960 | (modify-syntax-entry ?\] ")[" st) | ||
| 2961 | (modify-syntax-entry ?\{ "(}" st) | ||
| 2962 | (modify-syntax-entry ?\} "){" st) | ||
| 2963 | st) | ||
| 2868 | "Syntax table used in `vhdl-mode' buffers.") | 2964 | "Syntax table used in `vhdl-mode' buffers.") |
| 2869 | 2965 | ||
| 2870 | (defvar vhdl-mode-ext-syntax-table nil | 2966 | (defvar vhdl-mode-ext-syntax-table |
| 2967 | ;; Extended syntax table including '_' (for simpler search regexps). | ||
| 2968 | (let ((st (copy-syntax-table vhdl-mode-syntax-table))) | ||
| 2969 | (modify-syntax-entry ?_ "w" st) | ||
| 2970 | st) | ||
| 2871 | "Syntax table extended by `_' used in `vhdl-mode' buffers.") | 2971 | "Syntax table extended by `_' used in `vhdl-mode' buffers.") |
| 2872 | 2972 | ||
| 2873 | (defun vhdl-mode-syntax-table-init () | ||
| 2874 | "Initialize `vhdl-mode-syntax-table'." | ||
| 2875 | (setq vhdl-mode-syntax-table (make-syntax-table)) | ||
| 2876 | ;; define punctuation | ||
| 2877 | (modify-syntax-entry ?\# "." vhdl-mode-syntax-table) | ||
| 2878 | (modify-syntax-entry ?\$ "." vhdl-mode-syntax-table) | ||
| 2879 | (modify-syntax-entry ?\% "." vhdl-mode-syntax-table) | ||
| 2880 | (modify-syntax-entry ?\& "." vhdl-mode-syntax-table) | ||
| 2881 | (modify-syntax-entry ?\' "." vhdl-mode-syntax-table) | ||
| 2882 | (modify-syntax-entry ?\* "." vhdl-mode-syntax-table) | ||
| 2883 | (modify-syntax-entry ?\+ "." vhdl-mode-syntax-table) | ||
| 2884 | (modify-syntax-entry ?\. "." vhdl-mode-syntax-table) | ||
| 2885 | (modify-syntax-entry ?\/ "." vhdl-mode-syntax-table) | ||
| 2886 | (modify-syntax-entry ?\: "." vhdl-mode-syntax-table) | ||
| 2887 | (modify-syntax-entry ?\; "." vhdl-mode-syntax-table) | ||
| 2888 | (modify-syntax-entry ?\< "." vhdl-mode-syntax-table) | ||
| 2889 | (modify-syntax-entry ?\= "." vhdl-mode-syntax-table) | ||
| 2890 | (modify-syntax-entry ?\> "." vhdl-mode-syntax-table) | ||
| 2891 | (modify-syntax-entry ?\\ "." vhdl-mode-syntax-table) | ||
| 2892 | (modify-syntax-entry ?\| "." vhdl-mode-syntax-table) | ||
| 2893 | ;; define string | ||
| 2894 | (modify-syntax-entry ?\" "\"" vhdl-mode-syntax-table) | ||
| 2895 | ;; define underscore | ||
| 2896 | (when vhdl-underscore-is-part-of-word | ||
| 2897 | (modify-syntax-entry ?\_ "w" vhdl-mode-syntax-table)) | ||
| 2898 | ;; a single hyphen is punctuation, but a double hyphen starts a comment | ||
| 2899 | (modify-syntax-entry ?\- ". 12" vhdl-mode-syntax-table) | ||
| 2900 | ;; and \n and \^M end a comment | ||
| 2901 | (modify-syntax-entry ?\n ">" vhdl-mode-syntax-table) | ||
| 2902 | (modify-syntax-entry ?\^M ">" vhdl-mode-syntax-table) | ||
| 2903 | ;; define parentheses to match | ||
| 2904 | (modify-syntax-entry ?\( "()" vhdl-mode-syntax-table) | ||
| 2905 | (modify-syntax-entry ?\) ")(" vhdl-mode-syntax-table) | ||
| 2906 | (modify-syntax-entry ?\[ "(]" vhdl-mode-syntax-table) | ||
| 2907 | (modify-syntax-entry ?\] ")[" vhdl-mode-syntax-table) | ||
| 2908 | (modify-syntax-entry ?\{ "(}" vhdl-mode-syntax-table) | ||
| 2909 | (modify-syntax-entry ?\} "){" vhdl-mode-syntax-table) | ||
| 2910 | ;; extended syntax table including '_' (for simpler search regexps) | ||
| 2911 | (setq vhdl-mode-ext-syntax-table (copy-syntax-table vhdl-mode-syntax-table)) | ||
| 2912 | (modify-syntax-entry ?_ "w" vhdl-mode-ext-syntax-table)) | ||
| 2913 | |||
| 2914 | ;; initialize syntax table for VHDL Mode | ||
| 2915 | (vhdl-mode-syntax-table-init) | ||
| 2916 | |||
| 2917 | (defvar vhdl-syntactic-context nil | 2973 | (defvar vhdl-syntactic-context nil |
| 2918 | "Buffer local variable containing syntactic analysis list.") | 2974 | "Buffer local variable containing syntactic analysis list.") |
| 2919 | (make-variable-buffer-local 'vhdl-syntactic-context) | 2975 | (make-variable-buffer-local 'vhdl-syntactic-context) |
| @@ -3506,6 +3562,9 @@ STRING are replaced by `-' and substrings are converted to lower case." | |||
| 3506 | ["Whitespace Region" vhdl-fixup-whitespace-region (mark)] | 3562 | ["Whitespace Region" vhdl-fixup-whitespace-region (mark)] |
| 3507 | ["Whitespace Buffer" vhdl-fixup-whitespace-buffer t] | 3563 | ["Whitespace Buffer" vhdl-fixup-whitespace-buffer t] |
| 3508 | "--" | 3564 | "--" |
| 3565 | ["Statement Region" vhdl-fix-statement-region (mark)] | ||
| 3566 | ["Statement Buffer" vhdl-fix-statement-buffer t] | ||
| 3567 | "--" | ||
| 3509 | ["Trailing Spaces Buffer" vhdl-remove-trailing-spaces t]) | 3568 | ["Trailing Spaces Buffer" vhdl-remove-trailing-spaces t]) |
| 3510 | ("Update" | 3569 | ("Update" |
| 3511 | ["Sensitivity List" vhdl-update-sensitivity-list-process t] | 3570 | ["Sensitivity List" vhdl-update-sensitivity-list-process t] |
| @@ -3814,6 +3873,7 @@ STRING are replaced by `-' and substrings are converted to lower case." | |||
| 3814 | ["Always" | 3873 | ["Always" |
| 3815 | (customize-set-variable 'vhdl-include-group-comments 'always) | 3874 | (customize-set-variable 'vhdl-include-group-comments 'always) |
| 3816 | :style radio :selected (eq 'always vhdl-include-group-comments)]) | 3875 | :style radio :selected (eq 'always vhdl-include-group-comments)]) |
| 3876 | ["Actual Generic Name..." (customize-option 'vhdl-actual-generic-name) t] | ||
| 3817 | ["Actual Port Name..." (customize-option 'vhdl-actual-port-name) t] | 3877 | ["Actual Port Name..." (customize-option 'vhdl-actual-port-name) t] |
| 3818 | ["Instance Name..." (customize-option 'vhdl-instance-name) t] | 3878 | ["Instance Name..." (customize-option 'vhdl-instance-name) t] |
| 3819 | ("Testbench" | 3879 | ("Testbench" |
| @@ -3910,7 +3970,7 @@ STRING are replaced by `-' and substrings are converted to lower case." | |||
| 3910 | ["End Comment Column..." (customize-option 'vhdl-end-comment-column) t] | 3970 | ["End Comment Column..." (customize-option 'vhdl-end-comment-column) t] |
| 3911 | "--" | 3971 | "--" |
| 3912 | ["Customize Group..." (customize-group 'vhdl-comment) t]) | 3972 | ["Customize Group..." (customize-group 'vhdl-comment) t]) |
| 3913 | ("Align" | 3973 | ("Beautify" |
| 3914 | ["Auto Align Templates" | 3974 | ["Auto Align Templates" |
| 3915 | (customize-set-variable 'vhdl-auto-align (not vhdl-auto-align)) | 3975 | (customize-set-variable 'vhdl-auto-align (not vhdl-auto-align)) |
| 3916 | :style toggle :selected vhdl-auto-align] | 3976 | :style toggle :selected vhdl-auto-align] |
| @@ -3918,13 +3978,14 @@ STRING are replaced by `-' and substrings are converted to lower case." | |||
| 3918 | (customize-set-variable 'vhdl-align-groups (not vhdl-align-groups)) | 3978 | (customize-set-variable 'vhdl-align-groups (not vhdl-align-groups)) |
| 3919 | :style toggle :selected vhdl-align-groups] | 3979 | :style toggle :selected vhdl-align-groups] |
| 3920 | ["Group Separation String..." | 3980 | ["Group Separation String..." |
| 3921 | (customize-set-variable 'vhdl-align-group-separate) t] | 3981 | (customize-option 'vhdl-align-group-separate) t] |
| 3922 | ["Align Lines with Same Indent" | 3982 | ["Align Lines with Same Indent" |
| 3923 | (customize-set-variable 'vhdl-align-same-indent | 3983 | (customize-set-variable 'vhdl-align-same-indent |
| 3924 | (not vhdl-align-same-indent)) | 3984 | (not vhdl-align-same-indent)) |
| 3925 | :style toggle :selected vhdl-align-same-indent] | 3985 | :style toggle :selected vhdl-align-same-indent] |
| 3986 | ["Beautify Options..." (customize-option 'vhdl-beautify-options) t] | ||
| 3926 | "--" | 3987 | "--" |
| 3927 | ["Customize Group..." (customize-group 'vhdl-align) t]) | 3988 | ["Customize Group..." (customize-group 'vhdl-beautify) t]) |
| 3928 | ("Highlight" | 3989 | ("Highlight" |
| 3929 | ["Highlighting On/Off..." | 3990 | ["Highlighting On/Off..." |
| 3930 | (customize-option | 3991 | (customize-option |
| @@ -4188,14 +4249,13 @@ The directory of the current source file is scanned." | |||
| 4188 | (setq found nil) | 4249 | (setq found nil) |
| 4189 | (while file-list | 4250 | (while file-list |
| 4190 | (setq found t) | 4251 | (setq found t) |
| 4191 | (setq menu-list (cons (vector (car file-list) | 4252 | (push (vector (car file-list) (list 'find-file (car file-list)) t) |
| 4192 | (list 'find-file (car file-list)) t) | 4253 | menu-list) |
| 4193 | menu-list)) | ||
| 4194 | (setq file-list (cdr file-list))) | 4254 | (setq file-list (cdr file-list))) |
| 4195 | (setq menu-list (vhdl-menu-split menu-list "Sources")) | 4255 | (setq menu-list (vhdl-menu-split menu-list "Sources")) |
| 4196 | (when found (setq menu-list (cons "--" menu-list))) | 4256 | (when found (push "--" menu-list)) |
| 4197 | (setq menu-list (cons ["*Rescan*" vhdl-add-source-files-menu t] menu-list)) | 4257 | (push ["*Rescan*" vhdl-add-source-files-menu t] menu-list) |
| 4198 | (setq menu-list (cons "Sources" menu-list)) | 4258 | (push "Sources" menu-list) |
| 4199 | ;; Create menu | 4259 | ;; Create menu |
| 4200 | (easy-menu-add menu-list) | 4260 | (easy-menu-add menu-list) |
| 4201 | (easy-menu-define vhdl-sources-menu newmap | 4261 | (easy-menu-define vhdl-sources-menu newmap |
| @@ -4579,7 +4639,7 @@ Usage: | |||
| 4579 | option `vhdl-index-menu' to non-nil) or made accessible as a mouse menu | 4639 | option `vhdl-index-menu' to non-nil) or made accessible as a mouse menu |
| 4580 | (e.g. add \"(global-set-key '[S-down-mouse-3] 'imenu)\" to your start-up | 4640 | (e.g. add \"(global-set-key '[S-down-mouse-3] 'imenu)\" to your start-up |
| 4581 | file) for browsing the file contents (is not populated if buffer is | 4641 | file) for browsing the file contents (is not populated if buffer is |
| 4582 | larger than `font-lock-maximum-size'). Also, a source file menu can be | 4642 | larger than 256000). Also, a source file menu can be |
| 4583 | added (set option `vhdl-source-file-menu' to non-nil) for browsing the | 4643 | added (set option `vhdl-source-file-menu' to non-nil) for browsing the |
| 4584 | current directory for VHDL source files. | 4644 | current directory for VHDL source files. |
| 4585 | 4645 | ||
| @@ -4706,7 +4766,7 @@ Usage: | |||
| 4706 | automatically recognized as VHDL source files. To add an extension | 4766 | automatically recognized as VHDL source files. To add an extension |
| 4707 | \".xxx\", add the following line to your Emacs start-up file (`.emacs'): | 4767 | \".xxx\", add the following line to your Emacs start-up file (`.emacs'): |
| 4708 | 4768 | ||
| 4709 | \(setq auto-mode-alist (cons '(\"\\\\.xxx\\\\'\" . vhdl-mode) auto-mode-alist)) | 4769 | \(push '(\"\\\\.xxx\\\\'\" . vhdl-mode) auto-mode-alist) |
| 4710 | 4770 | ||
| 4711 | 4771 | ||
| 4712 | HINTS: | 4772 | HINTS: |
| @@ -7277,7 +7337,7 @@ indentation change." | |||
| 7277 | (beginning-of-line 2) | 7337 | (beginning-of-line 2) |
| 7278 | (setq syntax (vhdl-get-syntactic-context))))) | 7338 | (setq syntax (vhdl-get-syntactic-context))))) |
| 7279 | (when is-comment | 7339 | (when is-comment |
| 7280 | (setq syntax (cons (cons 'comment nil) syntax))) | 7340 | (push (cons 'comment nil) syntax)) |
| 7281 | (apply '+ (mapcar 'vhdl-get-offset syntax))) | 7341 | (apply '+ (mapcar 'vhdl-get-offset syntax))) |
| 7282 | ;; indent like previous nonblank line | 7342 | ;; indent like previous nonblank line |
| 7283 | (save-excursion (beginning-of-line) | 7343 | (save-excursion (beginning-of-line) |
| @@ -7388,7 +7448,7 @@ ENDPOS is encountered." | |||
| 7388 | 7448 | ||
| 7389 | 7449 | ||
| 7390 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 7450 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 7391 | ;;; Alignment, whitespace fixup, beautifying | 7451 | ;;; Alignment, beautifying |
| 7392 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 7452 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 7393 | 7453 | ||
| 7394 | (defconst vhdl-align-alist | 7454 | (defconst vhdl-align-alist |
| @@ -7604,7 +7664,8 @@ the token in MATCH." | |||
| 7604 | (when vhdl-progress-interval | 7664 | (when vhdl-progress-interval |
| 7605 | (setq vhdl-progress-info (vector (count-lines (point-min) beg) | 7665 | (setq vhdl-progress-info (vector (count-lines (point-min) beg) |
| 7606 | (count-lines (point-min) end) 0)))) | 7666 | (count-lines (point-min) end) 0)))) |
| 7607 | (vhdl-fixup-whitespace-region beg end t) | 7667 | (when (nth 0 vhdl-beautify-options) |
| 7668 | (vhdl-fixup-whitespace-region beg end t)) | ||
| 7608 | (goto-char beg) | 7669 | (goto-char beg) |
| 7609 | (if (not vhdl-align-groups) | 7670 | (if (not vhdl-align-groups) |
| 7610 | ;; align entire region | 7671 | ;; align entire region |
| @@ -7728,14 +7789,14 @@ the token in MATCH." | |||
| 7728 | ;; search for comment start positions and lengths | 7789 | ;; search for comment start positions and lengths |
| 7729 | (while (< (point) end) | 7790 | (while (< (point) end) |
| 7730 | (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>")) | 7791 | (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>")) |
| 7731 | (looking-at "^\\(.*[^ \t\n\r\f-]+\\)\\s-*\\(--.*\\)$") | 7792 | (looking-at "^\\(.*?[^ \t\n\r\f-]+\\)\\s-*\\(--.*\\)$") |
| 7732 | (not (save-excursion (goto-char (match-beginning 2)) | 7793 | (not (save-excursion (goto-char (match-beginning 2)) |
| 7733 | (vhdl-in-literal)))) | 7794 | (vhdl-in-literal)))) |
| 7734 | (setq start (+ (- (match-end 1) (match-beginning 1)) spacing)) | 7795 | (setq start (+ (- (match-end 1) (match-beginning 1)) spacing)) |
| 7735 | (setq length (- (match-end 2) (match-beginning 2))) | 7796 | (setq length (- (match-end 2) (match-beginning 2))) |
| 7736 | (setq start-max (max start start-max)) | 7797 | (setq start-max (max start start-max)) |
| 7737 | (setq length-max (max length length-max)) | 7798 | (setq length-max (max length length-max)) |
| 7738 | (setq comment-list (cons (cons start length) comment-list))) | 7799 | (push (cons start length) comment-list)) |
| 7739 | (beginning-of-line 2)) | 7800 | (beginning-of-line 2)) |
| 7740 | (setq comment-list | 7801 | (setq comment-list |
| 7741 | (sort comment-list (function (lambda (a b) (> (car a) (car b)))))) | 7802 | (sort comment-list (function (lambda (a b) (> (car a) (car b)))))) |
| @@ -7746,14 +7807,14 @@ the token in MATCH." | |||
| 7746 | (unless (or (= (caar comment-list) (car start-list)) | 7807 | (unless (or (= (caar comment-list) (car start-list)) |
| 7747 | (<= (+ (car start-list) (cdar comment-list)) | 7808 | (<= (+ (car start-list) (cdar comment-list)) |
| 7748 | end-comment-column)) | 7809 | end-comment-column)) |
| 7749 | (setq start-list (cons (caar comment-list) start-list))) | 7810 | (push (caar comment-list) start-list)) |
| 7750 | (setq comment-list (cdr comment-list))) | 7811 | (setq comment-list (cdr comment-list))) |
| 7751 | ;; align lines as nicely as possible | 7812 | ;; align lines as nicely as possible |
| 7752 | (goto-char beg) | 7813 | (goto-char beg) |
| 7753 | (while (< (point) end) | 7814 | (while (< (point) end) |
| 7754 | (setq cur-start nil) | 7815 | (setq cur-start nil) |
| 7755 | (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>")) | 7816 | (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>")) |
| 7756 | (or (and (looking-at "^\\(.*[^ \t\n\r\f-]+\\)\\(\\s-*\\)\\(--.*\\)$") | 7817 | (or (and (looking-at "^\\(.*?[^ \t\n\r\f-]+\\)\\(\\s-*\\)\\(--.*\\)$") |
| 7757 | (not (save-excursion | 7818 | (not (save-excursion |
| 7758 | (goto-char (match-beginning 3)) | 7819 | (goto-char (match-beginning 3)) |
| 7759 | (vhdl-in-literal)))) | 7820 | (vhdl-in-literal)))) |
| @@ -7879,7 +7940,7 @@ end of line, do nothing in comments and strings." | |||
| 7879 | (replace-match "\\2"))) | 7940 | (replace-match "\\2"))) |
| 7880 | ;; surround operator symbols by one space | 7941 | ;; surround operator symbols by one space |
| 7881 | (goto-char beg) | 7942 | (goto-char beg) |
| 7882 | (while (re-search-forward "\\(--.*\n\\|\"[^\"\n]*[\"\n]\\|\'.\'\\|\\\\[^\\\n]*[\\\n]\\)\\|\\(\\([^/:<>=]\\)\\(:\\|\\??=\\|\\??<<\\|\\??>>\\|\\??<\\|\\??>\\|:=\\|\\??<=\\|\\??>=\\|=>\\|\\??/=\\|\\?\\?\\)\\([^=>]\\|$\\)\\)" end t) | 7943 | (while (re-search-forward "\\(--.*\n\\|\"[^\"\n]*[\"\n]\\|\'.\'\\|\\\\[^\\\n]*[\\\n]\\)\\|\\(\\([^/:<>=\n]\\)\\(:\\|\\??=\\|\\??<<\\|\\??>>\\|\\??<\\|\\??>\\|:=\\|\\??<=\\|\\??>=\\|=>\\|\\??/=\\|\\?\\?\\)\\([^=>\n]\\|$\\)\\)" end t) |
| 7883 | (if (or (match-string 1) | 7944 | (if (or (match-string 1) |
| 7884 | (<= (match-beginning 0) ; not if at boi | 7945 | (<= (match-beginning 0) ; not if at boi |
| 7885 | (save-excursion (back-to-indentation) (point)))) | 7946 | (save-excursion (back-to-indentation) (point)))) |
| @@ -7913,6 +7974,154 @@ end of line, do nothing in comments." | |||
| 7913 | (vhdl-fixup-whitespace-region (point-min) (point-max))) | 7974 | (vhdl-fixup-whitespace-region (point-min) (point-max))) |
| 7914 | 7975 | ||
| 7915 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 7976 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 7977 | ;; Case fixing | ||
| 7978 | |||
| 7979 | (defun vhdl-fix-case-region-1 (beg end upper-case word-regexp &optional count) | ||
| 7980 | "Convert all words matching WORD-REGEXP in region to lower or upper case, | ||
| 7981 | depending on parameter UPPER-CASE." | ||
| 7982 | (let ((case-replace nil) | ||
| 7983 | (last-update 0)) | ||
| 7984 | (vhdl-prepare-search-2 | ||
| 7985 | (save-excursion | ||
| 7986 | (goto-char end) | ||
| 7987 | (setq end (point-marker)) | ||
| 7988 | (goto-char beg) | ||
| 7989 | (while (re-search-forward word-regexp end t) | ||
| 7990 | (or (vhdl-in-literal) | ||
| 7991 | (if upper-case | ||
| 7992 | (upcase-word -1) | ||
| 7993 | (downcase-word -1))) | ||
| 7994 | (when (and count vhdl-progress-interval (not noninteractive) | ||
| 7995 | (< vhdl-progress-interval | ||
| 7996 | (- (nth 1 (current-time)) last-update))) | ||
| 7997 | (message "Fixing case... (%2d%s)" | ||
| 7998 | (+ (* count 20) (/ (* 20 (- (point) beg)) (- end beg))) | ||
| 7999 | "%") | ||
| 8000 | (setq last-update (nth 1 (current-time))))) | ||
| 8001 | (goto-char end))))) | ||
| 8002 | |||
| 8003 | (defun vhdl-fix-case-region (beg end &optional arg) | ||
| 8004 | "Convert all VHDL words in region to lower or upper case, depending on | ||
| 8005 | options vhdl-upper-case-{keywords,types,attributes,enum-values}." | ||
| 8006 | (interactive "r\nP") | ||
| 8007 | (vhdl-fix-case-region-1 | ||
| 8008 | beg end vhdl-upper-case-keywords vhdl-keywords-regexp 0) | ||
| 8009 | (vhdl-fix-case-region-1 | ||
| 8010 | beg end vhdl-upper-case-types vhdl-types-regexp 1) | ||
| 8011 | (vhdl-fix-case-region-1 | ||
| 8012 | beg end vhdl-upper-case-attributes (concat "'" vhdl-attributes-regexp) 2) | ||
| 8013 | (vhdl-fix-case-region-1 | ||
| 8014 | beg end vhdl-upper-case-enum-values vhdl-enum-values-regexp 3) | ||
| 8015 | (vhdl-fix-case-region-1 | ||
| 8016 | beg end vhdl-upper-case-constants vhdl-constants-regexp 4) | ||
| 8017 | (when vhdl-progress-interval (message "Fixing case...done"))) | ||
| 8018 | |||
| 8019 | (defun vhdl-fix-case-buffer () | ||
| 8020 | "Convert all VHDL words in buffer to lower or upper case, depending on | ||
| 8021 | options vhdl-upper-case-{keywords,types,attributes,enum-values}." | ||
| 8022 | (interactive) | ||
| 8023 | (vhdl-fix-case-region (point-min) (point-max))) | ||
| 8024 | |||
| 8025 | (defun vhdl-fix-case-word (&optional arg) | ||
| 8026 | "Convert word after cursor to upper case if necessary." | ||
| 8027 | (interactive "p") | ||
| 8028 | (save-excursion | ||
| 8029 | (when arg (backward-word 1)) | ||
| 8030 | (vhdl-prepare-search-1 | ||
| 8031 | (when (and vhdl-upper-case-keywords | ||
| 8032 | (looking-at vhdl-keywords-regexp)) | ||
| 8033 | (upcase-word 1)) | ||
| 8034 | (when (and vhdl-upper-case-types | ||
| 8035 | (looking-at vhdl-types-regexp)) | ||
| 8036 | (upcase-word 1)) | ||
| 8037 | (when (and vhdl-upper-case-attributes | ||
| 8038 | (looking-at vhdl-attributes-regexp)) | ||
| 8039 | (upcase-word 1)) | ||
| 8040 | (when (and vhdl-upper-case-enum-values | ||
| 8041 | (looking-at vhdl-enum-values-regexp)) | ||
| 8042 | (upcase-word 1)) | ||
| 8043 | (when (and vhdl-upper-case-constants | ||
| 8044 | (looking-at vhdl-constants-regexp)) | ||
| 8045 | (upcase-word 1))))) | ||
| 8046 | |||
| 8047 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 8048 | ;; Fix statements | ||
| 8049 | ;; - force each statement to be on a separate line except when on same line | ||
| 8050 | ;; with 'end' keyword | ||
| 8051 | |||
| 8052 | (defun vhdl-fix-statement-region (beg end &optional arg) | ||
| 8053 | "Force statements in region on separate line except when on same line | ||
| 8054 | with 'end' keyword (necessary for correct indentation). | ||
| 8055 | Currently supported keywords: 'begin', 'if'." | ||
| 8056 | (interactive "r\nP") | ||
| 8057 | (vhdl-prepare-search-2 | ||
| 8058 | (let (point) | ||
| 8059 | (save-excursion | ||
| 8060 | (goto-char end) | ||
| 8061 | (setq end (point-marker)) | ||
| 8062 | (goto-char beg) | ||
| 8063 | ;; `begin' keyword | ||
| 8064 | (while (re-search-forward | ||
| 8065 | "^\\s-*[^ \t\n].*?\\(\\<begin\\>\\)\\(.*\\<end\\>\\)?" end t) | ||
| 8066 | (goto-char (match-end 0)) | ||
| 8067 | (setq point (point-marker)) | ||
| 8068 | (when (and (match-string 1) | ||
| 8069 | (or (not (match-string 2)) | ||
| 8070 | (save-excursion (goto-char (match-end 2)) | ||
| 8071 | (vhdl-in-literal))) | ||
| 8072 | (not (save-excursion (goto-char (match-beginning 1)) | ||
| 8073 | (vhdl-in-literal)))) | ||
| 8074 | (goto-char (match-beginning 1)) | ||
| 8075 | (insert "\n") | ||
| 8076 | (indent-according-to-mode)) | ||
| 8077 | (goto-char point)) | ||
| 8078 | (goto-char beg) | ||
| 8079 | ;; `for', `if' keywords | ||
| 8080 | (while (re-search-forward "\\<\\(for\\|if\\)\\>" end t) | ||
| 8081 | (goto-char (match-end 1)) | ||
| 8082 | (setq point (point-marker)) | ||
| 8083 | ;; exception: in literal or preceded by `end' or label | ||
| 8084 | (when (and (not (save-excursion (goto-char (match-beginning 1)) | ||
| 8085 | (vhdl-in-literal))) | ||
| 8086 | (save-excursion | ||
| 8087 | (beginning-of-line 1) | ||
| 8088 | (save-match-data | ||
| 8089 | (and (re-search-forward "^\\s-*\\([^ \t\n].*\\)" | ||
| 8090 | (match-beginning 1) t) | ||
| 8091 | (not (string-match | ||
| 8092 | "\\(\\<end\\>\\|\\<wait\\>\\|\\w+\\s-*:\\)\\s-*$" | ||
| 8093 | (match-string 1))))))) | ||
| 8094 | (goto-char (match-beginning 1)) | ||
| 8095 | (insert "\n") | ||
| 8096 | (indent-according-to-mode)) | ||
| 8097 | (goto-char point)))))) | ||
| 8098 | |||
| 8099 | (defun vhdl-fix-statement-buffer () | ||
| 8100 | "Force statements in buffer on separate line except when on same line | ||
| 8101 | with 'end' keyword (necessary for correct indentation)." | ||
| 8102 | (interactive) | ||
| 8103 | (vhdl-fix-statement-region (point-min) (point-max))) | ||
| 8104 | |||
| 8105 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 8106 | ;; Trailing spaces | ||
| 8107 | |||
| 8108 | (defun vhdl-remove-trailing-spaces-region (beg end &optional arg) | ||
| 8109 | "Remove trailing spaces in region." | ||
| 8110 | (interactive "r\nP") | ||
| 8111 | (save-excursion | ||
| 8112 | (goto-char end) | ||
| 8113 | (setq end (point-marker)) | ||
| 8114 | (goto-char beg) | ||
| 8115 | (while (re-search-forward "[ \t]+$" end t) | ||
| 8116 | (unless (vhdl-in-literal) | ||
| 8117 | (replace-match "" nil nil))))) | ||
| 8118 | |||
| 8119 | (defun vhdl-remove-trailing-spaces () | ||
| 8120 | "Remove trailing spaces in buffer." | ||
| 8121 | (interactive) | ||
| 8122 | (vhdl-remove-trailing-spaces-region (point-min) (point-max))) | ||
| 8123 | |||
| 8124 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 7916 | ;; Beautify | 8125 | ;; Beautify |
| 7917 | 8126 | ||
| 7918 | (defun vhdl-beautify-region (beg end) | 8127 | (defun vhdl-beautify-region (beg end) |
| @@ -7922,10 +8131,17 @@ case fixing to a region. Calls functions `vhdl-indent-buffer', | |||
| 7922 | `vhdl-fix-case-buffer'." | 8131 | `vhdl-fix-case-buffer'." |
| 7923 | (interactive "r") | 8132 | (interactive "r") |
| 7924 | (setq end (save-excursion (goto-char end) (point-marker))) | 8133 | (setq end (save-excursion (goto-char end) (point-marker))) |
| 7925 | (vhdl-indent-region beg end) | 8134 | (save-excursion ; remove DOS EOL characters in UNIX file |
| 8135 | (goto-char beg) | ||
| 8136 | (while (search-forward " " nil t) | ||
| 8137 | (replace-match "" nil t))) | ||
| 8138 | (when (nth 0 vhdl-beautify-options) (vhdl-fixup-whitespace-region beg end t)) | ||
| 8139 | (when (nth 1 vhdl-beautify-options) (vhdl-fix-statement-region beg end)) | ||
| 8140 | (when (nth 2 vhdl-beautify-options) (vhdl-indent-region beg end)) | ||
| 7926 | (let ((vhdl-align-groups t)) | 8141 | (let ((vhdl-align-groups t)) |
| 7927 | (vhdl-align-region beg end)) | 8142 | (when (nth 3 vhdl-beautify-options) (vhdl-align-region beg end))) |
| 7928 | (vhdl-fix-case-region beg end)) | 8143 | (when (nth 4 vhdl-beautify-options) (vhdl-fix-case-region beg end)) |
| 8144 | (when (nth 0 vhdl-beautify-options) (vhdl-remove-trailing-spaces-region beg end))) | ||
| 7929 | 8145 | ||
| 7930 | (defun vhdl-beautify-buffer () | 8146 | (defun vhdl-beautify-buffer () |
| 7931 | "Beautify buffer by applying indentation, whitespace fixup, alignment, and | 8147 | "Beautify buffer by applying indentation, whitespace fixup, alignment, and |
| @@ -8021,7 +8237,8 @@ buffer." | |||
| 8021 | (while (re-search-forward "^\\s-*\\(\\w+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?process\\>" nil t) | 8237 | (while (re-search-forward "^\\s-*\\(\\w+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?process\\>" nil t) |
| 8022 | (goto-char (match-beginning 0)) | 8238 | (goto-char (match-beginning 0)) |
| 8023 | (condition-case nil (vhdl-update-sensitivity-list) (error ""))) | 8239 | (condition-case nil (vhdl-update-sensitivity-list) (error ""))) |
| 8024 | (message "Updating sensitivity lists...done")))) | 8240 | (message "Updating sensitivity lists...done"))) |
| 8241 | (when noninteractive (save-buffer))) | ||
| 8025 | 8242 | ||
| 8026 | (defun vhdl-update-sensitivity-list () | 8243 | (defun vhdl-update-sensitivity-list () |
| 8027 | "Update sensitivity list." | 8244 | "Update sensitivity list." |
| @@ -8047,57 +8264,57 @@ buffer." | |||
| 8047 | (scan-regions-list | 8264 | (scan-regions-list |
| 8048 | '(;; right-hand side of signal/variable assignment | 8265 | '(;; right-hand side of signal/variable assignment |
| 8049 | ;; (special case: "<=" is relational operator in a condition) | 8266 | ;; (special case: "<=" is relational operator in a condition) |
| 8050 | ((re-search-forward "[<:]=" proc-end t) | 8267 | ((vhdl-re-search-forward "[<:]=" proc-end t) |
| 8051 | (re-search-forward ";\\|\\<\\(then\\|loop\\|report\\|severity\\|is\\)\\>" proc-end t)) | 8268 | (vhdl-re-search-forward ";\\|\\<\\(then\\|loop\\|report\\|severity\\|is\\)\\>" proc-end t)) |
| 8052 | ;; if condition | 8269 | ;; if condition |
| 8053 | ((re-search-forward "^\\s-*if\\>" proc-end t) | 8270 | ((vhdl-re-search-forward "^\\s-*if\\>" proc-end t) |
| 8054 | (re-search-forward "\\<then\\>" proc-end t)) | 8271 | (vhdl-re-search-forward "\\<then\\>" proc-end t)) |
| 8055 | ;; elsif condition | 8272 | ;; elsif condition |
| 8056 | ((re-search-forward "\\<elsif\\>" proc-end t) | 8273 | ((vhdl-re-search-forward "\\<elsif\\>" proc-end t) |
| 8057 | (re-search-forward "\\<then\\>" proc-end t)) | 8274 | (vhdl-re-search-forward "\\<then\\>" proc-end t)) |
| 8058 | ;; while loop condition | 8275 | ;; while loop condition |
| 8059 | ((re-search-forward "^\\s-*while\\>" proc-end t) | 8276 | ((vhdl-re-search-forward "^\\s-*while\\>" proc-end t) |
| 8060 | (re-search-forward "\\<loop\\>" proc-end t)) | 8277 | (vhdl-re-search-forward "\\<loop\\>" proc-end t)) |
| 8061 | ;; exit/next condition | 8278 | ;; exit/next condition |
| 8062 | ((re-search-forward "\\<\\(exit\\|next\\)\\s-+\\w+\\s-+when\\>" proc-end t) | 8279 | ((vhdl-re-search-forward "\\<\\(exit\\|next\\)\\s-+\\w+\\s-+when\\>" proc-end t) |
| 8063 | (re-search-forward ";" proc-end t)) | 8280 | (vhdl-re-search-forward ";" proc-end t)) |
| 8064 | ;; assert condition | 8281 | ;; assert condition |
| 8065 | ((re-search-forward "\\<assert\\>" proc-end t) | 8282 | ((vhdl-re-search-forward "\\<assert\\>" proc-end t) |
| 8066 | (re-search-forward "\\(\\<report\\>\\|\\<severity\\>\\|;\\)" proc-end t)) | 8283 | (vhdl-re-search-forward "\\(\\<report\\>\\|\\<severity\\>\\|;\\)" proc-end t)) |
| 8067 | ;; case expression | 8284 | ;; case expression |
| 8068 | ((re-search-forward "^\\s-*case\\>" proc-end t) | 8285 | ((vhdl-re-search-forward "^\\s-*case\\>" proc-end t) |
| 8069 | (re-search-forward "\\<is\\>" proc-end t)) | 8286 | (vhdl-re-search-forward "\\<is\\>" proc-end t)) |
| 8070 | ;; parameter list of procedure call, array index | 8287 | ;; parameter list of procedure call, array index |
| 8071 | ((and (re-search-forward "^\\s-*\\(\\w\\|\\.\\)+[ \t\n\r\f]*(" proc-end t) | 8288 | ((and (re-search-forward "^\\s-*\\(\\w\\|\\.\\)+[ \t\n\r\f]*(" proc-end t) |
| 8072 | (1- (point))) | 8289 | (1- (point))) |
| 8073 | (progn (backward-char) (forward-sexp) | 8290 | (progn (backward-char) (forward-sexp) |
| 8074 | (while (looking-at "(") (forward-sexp)) (point))))) | 8291 | (while (looking-at "(") (forward-sexp)) (point))))) |
| 8075 | name field read-list sens-list signal-list | 8292 | name field read-list sens-list signal-list tmp-list |
| 8076 | sens-beg sens-end beg end margin) | 8293 | sens-beg sens-end beg end margin) |
| 8077 | ;; scan for signals in old sensitivity list | 8294 | ;; scan for signals in old sensitivity list |
| 8078 | (goto-char proc-beg) | 8295 | (goto-char proc-beg) |
| 8079 | (re-search-forward "\\<process\\>" proc-mid t) | 8296 | (vhdl-re-search-forward "\\<process\\>" proc-mid t) |
| 8080 | (if (not (looking-at "[ \t\n\r\f]*(")) | 8297 | (if (not (looking-at "[ \t\n\r\f]*(")) |
| 8081 | (setq sens-beg (point)) | 8298 | (setq sens-beg (point)) |
| 8082 | (setq sens-beg (re-search-forward "\\([ \t\n\r\f]*\\)([ \t\n\r\f]*" nil t)) | 8299 | (setq sens-beg (vhdl-re-search-forward "\\([ \t\n\r\f]*\\)([ \t\n\r\f]*" nil t)) |
| 8083 | (goto-char (match-end 1)) | 8300 | (goto-char (match-end 1)) |
| 8084 | (forward-sexp) | 8301 | (forward-sexp) |
| 8085 | (setq sens-end (1- (point))) | 8302 | (setq sens-end (1- (point))) |
| 8086 | (goto-char sens-beg) | 8303 | (goto-char sens-beg) |
| 8087 | (while (and (re-search-forward "\\(\\w+\\)" sens-end t) | 8304 | (while (and (vhdl-re-search-forward "\\(\\w+\\)" sens-end t) |
| 8088 | (setq sens-list | 8305 | (setq sens-list |
| 8089 | (cons (downcase (match-string 0)) sens-list)) | 8306 | (cons (downcase (match-string 0)) sens-list)) |
| 8090 | (re-search-forward "\\s-*,\\s-*" sens-end t)))) | 8307 | (vhdl-re-search-forward "\\s-*,\\s-*" sens-end t)))) |
| 8091 | (setq signal-list (append visible-list sens-list)) | 8308 | (setq signal-list (append visible-list sens-list)) |
| 8092 | ;; search for sequential parts | 8309 | ;; search for sequential parts |
| 8093 | (goto-char proc-mid) | 8310 | (goto-char proc-mid) |
| 8094 | (while (setq beg (re-search-forward "^\\s-*\\(els\\)?if\\>" proc-end t)) | 8311 | (while (setq beg (re-search-forward "^\\s-*\\(els\\)?if\\>" proc-end t)) |
| 8095 | (setq end (re-search-forward "\\<then\\>" proc-end t)) | 8312 | (setq end (vhdl-re-search-forward "\\<then\\>" proc-end t)) |
| 8096 | (when (re-search-backward "\\('event\\|\\<\\(falling\\|rising\\)_edge\\)\\>" beg t) | 8313 | (when (vhdl-re-search-backward "\\('event\\|\\<\\(falling\\|rising\\)_edge\\)\\>" beg t) |
| 8097 | (goto-char end) | 8314 | (goto-char end) |
| 8098 | (backward-word 1) | 8315 | (backward-word 1) |
| 8099 | (vhdl-forward-sexp) | 8316 | (vhdl-forward-sexp) |
| 8100 | (setq seq-region-list (cons (cons end (point)) seq-region-list)) | 8317 | (push (cons end (point)) seq-region-list) |
| 8101 | (beginning-of-line))) | 8318 | (beginning-of-line))) |
| 8102 | ;; scan for signals read in process | 8319 | ;; scan for signals read in process |
| 8103 | (while scan-regions-list | 8320 | (while scan-regions-list |
| @@ -8114,15 +8331,35 @@ buffer." | |||
| 8114 | (and tmp-list (< (point) (cdar tmp-list)))))) | 8331 | (and tmp-list (< (point) (cdar tmp-list)))))) |
| 8115 | (while (vhdl-re-search-forward "[^'\".]\\<\\([a-zA-Z]\\w*\\)\\(\\(\\.\\w+\\|[ \t\n\r\f]*([^)]*)\\)*\\)[ \t\n\r\f]*\\('\\(\\w+\\)\\|\\(=>\\)\\)?" end t) | 8332 | (while (vhdl-re-search-forward "[^'\".]\\<\\([a-zA-Z]\\w*\\)\\(\\(\\.\\w+\\|[ \t\n\r\f]*([^)]*)\\)*\\)[ \t\n\r\f]*\\('\\(\\w+\\)\\|\\(=>\\)\\)?" end t) |
| 8116 | (setq name (match-string 1)) | 8333 | (setq name (match-string 1)) |
| 8334 | ;; get array index range | ||
| 8117 | (when vhdl-array-index-record-field-in-sensitivity-list | 8335 | (when vhdl-array-index-record-field-in-sensitivity-list |
| 8118 | (setq field (match-string 2))) | 8336 | (setq field (match-string 2)) |
| 8337 | ;; not use if it includes a variable name | ||
| 8338 | (save-match-data | ||
| 8339 | (setq tmp-list visible-list) | ||
| 8340 | (while (and field tmp-list) | ||
| 8341 | (when (string-match | ||
| 8342 | (concat "\\<" (car tmp-list) "\\>") field) | ||
| 8343 | (setq field nil)) | ||
| 8344 | (setq tmp-list (cdr tmp-list))))) | ||
| 8119 | (when (and (not (match-string 6)) ; not when formal parameter | 8345 | (when (and (not (match-string 6)) ; not when formal parameter |
| 8120 | (not (and (match-string 5) ; not event attribute | 8346 | (not (and (match-string 5) ; not event attribute |
| 8121 | (not (member (downcase (match-string 5)) | 8347 | (not (member (downcase (match-string 5)) |
| 8122 | '("event" "last_event" "transaction"))))) | 8348 | '("event" "last_event" "transaction"))))) |
| 8123 | (member (downcase name) signal-list)) | 8349 | (member (downcase name) signal-list)) |
| 8124 | (unless (member-ignore-case (concat name field) read-list) | 8350 | ;; not add if name or name+field already exists |
| 8125 | (setq read-list (cons (concat name field) read-list)))) | 8351 | (unless |
| 8352 | (or (member-ignore-case name read-list) | ||
| 8353 | (member-ignore-case (concat name field) read-list)) | ||
| 8354 | (push (concat name field) read-list)) | ||
| 8355 | (setq tmp-list read-list) | ||
| 8356 | ;; remove existing name+field if name is added | ||
| 8357 | (save-match-data | ||
| 8358 | (while tmp-list | ||
| 8359 | (when (string-match (concat "^" name field "[(.]") | ||
| 8360 | (car tmp-list)) | ||
| 8361 | (setq read-list (delete (car tmp-list) read-list))) | ||
| 8362 | (setq tmp-list (cdr tmp-list))))) | ||
| 8126 | (goto-char (match-end 1))))) | 8363 | (goto-char (match-end 1))))) |
| 8127 | (setq scan-regions-list (cdr scan-regions-list))) | 8364 | (setq scan-regions-list (cdr scan-regions-list))) |
| 8128 | ;; update sensitivity list | 8365 | ;; update sensitivity list |
| @@ -8178,7 +8415,7 @@ buffer." | |||
| 8178 | (while (< (point) end) | 8415 | (while (< (point) end) |
| 8179 | (when (looking-at "signal[ \t\n\r\f]+") | 8416 | (when (looking-at "signal[ \t\n\r\f]+") |
| 8180 | (goto-char (match-end 0))) | 8417 | (goto-char (match-end 0))) |
| 8181 | (while (looking-at "\\(\\w+\\)[ \t\n\r\f,]+") | 8418 | (while (looking-at "\\([a-zA-Z]\\w*\\)[ \t\n\r\f,]+") |
| 8182 | (setq signal-list | 8419 | (setq signal-list |
| 8183 | (cons (downcase (match-string 1)) signal-list)) | 8420 | (cons (downcase (match-string 1)) signal-list)) |
| 8184 | (goto-char (match-end 0)) | 8421 | (goto-char (match-end 0)) |
| @@ -8197,12 +8434,12 @@ buffer." | |||
| 8197 | (when (= 0 (nth 0 (parse-partial-sexp beg (point)))) | 8434 | (when (= 0 (nth 0 (parse-partial-sexp beg (point)))) |
| 8198 | (if (match-string 2) | 8435 | (if (match-string 2) |
| 8199 | ;; scan signal name | 8436 | ;; scan signal name |
| 8200 | (while (looking-at "[ \t\n\r\f,]+\\(\\w+\\)") | 8437 | (while (looking-at "[ \t\n\r\f,]+\\([a-zA-Z]\\w*\\)") |
| 8201 | (setq signal-list | 8438 | (setq signal-list |
| 8202 | (cons (downcase (match-string 1)) signal-list)) | 8439 | (cons (downcase (match-string 1)) signal-list)) |
| 8203 | (goto-char (match-end 0))) | 8440 | (goto-char (match-end 0))) |
| 8204 | ;; scan alias name, check is alias of (declared) signal | 8441 | ;; scan alias name, check is alias of (declared) signal |
| 8205 | (when (and (looking-at "[ \t\n\r\f]+\\(\\w+\\)[^;]*\\<is[ \t\n\r\f]+\\(\\w+\\)") | 8442 | (when (and (looking-at "[ \t\n\r\f]+\\([a-zA-Z]\\w*\\)[^;]*\\<is[ \t\n\r\f]+\\([a-zA-Z]\\w*\\)") |
| 8206 | (member (downcase (match-string 2)) signal-list)) | 8443 | (member (downcase (match-string 2)) signal-list)) |
| 8207 | (setq signal-list | 8444 | (setq signal-list |
| 8208 | (cons (downcase (match-string 1)) signal-list)) | 8445 | (cons (downcase (match-string 1)) signal-list)) |
| @@ -8290,19 +8527,6 @@ buffer." | |||
| 8290 | (goto-char end) | 8527 | (goto-char end) |
| 8291 | (insert ")"))))))) | 8528 | (insert ")"))))))) |
| 8292 | 8529 | ||
| 8293 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 8294 | ;; Miscellaneous | ||
| 8295 | |||
| 8296 | (defun vhdl-remove-trailing-spaces () | ||
| 8297 | "Remove trailing spaces in the whole buffer." | ||
| 8298 | (interactive) | ||
| 8299 | (save-match-data | ||
| 8300 | (save-excursion | ||
| 8301 | (goto-char (point-min)) | ||
| 8302 | (while (re-search-forward "[ \t]+$" (point-max) t) | ||
| 8303 | (unless (vhdl-in-literal) | ||
| 8304 | (replace-match "" nil nil)))))) | ||
| 8305 | |||
| 8306 | 8530 | ||
| 8307 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 8531 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 8308 | ;;; Electrification | 8532 | ;;; Electrification |
| @@ -8334,14 +8558,14 @@ project is defined." | |||
| 8334 | With a prefix argument ARG, enable the mode if ARG is positive, | 8558 | With a prefix argument ARG, enable the mode if ARG is positive, |
| 8335 | and disable it otherwise. If called from Lisp, enable it if ARG | 8559 | and disable it otherwise. If called from Lisp, enable it if ARG |
| 8336 | is omitted or nil." | 8560 | is omitted or nil." |
| 8337 | :global t) | 8561 | :global t :group 'vhdl-mode) |
| 8338 | 8562 | ||
| 8339 | (define-minor-mode vhdl-stutter-mode | 8563 | (define-minor-mode vhdl-stutter-mode |
| 8340 | "Toggle VHDL stuttering mode. | 8564 | "Toggle VHDL stuttering mode. |
| 8341 | With a prefix argument ARG, enable the mode if ARG is positive, | 8565 | With a prefix argument ARG, enable the mode if ARG is positive, |
| 8342 | and disable it otherwise. If called from Lisp, enable it if ARG | 8566 | and disable it otherwise. If called from Lisp, enable it if ARG |
| 8343 | is omitted or nil." | 8567 | is omitted or nil." |
| 8344 | :global t) | 8568 | :global t :group 'vhdl-mode) |
| 8345 | 8569 | ||
| 8346 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 8570 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 8347 | ;; Stuttering | 8571 | ;; Stuttering |
| @@ -8398,7 +8622,7 @@ is omitted or nil." | |||
| 8398 | (defun vhdl-electric-quote (count) "'' --> \"" | 8622 | (defun vhdl-electric-quote (count) "'' --> \"" |
| 8399 | (interactive "p") | 8623 | (interactive "p") |
| 8400 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) | 8624 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) |
| 8401 | (if (= (preceding-char) last-input-event) | 8625 | (if (= (preceding-char) vhdl-last-input-event) |
| 8402 | (progn (delete-char -1) (insert-char ?\" 1)) | 8626 | (progn (delete-char -1) (insert-char ?\" 1)) |
| 8403 | (insert-char ?\' 1)) | 8627 | (insert-char ?\' 1)) |
| 8404 | (self-insert-command count))) | 8628 | (self-insert-command count))) |
| @@ -8406,7 +8630,7 @@ is omitted or nil." | |||
| 8406 | (defun vhdl-electric-semicolon (count) "';;' --> ' : ', ': ;' --> ' := '" | 8630 | (defun vhdl-electric-semicolon (count) "';;' --> ' : ', ': ;' --> ' := '" |
| 8407 | (interactive "p") | 8631 | (interactive "p") |
| 8408 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) | 8632 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) |
| 8409 | (cond ((= (preceding-char) last-input-event) | 8633 | (cond ((= (preceding-char) vhdl-last-input-event) |
| 8410 | (progn (delete-char -1) | 8634 | (progn (delete-char -1) |
| 8411 | (unless (eq (preceding-char) ? ) (insert " ")) | 8635 | (unless (eq (preceding-char) ? ) (insert " ")) |
| 8412 | (insert ": ") | 8636 | (insert ": ") |
| @@ -8420,7 +8644,7 @@ is omitted or nil." | |||
| 8420 | (defun vhdl-electric-comma (count) "',,' --> ' <= '" | 8644 | (defun vhdl-electric-comma (count) "',,' --> ' <= '" |
| 8421 | (interactive "p") | 8645 | (interactive "p") |
| 8422 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) | 8646 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) |
| 8423 | (cond ((= (preceding-char) last-input-event) | 8647 | (cond ((= (preceding-char) vhdl-last-input-event) |
| 8424 | (progn (delete-char -1) | 8648 | (progn (delete-char -1) |
| 8425 | (unless (eq (preceding-char) ? ) (insert " ")) | 8649 | (unless (eq (preceding-char) ? ) (insert " ")) |
| 8426 | (insert "<= "))) | 8650 | (insert "<= "))) |
| @@ -8430,7 +8654,7 @@ is omitted or nil." | |||
| 8430 | (defun vhdl-electric-period (count) "'..' --> ' => '" | 8654 | (defun vhdl-electric-period (count) "'..' --> ' => '" |
| 8431 | (interactive "p") | 8655 | (interactive "p") |
| 8432 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) | 8656 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) |
| 8433 | (cond ((= (preceding-char) last-input-event) | 8657 | (cond ((= (preceding-char) vhdl-last-input-event) |
| 8434 | (progn (delete-char -1) | 8658 | (progn (delete-char -1) |
| 8435 | (unless (eq (preceding-char) ? ) (insert " ")) | 8659 | (unless (eq (preceding-char) ? ) (insert " ")) |
| 8436 | (insert "=> "))) | 8660 | (insert "=> "))) |
| @@ -8440,7 +8664,7 @@ is omitted or nil." | |||
| 8440 | (defun vhdl-electric-equal (count) "'==' --> ' == '" | 8664 | (defun vhdl-electric-equal (count) "'==' --> ' == '" |
| 8441 | (interactive "p") | 8665 | (interactive "p") |
| 8442 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) | 8666 | (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal))) |
| 8443 | (cond ((= (preceding-char) last-input-event) | 8667 | (cond ((= (preceding-char) vhdl-last-input-event) |
| 8444 | (progn (delete-char -1) | 8668 | (progn (delete-char -1) |
| 8445 | (unless (eq (preceding-char) ? ) (insert " ")) | 8669 | (unless (eq (preceding-char) ? ) (insert " ")) |
| 8446 | (insert "== "))) | 8670 | (insert "== "))) |
| @@ -8711,12 +8935,13 @@ since these are almost equivalent)." | |||
| 8711 | "[COMPONENT | ENTITY | CONFIGURATION]" " " t)) | 8935 | "[COMPONENT | ENTITY | CONFIGURATION]" " " t)) |
| 8712 | (setq unit (upcase (or unit ""))) | 8936 | (setq unit (upcase (or unit ""))) |
| 8713 | (cond ((equal unit "ENTITY") | 8937 | (cond ((equal unit "ENTITY") |
| 8714 | (vhdl-template-field "library name" "." nil nil nil nil | 8938 | (let ((begin (point))) |
| 8939 | (vhdl-template-field "library name" "." t begin (point) nil | ||
| 8715 | (vhdl-work-library)) | 8940 | (vhdl-work-library)) |
| 8716 | (vhdl-template-field "entity name" "(") | 8941 | (vhdl-template-field "entity name" "(") |
| 8717 | (if (vhdl-template-field "[architecture name]" nil t) | 8942 | (if (vhdl-template-field "[architecture name]" nil t) |
| 8718 | (insert ")") | 8943 | (insert ")") |
| 8719 | (delete-char -1))) | 8944 | (delete-char -1)))) |
| 8720 | ((equal unit "CONFIGURATION") | 8945 | ((equal unit "CONFIGURATION") |
| 8721 | (vhdl-template-field "library name" "." nil nil nil nil | 8946 | (vhdl-template-field "library name" "." nil nil nil nil |
| 8722 | (vhdl-work-library)) | 8947 | (vhdl-work-library)) |
| @@ -9852,7 +10077,7 @@ otherwise." | |||
| 9852 | (let ((definition | 10077 | (let ((definition |
| 9853 | (upcase | 10078 | (upcase |
| 9854 | (or (vhdl-template-field | 10079 | (or (vhdl-template-field |
| 9855 | "[scalar type | ARRAY | RECORD | ACCESS | FILE]" nil t) | 10080 | "[scalar type | ARRAY | RECORD | ACCESS | FILE | ENUM]" nil t) |
| 9856 | "")))) | 10081 | "")))) |
| 9857 | (cond ((equal definition "") | 10082 | (cond ((equal definition "") |
| 9858 | (delete-char -4) | 10083 | (delete-char -4) |
| @@ -9870,6 +10095,11 @@ otherwise." | |||
| 9870 | ((equal definition "FILE") | 10095 | ((equal definition "FILE") |
| 9871 | (vhdl-insert-keyword " OF ") | 10096 | (vhdl-insert-keyword " OF ") |
| 9872 | (vhdl-template-field "type" ";")) | 10097 | (vhdl-template-field "type" ";")) |
| 10098 | ((equal definition "ENUM") | ||
| 10099 | (kill-word -1) | ||
| 10100 | (insert "(") | ||
| 10101 | (setq end-pos (point-marker)) | ||
| 10102 | (insert ");")) | ||
| 9873 | (t (insert ";"))) | 10103 | (t (insert ";"))) |
| 9874 | (when mid-pos | 10104 | (when mid-pos |
| 9875 | (setq end-pos (point-marker)) | 10105 | (setq end-pos (point-marker)) |
| @@ -10916,7 +11146,7 @@ but not if inside a comment or quote." | |||
| 10916 | (backward-word 1) | 11146 | (backward-word 1) |
| 10917 | (vhdl-case-word 1) | 11147 | (vhdl-case-word 1) |
| 10918 | (delete-char 1)) | 11148 | (delete-char 1)) |
| 10919 | (let ((invoke-char last-command-event) | 11149 | (let ((invoke-char vhdl-last-input-event) |
| 10920 | (abbrev-mode -1) | 11150 | (abbrev-mode -1) |
| 10921 | (vhdl-template-invoked-by-hook t)) | 11151 | (vhdl-template-invoked-by-hook t)) |
| 10922 | (let ((caught (catch 'abort | 11152 | (let ((caught (catch 'abort |
| @@ -11640,7 +11870,8 @@ reflected in a subsequent paste operation." | |||
| 11640 | ;; paste formal and actual generic | 11870 | ;; paste formal and actual generic |
| 11641 | (insert (car (nth 0 generic)) " => " | 11871 | (insert (car (nth 0 generic)) " => " |
| 11642 | (if no-constants | 11872 | (if no-constants |
| 11643 | (car (nth 0 generic)) | 11873 | (vhdl-replace-string vhdl-actual-generic-name |
| 11874 | (car (nth 0 generic))) | ||
| 11644 | (or (nth 2 generic) ""))) | 11875 | (or (nth 2 generic) ""))) |
| 11645 | (setq generic-list (cdr generic-list)) | 11876 | (setq generic-list (cdr generic-list)) |
| 11646 | (insert (if generic-list "," ")")) | 11877 | (insert (if generic-list "," ")")) |
| @@ -11783,7 +12014,7 @@ reflected in a subsequent paste operation." | |||
| 11783 | ;; paste generic constants | 12014 | ;; paste generic constants |
| 11784 | (setq name (nth 0 generic)) | 12015 | (setq name (nth 0 generic)) |
| 11785 | (when name | 12016 | (when name |
| 11786 | (insert (car name)) | 12017 | (insert (vhdl-replace-string vhdl-actual-generic-name (car name))) |
| 11787 | ;; paste type | 12018 | ;; paste type |
| 11788 | (insert " : " (nth 1 generic)) | 12019 | (insert " : " (nth 1 generic)) |
| 11789 | ;; paste initialization | 12020 | ;; paste initialization |
| @@ -11809,7 +12040,7 @@ reflected in a subsequent paste operation." | |||
| 11809 | (message "Pasting port as signals...") | 12040 | (message "Pasting port as signals...") |
| 11810 | (unless no-indent (indent-according-to-mode)) | 12041 | (unless no-indent (indent-according-to-mode)) |
| 11811 | (let ((margin (current-indentation)) | 12042 | (let ((margin (current-indentation)) |
| 11812 | start port names | 12043 | start port names type generic-list port-name constant-name pos |
| 11813 | (port-list (nth 2 vhdl-port-list))) | 12044 | (port-list (nth 2 vhdl-port-list))) |
| 11814 | (when port-list | 12045 | (when port-list |
| 11815 | (setq start (point)) | 12046 | (setq start (point)) |
| @@ -11829,7 +12060,21 @@ reflected in a subsequent paste operation." | |||
| 11829 | (setq names (cdr names)) | 12060 | (setq names (cdr names)) |
| 11830 | (when names (insert ", "))) | 12061 | (when names (insert ", "))) |
| 11831 | ;; paste type | 12062 | ;; paste type |
| 11832 | (insert " : " (nth 3 port)) | 12063 | (setq type (nth 3 port)) |
| 12064 | (setq generic-list (nth 1 vhdl-port-list)) | ||
| 12065 | (vhdl-prepare-search-1 | ||
| 12066 | (setq pos 0) | ||
| 12067 | ;; replace formal by actual generics | ||
| 12068 | (while generic-list | ||
| 12069 | (setq port-name (car (nth 0 (car generic-list)))) | ||
| 12070 | (while (string-match (concat "\\<" port-name "\\>") type pos) | ||
| 12071 | (setq constant-name | ||
| 12072 | (save-match-data (vhdl-replace-string | ||
| 12073 | vhdl-actual-generic-name port-name))) | ||
| 12074 | (setq type (replace-match constant-name t nil type)) | ||
| 12075 | (setq pos (match-end 0))) | ||
| 12076 | (setq generic-list (cdr generic-list)))) | ||
| 12077 | (insert " : " type) | ||
| 11833 | ;; paste initialization (inputs only) | 12078 | ;; paste initialization (inputs only) |
| 11834 | (when (and initialize (nth 2 port) (equal "IN" (upcase (nth 2 port)))) | 12079 | (when (and initialize (nth 2 port) (equal "IN" (upcase (nth 2 port)))) |
| 11835 | (insert " := " | 12080 | (insert " := " |
| @@ -12418,77 +12663,6 @@ expressions (e.g. for index ranges of types and signals)." | |||
| 12418 | try-expand-list-all-buffers))) | 12663 | try-expand-list-all-buffers))) |
| 12419 | 12664 | ||
| 12420 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 12665 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 12421 | ;; Case fixing | ||
| 12422 | |||
| 12423 | (defun vhdl-fix-case-region-1 (beg end upper-case word-regexp &optional count) | ||
| 12424 | "Convert all words matching WORD-REGEXP in region to lower or upper case, | ||
| 12425 | depending on parameter UPPER-CASE." | ||
| 12426 | (let ((case-replace nil) | ||
| 12427 | (last-update 0)) | ||
| 12428 | (vhdl-prepare-search-2 | ||
| 12429 | (save-excursion | ||
| 12430 | (goto-char end) | ||
| 12431 | (setq end (point-marker)) | ||
| 12432 | (goto-char beg) | ||
| 12433 | (while (re-search-forward word-regexp end t) | ||
| 12434 | (or (vhdl-in-literal) | ||
| 12435 | (if upper-case | ||
| 12436 | (upcase-word -1) | ||
| 12437 | (downcase-word -1))) | ||
| 12438 | (when (and count vhdl-progress-interval (not noninteractive) | ||
| 12439 | (< vhdl-progress-interval | ||
| 12440 | (- (nth 1 (current-time)) last-update))) | ||
| 12441 | (message "Fixing case... (%2d%s)" | ||
| 12442 | (+ (* count 20) (/ (* 20 (- (point) beg)) (- end beg))) | ||
| 12443 | "%") | ||
| 12444 | (setq last-update (nth 1 (current-time))))) | ||
| 12445 | (goto-char end))))) | ||
| 12446 | |||
| 12447 | (defun vhdl-fix-case-region (beg end &optional arg) | ||
| 12448 | "Convert all VHDL words in region to lower or upper case, depending on | ||
| 12449 | options vhdl-upper-case-{keywords,types,attributes,enum-values}." | ||
| 12450 | (interactive "r\nP") | ||
| 12451 | (vhdl-fix-case-region-1 | ||
| 12452 | beg end vhdl-upper-case-keywords vhdl-keywords-regexp 0) | ||
| 12453 | (vhdl-fix-case-region-1 | ||
| 12454 | beg end vhdl-upper-case-types vhdl-types-regexp 1) | ||
| 12455 | (vhdl-fix-case-region-1 | ||
| 12456 | beg end vhdl-upper-case-attributes (concat "'" vhdl-attributes-regexp) 2) | ||
| 12457 | (vhdl-fix-case-region-1 | ||
| 12458 | beg end vhdl-upper-case-enum-values vhdl-enum-values-regexp 3) | ||
| 12459 | (vhdl-fix-case-region-1 | ||
| 12460 | beg end vhdl-upper-case-constants vhdl-constants-regexp 4) | ||
| 12461 | (when vhdl-progress-interval (message "Fixing case...done"))) | ||
| 12462 | |||
| 12463 | (defun vhdl-fix-case-buffer () | ||
| 12464 | "Convert all VHDL words in buffer to lower or upper case, depending on | ||
| 12465 | options vhdl-upper-case-{keywords,types,attributes,enum-values}." | ||
| 12466 | (interactive) | ||
| 12467 | (vhdl-fix-case-region (point-min) (point-max))) | ||
| 12468 | |||
| 12469 | (defun vhdl-fix-case-word (&optional arg) | ||
| 12470 | "Convert word after cursor to upper case if necessary." | ||
| 12471 | (interactive "p") | ||
| 12472 | (save-excursion | ||
| 12473 | (when arg (backward-word 1)) | ||
| 12474 | (vhdl-prepare-search-1 | ||
| 12475 | (when (and vhdl-upper-case-keywords | ||
| 12476 | (looking-at vhdl-keywords-regexp)) | ||
| 12477 | (upcase-word 1)) | ||
| 12478 | (when (and vhdl-upper-case-types | ||
| 12479 | (looking-at vhdl-types-regexp)) | ||
| 12480 | (upcase-word 1)) | ||
| 12481 | (when (and vhdl-upper-case-attributes | ||
| 12482 | (looking-at vhdl-attributes-regexp)) | ||
| 12483 | (upcase-word 1)) | ||
| 12484 | (when (and vhdl-upper-case-enum-values | ||
| 12485 | (looking-at vhdl-enum-values-regexp)) | ||
| 12486 | (upcase-word 1)) | ||
| 12487 | (when (and vhdl-upper-case-constants | ||
| 12488 | (looking-at vhdl-constants-regexp)) | ||
| 12489 | (upcase-word 1))))) | ||
| 12490 | |||
| 12491 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 12492 | ;; Line handling functions | 12666 | ;; Line handling functions |
| 12493 | 12667 | ||
| 12494 | (defun vhdl-current-line () | 12668 | (defun vhdl-current-line () |
| @@ -12642,7 +12816,7 @@ it works within comments too." | |||
| 12642 | ;; print results | 12816 | ;; print results |
| 12643 | (message "\n\ | 12817 | (message "\n\ |
| 12644 | File statistics: \"%s\"\n\ | 12818 | File statistics: \"%s\"\n\ |
| 12645 | ---------------------\n\ | 12819 | -----------------------\n\ |
| 12646 | # statements : %5d\n\ | 12820 | # statements : %5d\n\ |
| 12647 | # code lines : %5d\n\ | 12821 | # code lines : %5d\n\ |
| 12648 | # empty lines : %5d\n\ | 12822 | # empty lines : %5d\n\ |
| @@ -13493,9 +13667,9 @@ hierarchy otherwise.") | |||
| 13493 | (while (and (re-search-backward "^[ \t]*\\(end\\|use\\)\\>" nil t) | 13667 | (while (and (re-search-backward "^[ \t]*\\(end\\|use\\)\\>" nil t) |
| 13494 | (equal "USE" (upcase (match-string 1)))) | 13668 | (equal "USE" (upcase (match-string 1)))) |
| 13495 | (when (looking-at "^[ \t]*use[ \t\n\r\f]*\\(\\w+\\)\\.\\(\\w+\\)\\.\\w+") | 13669 | (when (looking-at "^[ \t]*use[ \t\n\r\f]*\\(\\w+\\)\\.\\(\\w+\\)\\.\\w+") |
| 13496 | (setq lib-alist (cons (cons (match-string-no-properties 1) | 13670 | (push (cons (match-string-no-properties 1) |
| 13497 | (vhdl-match-string-downcase 2)) | 13671 | (vhdl-match-string-downcase 2)) |
| 13498 | lib-alist)))))) | 13672 | lib-alist))))) |
| 13499 | lib-alist)) | 13673 | lib-alist)) |
| 13500 | 13674 | ||
| 13501 | (defun vhdl-scan-directory-contents (name &optional project update num-string | 13675 | (defun vhdl-scan-directory-contents (name &optional project update num-string |
| @@ -13541,7 +13715,7 @@ hierarchy otherwise.") | |||
| 13541 | file-tmp-list) | 13715 | file-tmp-list) |
| 13542 | (while file-list | 13716 | (while file-list |
| 13543 | (unless (string-match file-exclude-regexp (car file-list)) | 13717 | (unless (string-match file-exclude-regexp (car file-list)) |
| 13544 | (setq file-tmp-list (cons (car file-list) file-tmp-list))) | 13718 | (push (car file-list) file-tmp-list)) |
| 13545 | (setq file-list (cdr file-list))) | 13719 | (setq file-list (cdr file-list))) |
| 13546 | (setq file-list (nreverse file-tmp-list)))) | 13720 | (setq file-list (nreverse file-tmp-list)))) |
| 13547 | ;; do for all files | 13721 | ;; do for all files |
| @@ -13576,7 +13750,7 @@ hierarchy otherwise.") | |||
| 13576 | "Entity declared twice (used 1.): \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)" | 13750 | "Entity declared twice (used 1.): \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)" |
| 13577 | ent-name (nth 1 ent-entry) (nth 2 ent-entry) | 13751 | ent-name (nth 1 ent-entry) (nth 2 ent-entry) |
| 13578 | file-name (vhdl-current-line)) | 13752 | file-name (vhdl-current-line)) |
| 13579 | (setq ent-list (cons ent-key ent-list)) | 13753 | (push ent-key ent-list) |
| 13580 | (aput 'ent-alist ent-key | 13754 | (aput 'ent-alist ent-key |
| 13581 | (list ent-name file-name (vhdl-current-line) | 13755 | (list ent-name file-name (vhdl-current-line) |
| 13582 | (nth 3 ent-entry) (nth 4 ent-entry) | 13756 | (nth 3 ent-entry) (nth 4 ent-entry) |
| @@ -13628,7 +13802,7 @@ hierarchy otherwise.") | |||
| 13628 | "Configuration declared twice (used 1.): \"%s\" of \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)" | 13802 | "Configuration declared twice (used 1.): \"%s\" of \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)" |
| 13629 | conf-name ent-name (nth 1 conf-entry) | 13803 | conf-name ent-name (nth 1 conf-entry) |
| 13630 | (nth 2 conf-entry) file-name conf-line) | 13804 | (nth 2 conf-entry) file-name conf-line) |
| 13631 | (setq conf-list (cons conf-key conf-list)) | 13805 | (push conf-key conf-list) |
| 13632 | ;; scan for subconfigurations and subentities | 13806 | ;; scan for subconfigurations and subentities |
| 13633 | (while (re-search-forward "^[ \t]*for[ \t\n\r\f]+\\(\\w+\\([ \t\n\r\f]*,[ \t\n\r\f]*\\w+\\)*\\)[ \t\n\r\f]*:[ \t\n\r\f]*\\(\\w+\\)[ \t\n\r\f]+" end-of-unit t) | 13807 | (while (re-search-forward "^[ \t]*for[ \t\n\r\f]+\\(\\w+\\([ \t\n\r\f]*,[ \t\n\r\f]*\\w+\\)*\\)[ \t\n\r\f]*:[ \t\n\r\f]*\\(\\w+\\)[ \t\n\r\f]+" end-of-unit t) |
| 13634 | (setq inst-comp-key (vhdl-match-string-downcase 3) | 13808 | (setq inst-comp-key (vhdl-match-string-downcase 3) |
| @@ -13691,8 +13865,8 @@ hierarchy otherwise.") | |||
| 13691 | (setq func-alist (nreverse func-alist)) | 13865 | (setq func-alist (nreverse func-alist)) |
| 13692 | (setq comp-alist (nreverse comp-alist)) | 13866 | (setq comp-alist (nreverse comp-alist)) |
| 13693 | (if is-body | 13867 | (if is-body |
| 13694 | (setq pack-body-list (cons pack-key pack-body-list)) | 13868 | (push pack-key pack-body-list) |
| 13695 | (setq pack-list (cons pack-key pack-list))) | 13869 | (push pack-key pack-list)) |
| 13696 | (aput | 13870 | (aput |
| 13697 | 'pack-alist pack-key | 13871 | 'pack-alist pack-key |
| 13698 | (if is-body | 13872 | (if is-body |
| @@ -13946,7 +14120,7 @@ of PROJECT." | |||
| 13946 | (let ((case-fold-search nil)) | 14120 | (let ((case-fold-search nil)) |
| 13947 | (while dir-list | 14121 | (while dir-list |
| 13948 | (unless (string-match file-exclude-regexp (car dir-list)) | 14122 | (unless (string-match file-exclude-regexp (car dir-list)) |
| 13949 | (setq dir-list-tmp (cons (car dir-list) dir-list-tmp))) | 14123 | (push (car dir-list) dir-list-tmp)) |
| 13950 | (setq dir-list (cdr dir-list))) | 14124 | (setq dir-list (cdr dir-list))) |
| 13951 | (setq dir-list (nreverse dir-list-tmp)))) | 14125 | (setq dir-list (nreverse dir-list-tmp)))) |
| 13952 | (message "Collecting source files...done") | 14126 | (message "Collecting source files...done") |
| @@ -14338,12 +14512,19 @@ if required." | |||
| 14338 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 14512 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 14339 | ;; Add hierarchy browser functionality to speedbar | 14513 | ;; Add hierarchy browser functionality to speedbar |
| 14340 | 14514 | ||
| 14341 | (defvar vhdl-speedbar-key-map nil | 14515 | (defvar vhdl-speedbar-mode-map nil |
| 14342 | "Keymap used when in the VHDL hierarchy browser mode.") | 14516 | "Keymap used when in the VHDL hierarchy browser mode.") |
| 14343 | 14517 | ||
| 14344 | (defvar vhdl-speedbar-menu-items nil | 14518 | (defvar vhdl-speedbar-menu-items nil |
| 14345 | "Additional menu-items to add to speedbar frame.") | 14519 | "Additional menu-items to add to speedbar frame.") |
| 14346 | 14520 | ||
| 14521 | (declare-function speedbar-add-supported-extension "speedbar" (extension)) | ||
| 14522 | (declare-function speedbar-add-mode-functions-list "speedbar" (new-list)) | ||
| 14523 | (declare-function speedbar-make-specialized-keymap "speedbar" ()) | ||
| 14524 | (declare-function speedbar-change-initial-expansion-list "speedbar" | ||
| 14525 | (new-default)) | ||
| 14526 | (declare-function speedbar-add-expansion-list "speedbar" (new-list)) | ||
| 14527 | |||
| 14347 | (defun vhdl-speedbar-initialize () | 14528 | (defun vhdl-speedbar-initialize () |
| 14348 | "Initialize speedbar." | 14529 | "Initialize speedbar." |
| 14349 | ;; general settings | 14530 | ;; general settings |
| @@ -14366,24 +14547,24 @@ if required." | |||
| 14366 | (speedbar-item-info . vhdl-speedbar-item-info) | 14547 | (speedbar-item-info . vhdl-speedbar-item-info) |
| 14367 | (speedbar-line-directory . vhdl-speedbar-line-project))) | 14548 | (speedbar-line-directory . vhdl-speedbar-line-project))) |
| 14368 | ;; keymap | 14549 | ;; keymap |
| 14369 | (unless vhdl-speedbar-key-map | 14550 | (unless vhdl-speedbar-mode-map |
| 14370 | (setq vhdl-speedbar-key-map (speedbar-make-specialized-keymap)) | 14551 | (setq vhdl-speedbar-mode-map (speedbar-make-specialized-keymap)) |
| 14371 | (define-key vhdl-speedbar-key-map "e" 'speedbar-edit-line) | 14552 | (define-key vhdl-speedbar-mode-map "e" 'speedbar-edit-line) |
| 14372 | (define-key vhdl-speedbar-key-map "\C-m" 'speedbar-edit-line) | 14553 | (define-key vhdl-speedbar-mode-map "\C-m" 'speedbar-edit-line) |
| 14373 | (define-key vhdl-speedbar-key-map "+" 'speedbar-expand-line) | 14554 | (define-key vhdl-speedbar-mode-map "+" 'speedbar-expand-line) |
| 14374 | (define-key vhdl-speedbar-key-map "=" 'speedbar-expand-line) | 14555 | (define-key vhdl-speedbar-mode-map "=" 'speedbar-expand-line) |
| 14375 | (define-key vhdl-speedbar-key-map "-" 'vhdl-speedbar-contract-level) | 14556 | (define-key vhdl-speedbar-mode-map "-" 'vhdl-speedbar-contract-level) |
| 14376 | (define-key vhdl-speedbar-key-map "_" 'vhdl-speedbar-contract-all) | 14557 | (define-key vhdl-speedbar-mode-map "_" 'vhdl-speedbar-contract-all) |
| 14377 | (define-key vhdl-speedbar-key-map "C" 'vhdl-speedbar-port-copy) | 14558 | (define-key vhdl-speedbar-mode-map "C" 'vhdl-speedbar-port-copy) |
| 14378 | (define-key vhdl-speedbar-key-map "P" 'vhdl-speedbar-place-component) | 14559 | (define-key vhdl-speedbar-mode-map "P" 'vhdl-speedbar-place-component) |
| 14379 | (define-key vhdl-speedbar-key-map "F" 'vhdl-speedbar-configuration) | 14560 | (define-key vhdl-speedbar-mode-map "F" 'vhdl-speedbar-configuration) |
| 14380 | (define-key vhdl-speedbar-key-map "A" 'vhdl-speedbar-select-mra) | 14561 | (define-key vhdl-speedbar-mode-map "A" 'vhdl-speedbar-select-mra) |
| 14381 | (define-key vhdl-speedbar-key-map "K" 'vhdl-speedbar-make-design) | 14562 | (define-key vhdl-speedbar-mode-map "K" 'vhdl-speedbar-make-design) |
| 14382 | (define-key vhdl-speedbar-key-map "R" 'vhdl-speedbar-rescan-hierarchy) | 14563 | (define-key vhdl-speedbar-mode-map "R" 'vhdl-speedbar-rescan-hierarchy) |
| 14383 | (define-key vhdl-speedbar-key-map "S" 'vhdl-save-caches) | 14564 | (define-key vhdl-speedbar-mode-map "S" 'vhdl-save-caches) |
| 14384 | (let ((key 0)) | 14565 | (let ((key 0)) |
| 14385 | (while (<= key 9) | 14566 | (while (<= key 9) |
| 14386 | (define-key vhdl-speedbar-key-map (int-to-string key) | 14567 | (define-key vhdl-speedbar-mode-map (int-to-string key) |
| 14387 | `(lambda () (interactive) (vhdl-speedbar-set-depth ,key))) | 14568 | `(lambda () (interactive) (vhdl-speedbar-set-depth ,key))) |
| 14388 | (setq key (1+ key))))) | 14569 | (setq key (1+ key))))) |
| 14389 | (define-key speedbar-mode-map "h" | 14570 | (define-key speedbar-mode-map "h" |
| @@ -14436,10 +14617,10 @@ if required." | |||
| 14436 | ["Save Caches" vhdl-save-caches vhdl-updated-project-list]))) | 14617 | ["Save Caches" vhdl-save-caches vhdl-updated-project-list]))) |
| 14437 | ;; hook-ups | 14618 | ;; hook-ups |
| 14438 | (speedbar-add-expansion-list | 14619 | (speedbar-add-expansion-list |
| 14439 | '("vhdl directory" vhdl-speedbar-menu-items vhdl-speedbar-key-map | 14620 | '("vhdl directory" vhdl-speedbar-menu-items vhdl-speedbar-mode-map |
| 14440 | vhdl-speedbar-display-directory)) | 14621 | vhdl-speedbar-display-directory)) |
| 14441 | (speedbar-add-expansion-list | 14622 | (speedbar-add-expansion-list |
| 14442 | '("vhdl project" vhdl-speedbar-menu-items vhdl-speedbar-key-map | 14623 | '("vhdl project" vhdl-speedbar-menu-items vhdl-speedbar-mode-map |
| 14443 | vhdl-speedbar-display-projects)) | 14624 | vhdl-speedbar-display-projects)) |
| 14444 | (setq speedbar-stealthy-function-list | 14625 | (setq speedbar-stealthy-function-list |
| 14445 | (append | 14626 | (append |
| @@ -14473,11 +14654,15 @@ if required." | |||
| 14473 | "Name of last selected project.") | 14654 | "Name of last selected project.") |
| 14474 | 14655 | ||
| 14475 | ;; macros must be defined in the file they are used (copied from `speedbar.el') | 14656 | ;; macros must be defined in the file they are used (copied from `speedbar.el') |
| 14476 | (defmacro speedbar-with-writable (&rest forms) | 14657 | ;;; (defmacro speedbar-with-writable (&rest forms) |
| 14477 | "Allow the buffer to be writable and evaluate FORMS." | 14658 | ;;; "Allow the buffer to be writable and evaluate FORMS." |
| 14478 | (list 'let '((inhibit-read-only t)) | 14659 | ;;; (list 'let '((inhibit-read-only t)) |
| 14479 | (cons 'progn forms))) | 14660 | ;;; (cons 'progn forms))) |
| 14480 | (put 'speedbar-with-writable 'lisp-indent-function 0) | 14661 | ;;; (put 'speedbar-with-writable 'lisp-indent-function 0) |
| 14662 | |||
| 14663 | (declare-function speedbar-extension-list-to-regex "speedbar" (extlist)) | ||
| 14664 | (declare-function speedbar-directory-buttons "speedbar" (directory _index)) | ||
| 14665 | (declare-function speedbar-file-lists "speedbar" (directory)) | ||
| 14481 | 14666 | ||
| 14482 | (defun vhdl-speedbar-display-directory (directory depth &optional rescan) | 14667 | (defun vhdl-speedbar-display-directory (directory depth &optional rescan) |
| 14483 | "Display directory and hierarchy information in speedbar." | 14668 | "Display directory and hierarchy information in speedbar." |
| @@ -14513,6 +14698,9 @@ if required." | |||
| 14513 | (error (vhdl-warning-when-idle "ERROR: Invalid hierarchy information, unable to display correctly")))) | 14698 | (error (vhdl-warning-when-idle "ERROR: Invalid hierarchy information, unable to display correctly")))) |
| 14514 | (setq speedbar-full-text-cache nil)) ; prevent caching | 14699 | (setq speedbar-full-text-cache nil)) ; prevent caching |
| 14515 | 14700 | ||
| 14701 | (declare-function speedbar-make-tag-line "speedbar" | ||
| 14702 | (type char func data tag tfunc tdata tface depth)) | ||
| 14703 | |||
| 14516 | (defun vhdl-speedbar-insert-projects () | 14704 | (defun vhdl-speedbar-insert-projects () |
| 14517 | "Insert all projects in speedbar." | 14705 | "Insert all projects in speedbar." |
| 14518 | (vhdl-speedbar-make-title-line "Projects:") | 14706 | (vhdl-speedbar-make-title-line "Projects:") |
| @@ -14616,6 +14804,8 @@ otherwise use cached data." | |||
| 14616 | depth) | 14804 | depth) |
| 14617 | (setq pack-alist (cdr pack-alist)))))) | 14805 | (setq pack-alist (cdr pack-alist)))))) |
| 14618 | 14806 | ||
| 14807 | (declare-function speedbar-line-directory "speedbar" (&optional depth)) | ||
| 14808 | |||
| 14619 | (defun vhdl-speedbar-rescan-hierarchy () | 14809 | (defun vhdl-speedbar-rescan-hierarchy () |
| 14620 | "Rescan hierarchy for the directory or project under the cursor." | 14810 | "Rescan hierarchy for the directory or project under the cursor." |
| 14621 | (interactive) | 14811 | (interactive) |
| @@ -14637,6 +14827,8 @@ otherwise use cached data." | |||
| 14637 | (abbreviate-file-name (match-string 1 path))))) | 14827 | (abbreviate-file-name (match-string 1 path))))) |
| 14638 | (vhdl-speedbar-refresh key))) | 14828 | (vhdl-speedbar-refresh key))) |
| 14639 | 14829 | ||
| 14830 | (declare-function speedbar-goto-this-file "speedbar" (file)) | ||
| 14831 | |||
| 14640 | (defun vhdl-speedbar-expand-dirs (directory) | 14832 | (defun vhdl-speedbar-expand-dirs (directory) |
| 14641 | "Expand subdirectories in DIRECTORY according to | 14833 | "Expand subdirectories in DIRECTORY according to |
| 14642 | `speedbar-shown-directories'." | 14834 | `speedbar-shown-directories'." |
| @@ -14686,6 +14878,8 @@ otherwise use cached data." | |||
| 14686 | (setq unit-alist (cdr unit-alist)))))) | 14878 | (setq unit-alist (cdr unit-alist)))))) |
| 14687 | (vhdl-speedbar-update-current-unit nil t)) | 14879 | (vhdl-speedbar-update-current-unit nil t)) |
| 14688 | 14880 | ||
| 14881 | (declare-function speedbar-center-buffer-smartly "speedbar" ()) | ||
| 14882 | |||
| 14689 | (defun vhdl-speedbar-contract-level () | 14883 | (defun vhdl-speedbar-contract-level () |
| 14690 | "Contract current level in current directory/project." | 14884 | "Contract current level in current directory/project." |
| 14691 | (interactive) | 14885 | (interactive) |
| @@ -14726,21 +14920,24 @@ otherwise use cached data." | |||
| 14726 | (setq arch-alist (nth 4 (car ent-alist))) | 14920 | (setq arch-alist (nth 4 (car ent-alist))) |
| 14727 | (setq subunit-alist nil) | 14921 | (setq subunit-alist nil) |
| 14728 | (while arch-alist | 14922 | (while arch-alist |
| 14729 | (setq subunit-alist (cons (caar arch-alist) subunit-alist)) | 14923 | (push (caar arch-alist) subunit-alist) |
| 14730 | (setq arch-alist (cdr arch-alist))) | 14924 | (setq arch-alist (cdr arch-alist))) |
| 14731 | (setq unit-alist (cons (list (caar ent-alist) subunit-alist) unit-alist)) | 14925 | (push (list (caar ent-alist) subunit-alist) unit-alist) |
| 14732 | (setq ent-alist (cdr ent-alist))) | 14926 | (setq ent-alist (cdr ent-alist))) |
| 14733 | (while conf-alist | 14927 | (while conf-alist |
| 14734 | (setq unit-alist (cons (list (caar conf-alist)) unit-alist)) | 14928 | (push (list (caar conf-alist)) unit-alist) |
| 14735 | (setq conf-alist (cdr conf-alist))) | 14929 | (setq conf-alist (cdr conf-alist))) |
| 14736 | (while pack-alist | 14930 | (while pack-alist |
| 14737 | (setq unit-alist (cons (list (caar pack-alist)) unit-alist)) | 14931 | (push (list (caar pack-alist)) unit-alist) |
| 14738 | (setq pack-alist (cdr pack-alist))) | 14932 | (setq pack-alist (cdr pack-alist))) |
| 14739 | (aput 'vhdl-speedbar-shown-unit-alist key unit-alist) | 14933 | (aput 'vhdl-speedbar-shown-unit-alist key unit-alist) |
| 14740 | (vhdl-speedbar-refresh) | 14934 | (vhdl-speedbar-refresh) |
| 14741 | (when (memq 'display vhdl-speedbar-save-cache) | 14935 | (when (memq 'display vhdl-speedbar-save-cache) |
| 14742 | (add-to-list 'vhdl-updated-project-list key)))) | 14936 | (add-to-list 'vhdl-updated-project-list key)))) |
| 14743 | 14937 | ||
| 14938 | (declare-function speedbar-change-expand-button-char "speedbar" (char)) | ||
| 14939 | (declare-function speedbar-delete-subblock "speedbar" (indent)) | ||
| 14940 | |||
| 14744 | (defun vhdl-speedbar-expand-project (text token indent) | 14941 | (defun vhdl-speedbar-expand-project (text token indent) |
| 14745 | "Expand/contract the project under the cursor." | 14942 | "Expand/contract the project under the cursor." |
| 14746 | (cond | 14943 | (cond |
| @@ -15069,6 +15266,8 @@ otherwise use cached data." | |||
| 15069 | (setq vhdl-speedbar-last-selected-project vhdl-project))) | 15266 | (setq vhdl-speedbar-last-selected-project vhdl-project))) |
| 15070 | t) | 15267 | t) |
| 15071 | 15268 | ||
| 15269 | (declare-function speedbar-position-cursor-on-line "speedbar" ()) | ||
| 15270 | |||
| 15072 | (defun vhdl-speedbar-update-current-unit (&optional no-position always) | 15271 | (defun vhdl-speedbar-update-current-unit (&optional no-position always) |
| 15073 | "Highlight all design units that are contained in the current file. | 15272 | "Highlight all design units that are contained in the current file. |
| 15074 | NO-POSITION non-nil means do not re-position cursor." | 15273 | NO-POSITION non-nil means do not re-position cursor." |
| @@ -15158,6 +15357,9 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15158 | (setq unit-list (cdr unit-list))) | 15357 | (setq unit-list (cdr unit-list))) |
| 15159 | pos) | 15358 | pos) |
| 15160 | 15359 | ||
| 15360 | (declare-function speedbar-make-button "speedbar" | ||
| 15361 | (start end face mouse function &optional token)) | ||
| 15362 | |||
| 15161 | (defun vhdl-speedbar-make-inst-line (inst-name inst-file-marker | 15363 | (defun vhdl-speedbar-make-inst-line (inst-name inst-file-marker |
| 15162 | ent-name ent-file-marker | 15364 | ent-name ent-file-marker |
| 15163 | arch-name arch-file-marker | 15365 | arch-name arch-file-marker |
| @@ -15344,6 +15546,8 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15344 | 'speedbar-directory-face level) | 15546 | 'speedbar-directory-face level) |
| 15345 | (setq dirs (cdr dirs))))) | 15547 | (setq dirs (cdr dirs))))) |
| 15346 | 15548 | ||
| 15549 | (declare-function speedbar-reset-scanners "speedbar" ()) | ||
| 15550 | |||
| 15347 | (defun vhdl-speedbar-dired (text token indent) | 15551 | (defun vhdl-speedbar-dired (text token indent) |
| 15348 | "Speedbar click handler for directory expand button in hierarchy mode." | 15552 | "Speedbar click handler for directory expand button in hierarchy mode." |
| 15349 | (cond ((string-match "+" text) ; we have to expand this dir | 15553 | (cond ((string-match "+" text) ; we have to expand this dir |
| @@ -15374,7 +15578,7 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15374 | (concat (speedbar-line-directory indent) token)))) | 15578 | (concat (speedbar-line-directory indent) token)))) |
| 15375 | (while oldl | 15579 | (while oldl |
| 15376 | (if (not (string-match (concat "^" (regexp-quote td)) (car oldl))) | 15580 | (if (not (string-match (concat "^" (regexp-quote td)) (car oldl))) |
| 15377 | (setq newl (cons (car oldl) newl))) | 15581 | (push (car oldl) newl)) |
| 15378 | (setq oldl (cdr oldl))) | 15582 | (setq oldl (cdr oldl))) |
| 15379 | (setq speedbar-shown-directories (nreverse newl))) | 15583 | (setq speedbar-shown-directories (nreverse newl))) |
| 15380 | (speedbar-change-expand-button-char ?+) | 15584 | (speedbar-change-expand-button-char ?+) |
| @@ -15383,6 +15587,8 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15383 | (when (equal (selected-frame) speedbar-frame) | 15587 | (when (equal (selected-frame) speedbar-frame) |
| 15384 | (speedbar-center-buffer-smartly))) | 15588 | (speedbar-center-buffer-smartly))) |
| 15385 | 15589 | ||
| 15590 | (declare-function speedbar-files-item-info "speedbar" ()) | ||
| 15591 | |||
| 15386 | (defun vhdl-speedbar-item-info () | 15592 | (defun vhdl-speedbar-item-info () |
| 15387 | "Derive and display information about this line item." | 15593 | "Derive and display information about this line item." |
| 15388 | (save-excursion | 15594 | (save-excursion |
| @@ -15431,6 +15637,8 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15431 | (vhdl-default-directory))))) | 15637 | (vhdl-default-directory))))) |
| 15432 | (t (message ""))))) | 15638 | (t (message ""))))) |
| 15433 | 15639 | ||
| 15640 | (declare-function speedbar-line-text "speedbar" (&optional p)) | ||
| 15641 | |||
| 15434 | (defun vhdl-speedbar-line-text () | 15642 | (defun vhdl-speedbar-line-text () |
| 15435 | "Calls `speedbar-line-text' and removes text properties." | 15643 | "Calls `speedbar-line-text' and removes text properties." |
| 15436 | (let ((string (speedbar-line-text))) | 15644 | (let ((string (speedbar-line-text))) |
| @@ -15481,7 +15689,7 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15481 | (setq dir (car path-list)) | 15689 | (setq dir (car path-list)) |
| 15482 | (string-match "\\(-r \\)?\\(\\([^?*]*[/\\]\\)*\\)" dir) | 15690 | (string-match "\\(-r \\)?\\(\\([^?*]*[/\\]\\)*\\)" dir) |
| 15483 | (if (file-directory-p (match-string 2 dir)) | 15691 | (if (file-directory-p (match-string 2 dir)) |
| 15484 | (setq path-list-1 (cons dir path-list-1)) | 15692 | (push dir path-list-1) |
| 15485 | (vhdl-warning-when-idle "No such directory: \"%s\"" (match-string 2 dir))) | 15693 | (vhdl-warning-when-idle "No such directory: \"%s\"" (match-string 2 dir))) |
| 15486 | (setq path-list (cdr path-list))) | 15694 | (setq path-list (cdr path-list))) |
| 15487 | ;; resolve path wildcards | 15695 | ;; resolve path wildcards |
| @@ -15503,13 +15711,13 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15503 | dir-list) | 15711 | dir-list) |
| 15504 | (while all-list | 15712 | (while all-list |
| 15505 | (when (file-directory-p (car all-list)) | 15713 | (when (file-directory-p (car all-list)) |
| 15506 | (setq dir-list (cons (car all-list) dir-list))) | 15714 | (push (car all-list) dir-list)) |
| 15507 | (setq all-list (cdr all-list))) | 15715 | (setq all-list (cdr all-list))) |
| 15508 | dir-list)) | 15716 | dir-list)) |
| 15509 | (cdr path-list-1)))) | 15717 | (cdr path-list-1)))) |
| 15510 | (string-match "\\(-r \\)?\\(.*\\)[/\\].*" dir) | 15718 | (string-match "\\(-r \\)?\\(.*\\)[/\\].*" dir) |
| 15511 | (when (file-directory-p (match-string 2 dir)) | 15719 | (when (file-directory-p (match-string 2 dir)) |
| 15512 | (setq path-list-2 (cons dir path-list-2))) | 15720 | (push dir path-list-2)) |
| 15513 | (setq path-list-1 (cdr path-list-1)))) | 15721 | (setq path-list-1 (cdr path-list-1)))) |
| 15514 | (nreverse path-list-2))) | 15722 | (nreverse path-list-2))) |
| 15515 | 15723 | ||
| @@ -15525,6 +15733,11 @@ NO-POSITION non-nil means do not re-position cursor." | |||
| 15525 | (goto-char dest) | 15733 | (goto-char dest) |
| 15526 | nil))) | 15734 | nil))) |
| 15527 | 15735 | ||
| 15736 | (declare-function speedbar-find-file-in-frame "speedbar" (file)) | ||
| 15737 | (declare-function speedbar-set-timer "speedbar" (timeout)) | ||
| 15738 | ;; speedbar loads dframe at runtime. | ||
| 15739 | (declare-function dframe-maybee-jump-to-attached-frame "dframe" ()) | ||
| 15740 | |||
| 15528 | (defun vhdl-speedbar-find-file (text token indent) | 15741 | (defun vhdl-speedbar-find-file (text token indent) |
| 15529 | "When user clicks on TEXT, load file with name and position in TOKEN. | 15742 | "When user clicks on TEXT, load file with name and position in TOKEN. |
| 15530 | Jump to the design unit if `vhdl-speedbar-jump-to-unit' is t or if the file | 15743 | Jump to the design unit if `vhdl-speedbar-jump-to-unit' is t or if the file |
| @@ -15534,12 +15747,11 @@ is already shown in a buffer." | |||
| 15534 | (let ((buffer (get-file-buffer (car token)))) | 15747 | (let ((buffer (get-file-buffer (car token)))) |
| 15535 | (speedbar-find-file-in-frame (car token)) | 15748 | (speedbar-find-file-in-frame (car token)) |
| 15536 | (when (or vhdl-speedbar-jump-to-unit buffer) | 15749 | (when (or vhdl-speedbar-jump-to-unit buffer) |
| 15537 | (goto-char (point-min)) | 15750 | (vhdl-goto-line (cdr token)) |
| 15538 | (forward-line (1- (cdr token))) | ||
| 15539 | (recenter)) | 15751 | (recenter)) |
| 15540 | (vhdl-speedbar-update-current-unit t t) | 15752 | (vhdl-speedbar-update-current-unit t t) |
| 15541 | (speedbar-set-timer dframe-update-speed) | 15753 | (speedbar-set-timer dframe-update-speed) |
| 15542 | (speedbar-maybee-jump-to-attached-frame)))) | 15754 | (dframe-maybee-jump-to-attached-frame)))) |
| 15543 | 15755 | ||
| 15544 | (defun vhdl-speedbar-port-copy () | 15756 | (defun vhdl-speedbar-port-copy () |
| 15545 | "Copy the port of the entity/component or subprogram under the cursor." | 15757 | "Copy the port of the entity/component or subprogram under the cursor." |
| @@ -15553,8 +15765,7 @@ is already shown in a buffer." | |||
| 15553 | (let ((token (get-text-property | 15765 | (let ((token (get-text-property |
| 15554 | (match-beginning 3) 'speedbar-token))) | 15766 | (match-beginning 3) 'speedbar-token))) |
| 15555 | (vhdl-visit-file (car token) t | 15767 | (vhdl-visit-file (car token) t |
| 15556 | (progn (goto-char (point-min)) | 15768 | (progn (vhdl-goto-line (cdr token)) |
| 15557 | (forward-line (1- (cdr token))) | ||
| 15558 | (end-of-line) | 15769 | (end-of-line) |
| 15559 | (if is-entity | 15770 | (if is-entity |
| 15560 | (vhdl-port-copy) | 15771 | (vhdl-port-copy) |
| @@ -15600,6 +15811,8 @@ is already shown in a buffer." | |||
| 15600 | (setcar (cddr (cddr ent-entry)) arch-key) ; (nth 4 ent-entry) | 15811 | (setcar (cddr (cddr ent-entry)) arch-key) ; (nth 4 ent-entry) |
| 15601 | (speedbar-refresh)))) | 15812 | (speedbar-refresh)))) |
| 15602 | 15813 | ||
| 15814 | (declare-function speedbar-line-file "speedbar" (&optional p)) | ||
| 15815 | |||
| 15603 | (defun vhdl-speedbar-make-design () | 15816 | (defun vhdl-speedbar-make-design () |
| 15604 | "Make (compile) design unit or directory/project under the cursor." | 15817 | "Make (compile) design unit or directory/project under the cursor." |
| 15605 | (interactive) | 15818 | (interactive) |
| @@ -16007,7 +16220,7 @@ component instantiation." | |||
| 16007 | (or (aget generic-alist (match-string 2) t) | 16220 | (or (aget generic-alist (match-string 2) t) |
| 16008 | (error "ERROR: Formal generic \"%s\" mismatch for instance \"%s\"" (match-string 2) inst-name)) | 16221 | (error "ERROR: Formal generic \"%s\" mismatch for instance \"%s\"" (match-string 2) inst-name)) |
| 16009 | (cdar generic-alist)))) | 16222 | (cdar generic-alist)))) |
| 16010 | (setq constant-alist (cons constant-entry constant-alist)) | 16223 | (push constant-entry constant-alist) |
| 16011 | (setq constant-name (downcase constant-name)) | 16224 | (setq constant-name (downcase constant-name)) |
| 16012 | (if (or (member constant-name single-list) | 16225 | (if (or (member constant-name single-list) |
| 16013 | (member constant-name multi-list)) | 16226 | (member constant-name multi-list)) |
| @@ -16027,7 +16240,7 @@ component instantiation." | |||
| 16027 | (or (aget port-alist (match-string 2) t) | 16240 | (or (aget port-alist (match-string 2) t) |
| 16028 | (error "ERROR: Formal port \"%s\" mismatch for instance \"%s\"" (match-string 2) inst-name)) | 16241 | (error "ERROR: Formal port \"%s\" mismatch for instance \"%s\"" (match-string 2) inst-name)) |
| 16029 | (cdar port-alist)))) | 16242 | (cdar port-alist)))) |
| 16030 | (setq signal-alist (cons signal-entry signal-alist)) | 16243 | (push signal-entry signal-alist) |
| 16031 | (setq signal-name (downcase signal-name)) | 16244 | (setq signal-name (downcase signal-name)) |
| 16032 | (if (equal (upcase (nth 2 signal-entry)) "IN") | 16245 | (if (equal (upcase (nth 2 signal-entry)) "IN") |
| 16033 | ;; input signal | 16246 | ;; input signal |
| @@ -16061,8 +16274,8 @@ component instantiation." | |||
| 16061 | (unless (match-string 1) | 16274 | (unless (match-string 1) |
| 16062 | (setq port-alist (cdr port-alist))) | 16275 | (setq port-alist (cdr port-alist))) |
| 16063 | (vhdl-forward-syntactic-ws)) | 16276 | (vhdl-forward-syntactic-ws)) |
| 16064 | (setq inst-alist (cons (list inst-name (nreverse constant-alist) | 16277 | (push (list inst-name (nreverse constant-alist) |
| 16065 | (nreverse signal-alist)) inst-alist))) | 16278 | (nreverse signal-alist)) inst-alist)) |
| 16066 | ;; prepare signal insertion | 16279 | ;; prepare signal insertion |
| 16067 | (vhdl-goto-marker arch-decl-pos) | 16280 | (vhdl-goto-marker arch-decl-pos) |
| 16068 | (forward-line 1) | 16281 | (forward-line 1) |
| @@ -16129,6 +16342,7 @@ component instantiation." | |||
| 16129 | (while constant-alist | 16342 | (while constant-alist |
| 16130 | (setq constant-name (downcase (caar constant-alist)) | 16343 | (setq constant-name (downcase (caar constant-alist)) |
| 16131 | constant-entry (car constant-alist)) | 16344 | constant-entry (car constant-alist)) |
| 16345 | (unless (string-match "^[0-9]+" constant-name) | ||
| 16132 | (cond ((member constant-name written-list) | 16346 | (cond ((member constant-name written-list) |
| 16133 | nil) | 16347 | nil) |
| 16134 | ((member constant-name multi-list) | 16348 | ((member constant-name multi-list) |
| @@ -16145,7 +16359,7 @@ component instantiation." | |||
| 16145 | (setq generic-end-pos | 16359 | (setq generic-end-pos |
| 16146 | (vhdl-compose-insert-generic constant-entry)) | 16360 | (vhdl-compose-insert-generic constant-entry)) |
| 16147 | (setq generic-inst-pos (point-marker)) | 16361 | (setq generic-inst-pos (point-marker)) |
| 16148 | (add-to-list 'written-list constant-name))) | 16362 | (add-to-list 'written-list constant-name)))) |
| 16149 | (setq constant-alist (cdr constant-alist))) | 16363 | (setq constant-alist (cdr constant-alist))) |
| 16150 | (when (/= constant-temp-pos generic-inst-pos) | 16364 | (when (/= constant-temp-pos generic-inst-pos) |
| 16151 | (vhdl-goto-marker (vhdl-max-marker constant-temp-pos generic-pos)) | 16365 | (vhdl-goto-marker (vhdl-max-marker constant-temp-pos generic-pos)) |
| @@ -16305,8 +16519,7 @@ current project/directory." | |||
| 16305 | ;; insert component declarations | 16519 | ;; insert component declarations |
| 16306 | (while ent-alist | 16520 | (while ent-alist |
| 16307 | (vhdl-visit-file (nth 2 (car ent-alist)) nil | 16521 | (vhdl-visit-file (nth 2 (car ent-alist)) nil |
| 16308 | (progn (goto-char (point-min)) | 16522 | (progn (vhdl-goto-line (nth 3 (car ent-alist))) |
| 16309 | (forward-line (1- (nth 3 (car ent-alist)))) | ||
| 16310 | (end-of-line) | 16523 | (end-of-line) |
| 16311 | (vhdl-port-copy))) | 16524 | (vhdl-port-copy))) |
| 16312 | (goto-char component-pos) | 16525 | (goto-char component-pos) |
| @@ -16562,12 +16775,12 @@ no project is defined." | |||
| 16562 | (setq sublist (nth 11 (car commands-alist))) | 16775 | (setq sublist (nth 11 (car commands-alist))) |
| 16563 | (unless (or (equal "" (car sublist)) | 16776 | (unless (or (equal "" (car sublist)) |
| 16564 | (assoc (car sublist) regexp-alist)) | 16777 | (assoc (car sublist) regexp-alist)) |
| 16565 | (setq regexp-alist (cons (list (nth 0 sublist) | 16778 | (push (list (nth 0 sublist) |
| 16566 | (if (= 0 (nth 1 sublist)) | 16779 | (if (and (featurep 'xemacs) (not (nth 1 sublist))) |
| 16567 | (if (featurep 'xemacs) 9 nil) | 16780 | 9 |
| 16568 | (nth 1 sublist)) | 16781 | (nth 1 sublist)) |
| 16569 | (nth 2 sublist) (nth 3 sublist)) | 16782 | (nth 2 sublist) (nth 3 sublist)) |
| 16570 | regexp-alist))) | 16783 | regexp-alist)) |
| 16571 | (setq commands-alist (cdr commands-alist))) | 16784 | (setq commands-alist (cdr commands-alist))) |
| 16572 | (setq compilation-error-regexp-alist | 16785 | (setq compilation-error-regexp-alist |
| 16573 | (append compilation-error-regexp-alist (nreverse regexp-alist)))) | 16786 | (append compilation-error-regexp-alist (nreverse regexp-alist)))) |
| @@ -16580,7 +16793,7 @@ no project is defined." | |||
| 16580 | (setq sublist (nth 12 (car commands-alist))) | 16793 | (setq sublist (nth 12 (car commands-alist))) |
| 16581 | (unless (or (equal "" (car sublist)) | 16794 | (unless (or (equal "" (car sublist)) |
| 16582 | (assoc (car sublist) regexp-alist)) | 16795 | (assoc (car sublist) regexp-alist)) |
| 16583 | (setq regexp-alist (cons sublist regexp-alist))) | 16796 | (push sublist regexp-alist)) |
| 16584 | (setq commands-alist (cdr commands-alist))) | 16797 | (setq commands-alist (cdr commands-alist))) |
| 16585 | (setq compilation-file-regexp-alist | 16798 | (setq compilation-file-regexp-alist |
| 16586 | (append compilation-file-regexp-alist (nreverse regexp-alist)))))) | 16799 | (append compilation-file-regexp-alist (nreverse regexp-alist)))))) |
| @@ -16709,6 +16922,42 @@ specified by a target." | |||
| 16709 | (compile (concat (if (equal command "") "make" command) | 16922 | (compile (concat (if (equal command "") "make" command) |
| 16710 | " " options " " vhdl-make-target)))) | 16923 | " " options " " vhdl-make-target)))) |
| 16711 | 16924 | ||
| 16925 | ;; Emacs 22+ setup | ||
| 16926 | (defvar vhdl-error-regexp-emacs-alist | ||
| 16927 | ;; Get regexps from `vhdl-compiler-alist' | ||
| 16928 | (let ((compiler-alist vhdl-compiler-alist) | ||
| 16929 | (error-regexp-alist '((vhdl-directory "^ *Compiling \"\\(.+\\)\"" 1)))) | ||
| 16930 | (while compiler-alist | ||
| 16931 | ;; add error message regexps | ||
| 16932 | (setq error-regexp-alist | ||
| 16933 | (cons (append (list (make-symbol (concat "vhdl-" (subst-char-in-string ? ?- (downcase (nth 0 (car compiler-alist))))))) | ||
| 16934 | (nth 11 (car compiler-alist))) | ||
| 16935 | error-regexp-alist)) | ||
| 16936 | ;; add filename regexps | ||
| 16937 | (when (/= 0 (nth 1 (nth 12 (car compiler-alist)))) | ||
| 16938 | (setq error-regexp-alist | ||
| 16939 | (cons (append (list (make-symbol (concat "vhdl-" (subst-char-in-string ? ?- (downcase (nth 0 (car compiler-alist)))) "-file"))) | ||
| 16940 | (nth 12 (car compiler-alist))) | ||
| 16941 | error-regexp-alist))) | ||
| 16942 | (setq compiler-alist (cdr compiler-alist))) | ||
| 16943 | error-regexp-alist) | ||
| 16944 | "List of regexps for VHDL compilers. For Emacs 22+.") | ||
| 16945 | |||
| 16946 | ;; Add error regexps using compilation-mode-hook. | ||
| 16947 | (defun vhdl-error-regexp-add-emacs () | ||
| 16948 | "Set up Emacs compile for VHDL." | ||
| 16949 | (interactive) | ||
| 16950 | (when (and (boundp 'compilation-error-regexp-alist-alist) | ||
| 16951 | (not (assoc 'vhdl-modelsim compilation-error-regexp-alist-alist))) | ||
| 16952 | (mapcar | ||
| 16953 | (lambda (item) | ||
| 16954 | (push (car item) compilation-error-regexp-alist) | ||
| 16955 | (push item compilation-error-regexp-alist-alist)) | ||
| 16956 | vhdl-error-regexp-emacs-alist))) | ||
| 16957 | |||
| 16958 | (when vhdl-emacs-22 | ||
| 16959 | (add-hook 'compilation-mode-hook 'vhdl-error-regexp-add-emacs)) | ||
| 16960 | |||
| 16712 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 16961 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 16713 | ;; Makefile generation | 16962 | ;; Makefile generation |
| 16714 | 16963 | ||
| @@ -16731,7 +16980,7 @@ specified by a target." | |||
| 16731 | (let (pack-list) | 16980 | (let (pack-list) |
| 16732 | (while lib-alist | 16981 | (while lib-alist |
| 16733 | (when (equal (downcase (caar lib-alist)) (downcase work-library)) | 16982 | (when (equal (downcase (caar lib-alist)) (downcase work-library)) |
| 16734 | (setq pack-list (cons (cdar lib-alist) pack-list))) | 16983 | (push (cdar lib-alist) pack-list)) |
| 16735 | (setq lib-alist (cdr lib-alist))) | 16984 | (setq lib-alist (cdr lib-alist))) |
| 16736 | pack-list)) | 16985 | pack-list)) |
| 16737 | 16986 | ||
| @@ -16783,8 +17032,10 @@ specified by a target." | |||
| 16783 | (setq ent-entry (car ent-alist) | 17032 | (setq ent-entry (car ent-alist) |
| 16784 | ent-key (nth 0 ent-entry)) | 17033 | ent-key (nth 0 ent-entry)) |
| 16785 | (when (nth 2 ent-entry) | 17034 | (when (nth 2 ent-entry) |
| 16786 | (setq ent-file-name (file-relative-name | 17035 | (setq ent-file-name (if vhdl-compile-absolute-path |
| 16787 | (nth 2 ent-entry) compile-directory) | 17036 | (nth 2 ent-entry) |
| 17037 | (file-relative-name (nth 2 ent-entry) | ||
| 17038 | compile-directory)) | ||
| 16788 | arch-alist (nth 4 ent-entry) | 17039 | arch-alist (nth 4 ent-entry) |
| 16789 | lib-alist (nth 6 ent-entry) | 17040 | lib-alist (nth 6 ent-entry) |
| 16790 | rule (aget rule-alist ent-file-name) | 17041 | rule (aget rule-alist ent-file-name) |
| @@ -16794,9 +17045,9 @@ specified by a target." | |||
| 16794 | subcomp-list nil) | 17045 | subcomp-list nil) |
| 16795 | (setq tmp-key (vhdl-replace-string | 17046 | (setq tmp-key (vhdl-replace-string |
| 16796 | ent-regexp (funcall adjust-case ent-key))) | 17047 | ent-regexp (funcall adjust-case ent-key))) |
| 16797 | (setq unit-list (cons (cons ent-key tmp-key) unit-list)) | 17048 | (push (cons ent-key tmp-key) unit-list) |
| 16798 | ;; rule target for this entity | 17049 | ;; rule target for this entity |
| 16799 | (setq target-list (cons ent-key target-list)) | 17050 | (push ent-key target-list) |
| 16800 | ;; rule dependencies for all used packages | 17051 | ;; rule dependencies for all used packages |
| 16801 | (setq pack-list (vhdl-get-packages lib-alist work-library)) | 17052 | (setq pack-list (vhdl-get-packages lib-alist work-library)) |
| 16802 | (setq depend-list (append depend-list pack-list)) | 17053 | (setq depend-list (append depend-list pack-list)) |
| @@ -16808,8 +17059,10 @@ specified by a target." | |||
| 16808 | (setq arch-entry (car arch-alist) | 17059 | (setq arch-entry (car arch-alist) |
| 16809 | arch-key (nth 0 arch-entry) | 17060 | arch-key (nth 0 arch-entry) |
| 16810 | ent-arch-key (concat ent-key "-" arch-key) | 17061 | ent-arch-key (concat ent-key "-" arch-key) |
| 16811 | arch-file-name (file-relative-name (nth 2 arch-entry) | 17062 | arch-file-name (if vhdl-compile-absolute-path |
| 16812 | compile-directory) | 17063 | (nth 2 arch-entry) |
| 17064 | (file-relative-name (nth 2 arch-entry) | ||
| 17065 | compile-directory)) | ||
| 16813 | inst-alist (nth 4 arch-entry) | 17066 | inst-alist (nth 4 arch-entry) |
| 16814 | lib-alist (nth 5 arch-entry) | 17067 | lib-alist (nth 5 arch-entry) |
| 16815 | rule (aget rule-alist arch-file-name) | 17068 | rule (aget rule-alist arch-file-name) |
| @@ -16820,11 +17073,11 @@ specified by a target." | |||
| 16820 | (funcall adjust-case (concat arch-key " " ent-key)))) | 17073 | (funcall adjust-case (concat arch-key " " ent-key)))) |
| 16821 | (setq unit-list | 17074 | (setq unit-list |
| 16822 | (cons (cons ent-arch-key tmp-key) unit-list)) | 17075 | (cons (cons ent-arch-key tmp-key) unit-list)) |
| 16823 | (setq second-list (cons ent-arch-key second-list)) | 17076 | (push ent-arch-key second-list) |
| 16824 | ;; rule target for this architecture | 17077 | ;; rule target for this architecture |
| 16825 | (setq target-list (cons ent-arch-key target-list)) | 17078 | (push ent-arch-key target-list) |
| 16826 | ;; rule dependency for corresponding entity | 17079 | ;; rule dependency for corresponding entity |
| 16827 | (setq depend-list (cons ent-key depend-list)) | 17080 | (push ent-key depend-list) |
| 16828 | ;; rule dependencies for contained component instantiations | 17081 | ;; rule dependencies for contained component instantiations |
| 16829 | (while inst-alist | 17082 | (while inst-alist |
| 16830 | (setq inst-entry (car inst-alist)) | 17083 | (setq inst-entry (car inst-alist)) |
| @@ -16842,9 +17095,8 @@ specified by a target." | |||
| 16842 | ;; add rule | 17095 | ;; add rule |
| 16843 | (aput 'rule-alist arch-file-name (list target-list depend-list)) | 17096 | (aput 'rule-alist arch-file-name (list target-list depend-list)) |
| 16844 | (setq arch-alist (cdr arch-alist))) | 17097 | (setq arch-alist (cdr arch-alist))) |
| 16845 | (setq prim-list (cons (list ent-key second-list | 17098 | (push (list ent-key second-list (append subcomp-list all-pack-list)) |
| 16846 | (append subcomp-list all-pack-list)) | 17099 | prim-list)) |
| 16847 | prim-list))) | ||
| 16848 | (setq ent-alist (cdr ent-alist))) | 17100 | (setq ent-alist (cdr ent-alist))) |
| 16849 | (setq ent-alist tmp-list) | 17101 | (setq ent-alist tmp-list) |
| 16850 | ;; rules for all configurations | 17102 | ;; rules for all configurations |
| @@ -16852,8 +17104,10 @@ specified by a target." | |||
| 16852 | (while conf-alist | 17104 | (while conf-alist |
| 16853 | (setq conf-entry (car conf-alist) | 17105 | (setq conf-entry (car conf-alist) |
| 16854 | conf-key (nth 0 conf-entry) | 17106 | conf-key (nth 0 conf-entry) |
| 16855 | conf-file-name (file-relative-name | 17107 | conf-file-name (if vhdl-compile-absolute-path |
| 16856 | (nth 2 conf-entry) compile-directory) | 17108 | (nth 2 conf-entry) |
| 17109 | (file-relative-name (nth 2 conf-entry) | ||
| 17110 | compile-directory)) | ||
| 16857 | ent-key (nth 4 conf-entry) | 17111 | ent-key (nth 4 conf-entry) |
| 16858 | arch-key (nth 5 conf-entry) | 17112 | arch-key (nth 5 conf-entry) |
| 16859 | inst-alist (nth 6 conf-entry) | 17113 | inst-alist (nth 6 conf-entry) |
| @@ -16864,9 +17118,9 @@ specified by a target." | |||
| 16864 | subcomp-list (list ent-key)) | 17118 | subcomp-list (list ent-key)) |
| 16865 | (setq tmp-key (vhdl-replace-string | 17119 | (setq tmp-key (vhdl-replace-string |
| 16866 | conf-regexp (funcall adjust-case conf-key))) | 17120 | conf-regexp (funcall adjust-case conf-key))) |
| 16867 | (setq unit-list (cons (cons conf-key tmp-key) unit-list)) | 17121 | (push (cons conf-key tmp-key) unit-list) |
| 16868 | ;; rule target for this configuration | 17122 | ;; rule target for this configuration |
| 16869 | (setq target-list (cons conf-key target-list)) | 17123 | (push conf-key target-list) |
| 16870 | ;; rule dependency for corresponding entity and architecture | 17124 | ;; rule dependency for corresponding entity and architecture |
| 16871 | (setq depend-list | 17125 | (setq depend-list |
| 16872 | (cons ent-key (cons (concat ent-key "-" arch-key) depend-list))) | 17126 | (cons ent-key (cons (concat ent-key "-" arch-key) depend-list))) |
| @@ -16884,16 +17138,14 @@ specified by a target." | |||
| 16884 | (setq depend-list (cons inst-ent-key depend-list) | 17138 | (setq depend-list (cons inst-ent-key depend-list) |
| 16885 | subcomp-list (cons inst-ent-key subcomp-list))) | 17139 | subcomp-list (cons inst-ent-key subcomp-list))) |
| 16886 | ; (when comp-arch-key | 17140 | ; (when comp-arch-key |
| 16887 | ; (setq depend-list (cons (concat comp-ent-key "-" comp-arch-key) | 17141 | ; (push (concat comp-ent-key "-" comp-arch-key) depend-list)) |
| 16888 | ; depend-list))) | ||
| 16889 | (when inst-conf-key | 17142 | (when inst-conf-key |
| 16890 | (setq depend-list (cons inst-conf-key depend-list) | 17143 | (setq depend-list (cons inst-conf-key depend-list) |
| 16891 | subcomp-list (cons inst-conf-key subcomp-list)))) | 17144 | subcomp-list (cons inst-conf-key subcomp-list)))) |
| 16892 | (setq inst-alist (cdr inst-alist))) | 17145 | (setq inst-alist (cdr inst-alist))) |
| 16893 | ;; add rule | 17146 | ;; add rule |
| 16894 | (aput 'rule-alist conf-file-name (list target-list depend-list)) | 17147 | (aput 'rule-alist conf-file-name (list target-list depend-list)) |
| 16895 | (setq prim-list (cons (list conf-key nil (append subcomp-list pack-list)) | 17148 | (push (list conf-key nil (append subcomp-list pack-list)) prim-list) |
| 16896 | prim-list)) | ||
| 16897 | (setq conf-alist (cdr conf-alist))) | 17149 | (setq conf-alist (cdr conf-alist))) |
| 16898 | (setq conf-alist tmp-list) | 17150 | (setq conf-alist tmp-list) |
| 16899 | ;; rules for all packages | 17151 | ;; rules for all packages |
| @@ -16903,16 +17155,18 @@ specified by a target." | |||
| 16903 | pack-key (nth 0 pack-entry) | 17155 | pack-key (nth 0 pack-entry) |
| 16904 | pack-body-key nil) | 17156 | pack-body-key nil) |
| 16905 | (when (nth 2 pack-entry) | 17157 | (when (nth 2 pack-entry) |
| 16906 | (setq pack-file-name (file-relative-name (nth 2 pack-entry) | 17158 | (setq pack-file-name (if vhdl-compile-absolute-path |
| 16907 | compile-directory) | 17159 | (nth 2 pack-entry) |
| 17160 | (file-relative-name (nth 2 pack-entry) | ||
| 17161 | compile-directory)) | ||
| 16908 | lib-alist (nth 6 pack-entry) lib-body-alist (nth 10 pack-entry) | 17162 | lib-alist (nth 6 pack-entry) lib-body-alist (nth 10 pack-entry) |
| 16909 | rule (aget rule-alist pack-file-name) | 17163 | rule (aget rule-alist pack-file-name) |
| 16910 | target-list (nth 0 rule) depend-list (nth 1 rule)) | 17164 | target-list (nth 0 rule) depend-list (nth 1 rule)) |
| 16911 | (setq tmp-key (vhdl-replace-string | 17165 | (setq tmp-key (vhdl-replace-string |
| 16912 | pack-regexp (funcall adjust-case pack-key))) | 17166 | pack-regexp (funcall adjust-case pack-key))) |
| 16913 | (setq unit-list (cons (cons pack-key tmp-key) unit-list)) | 17167 | (push (cons pack-key tmp-key) unit-list) |
| 16914 | ;; rule target for this package | 17168 | ;; rule target for this package |
| 16915 | (setq target-list (cons pack-key target-list)) | 17169 | (push pack-key target-list) |
| 16916 | ;; rule dependencies for all used packages | 17170 | ;; rule dependencies for all used packages |
| 16917 | (setq pack-list (vhdl-get-packages lib-alist work-library)) | 17171 | (setq pack-list (vhdl-get-packages lib-alist work-library)) |
| 16918 | (setq depend-list (append depend-list pack-list)) | 17172 | (setq depend-list (append depend-list pack-list)) |
| @@ -16922,8 +17176,10 @@ specified by a target." | |||
| 16922 | ;; rules for this package's body | 17176 | ;; rules for this package's body |
| 16923 | (when (nth 7 pack-entry) | 17177 | (when (nth 7 pack-entry) |
| 16924 | (setq pack-body-key (concat pack-key "-body") | 17178 | (setq pack-body-key (concat pack-key "-body") |
| 16925 | pack-body-file-name (file-relative-name (nth 7 pack-entry) | 17179 | pack-body-file-name (if vhdl-compile-absolute-path |
| 16926 | compile-directory) | 17180 | (nth 7 pack-entry) |
| 17181 | (file-relative-name (nth 7 pack-entry) | ||
| 17182 | compile-directory)) | ||
| 16927 | rule (aget rule-alist pack-body-file-name) | 17183 | rule (aget rule-alist pack-body-file-name) |
| 16928 | target-list (nth 0 rule) | 17184 | target-list (nth 0 rule) |
| 16929 | depend-list (nth 1 rule)) | 17185 | depend-list (nth 1 rule)) |
| @@ -16932,9 +17188,9 @@ specified by a target." | |||
| 16932 | (setq unit-list | 17188 | (setq unit-list |
| 16933 | (cons (cons pack-body-key tmp-key) unit-list)) | 17189 | (cons (cons pack-body-key tmp-key) unit-list)) |
| 16934 | ;; rule target for this package's body | 17190 | ;; rule target for this package's body |
| 16935 | (setq target-list (cons pack-body-key target-list)) | 17191 | (push pack-body-key target-list) |
| 16936 | ;; rule dependency for corresponding package declaration | 17192 | ;; rule dependency for corresponding package declaration |
| 16937 | (setq depend-list (cons pack-key depend-list)) | 17193 | (push pack-key depend-list) |
| 16938 | ;; rule dependencies for all used packages | 17194 | ;; rule dependencies for all used packages |
| 16939 | (setq pack-list (vhdl-get-packages lib-body-alist work-library)) | 17195 | (setq pack-list (vhdl-get-packages lib-body-alist work-library)) |
| 16940 | (setq depend-list (append depend-list pack-list)) | 17196 | (setq depend-list (append depend-list pack-list)) |
| @@ -17057,16 +17313,16 @@ specified by a target." | |||
| 17057 | (unless (equal unit-key unit-name) | 17313 | (unless (equal unit-key unit-name) |
| 17058 | (insert " \\\n" unit-name)) | 17314 | (insert " \\\n" unit-name)) |
| 17059 | (insert " :" | 17315 | (insert " :" |
| 17060 | " \\\n\t\t" (nth 2 vhdl-makefile-default-targets) | 17316 | " \\\n\t\t" (nth 2 vhdl-makefile-default-targets)) |
| 17061 | " \\\n\t\t$(UNIT-" work-library "-" unit-key ")") | ||
| 17062 | (while second-list | ||
| 17063 | (insert " \\\n\t\t$(UNIT-" work-library "-" (car second-list) ")") | ||
| 17064 | (setq second-list (cdr second-list))) | ||
| 17065 | (while subcomp-list | 17317 | (while subcomp-list |
| 17066 | (when (and (assoc (car subcomp-list) unit-list) | 17318 | (when (and (assoc (car subcomp-list) unit-list) |
| 17067 | (not (equal unit-key (car subcomp-list)))) | 17319 | (not (equal unit-key (car subcomp-list)))) |
| 17068 | (insert " \\\n\t\t" (car subcomp-list))) | 17320 | (insert " \\\n\t\t" (car subcomp-list))) |
| 17069 | (setq subcomp-list (cdr subcomp-list))) | 17321 | (setq subcomp-list (cdr subcomp-list))) |
| 17322 | (insert " \\\n\t\t$(UNIT-" work-library "-" unit-key ")") | ||
| 17323 | (while second-list | ||
| 17324 | (insert " \\\n\t\t$(UNIT-" work-library "-" (car second-list) ")") | ||
| 17325 | (setq second-list (cdr second-list))) | ||
| 17070 | (insert "\n") | 17326 | (insert "\n") |
| 17071 | (setq prim-list (cdr prim-list))) | 17327 | (setq prim-list (cdr prim-list))) |
| 17072 | ;; insert rule for each library unit file | 17328 | ;; insert rule for each library unit file |
| @@ -17205,6 +17461,7 @@ specified by a target." | |||
| 17205 | 'vhdl-include-direction-comments | 17461 | 'vhdl-include-direction-comments |
| 17206 | 'vhdl-include-type-comments | 17462 | 'vhdl-include-type-comments |
| 17207 | 'vhdl-include-group-comments | 17463 | 'vhdl-include-group-comments |
| 17464 | 'vhdl-actual-generic-name | ||
| 17208 | 'vhdl-actual-port-name | 17465 | 'vhdl-actual-port-name |
| 17209 | 'vhdl-instance-name | 17466 | 'vhdl-instance-name |
| 17210 | 'vhdl-testbench-entity-name | 17467 | 'vhdl-testbench-entity-name |
| @@ -17287,13 +17544,21 @@ specified by a target." | |||
| 17287 | 17544 | ||
| 17288 | (defconst vhdl-doc-release-notes nil | 17545 | (defconst vhdl-doc-release-notes nil |
| 17289 | "\ | 17546 | "\ |
| 17290 | Release Notes for VHDL Mode 3.33 | 17547 | Release Notes for VHDL Mode 3.34 |
| 17291 | ================================ | 17548 | ================================ |
| 17292 | 17549 | ||
| 17293 | - New Features | 17550 | - Added support for GNU Emacs 22/23/24: |
| 17294 | - User Options | 17551 | - Compilation error parsing fixed for new `compile.el' package. |
| 17552 | |||
| 17553 | - Port translation: Derive actual generic name from formal generic name. | ||
| 17554 | |||
| 17555 | - New user options: | ||
| 17556 | `vhdl-actual-generic-name': Specify how actual generic names are obtained. | ||
| 17295 | 17557 | ||
| 17296 | 17558 | ||
| 17559 | Release Notes for VHDL Mode 3.33 | ||
| 17560 | ================================ | ||
| 17561 | |||
| 17297 | New Features | 17562 | New Features |
| 17298 | ------------ | 17563 | ------------ |
| 17299 | 17564 | ||
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el index edfe368479c..c8044f407fc 100644 --- a/lisp/progmodes/which-func.el +++ b/lisp/progmodes/which-func.el | |||
| @@ -343,6 +343,10 @@ If no function name is found, return nil." | |||
| 343 | 343 | ||
| 344 | ;;; Integration with other packages | 344 | ;;; Integration with other packages |
| 345 | 345 | ||
| 346 | (defvar ediff-window-A) | ||
| 347 | (defvar ediff-window-B) | ||
| 348 | (defvar ediff-window-C) | ||
| 349 | |||
| 346 | (defun which-func-update-ediff-windows () | 350 | (defun which-func-update-ediff-windows () |
| 347 | "Update Which-Function mode display for Ediff windows. | 351 | "Update Which-Function mode display for Ediff windows. |
| 348 | This function is meant to be called from `ediff-select-hook'." | 352 | This function is meant to be called from `ediff-select-hook'." |
diff --git a/lisp/progmodes/xscheme.el b/lisp/progmodes/xscheme.el index 2ad44b4b1c8..37c3cd37a6c 100644 --- a/lisp/progmodes/xscheme.el +++ b/lisp/progmodes/xscheme.el | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | ;;;; Internal Variables | 35 | ;;;; Internal Variables |
| 36 | 36 | ||
| 37 | (defvar xscheme-previous-mode) | 37 | (defvar xscheme-previous-mode) |
| 38 | (defvar xscheme-previous-process-state) | ||
| 39 | (defvar xscheme-last-input-end) | 38 | (defvar xscheme-last-input-end) |
| 40 | 39 | ||
| 41 | (defvar xscheme-process-command-line nil | 40 | (defvar xscheme-process-command-line nil |
| @@ -388,8 +387,6 @@ with no args, if that value is non-nil. | |||
| 388 | (if (not preserve) | 387 | (if (not preserve) |
| 389 | (let ((previous-mode major-mode)) | 388 | (let ((previous-mode major-mode)) |
| 390 | (kill-all-local-variables) | 389 | (kill-all-local-variables) |
| 391 | (make-local-variable 'xscheme-process-name) | ||
| 392 | (make-local-variable 'xscheme-previous-process-state) | ||
| 393 | (make-local-variable 'xscheme-runlight-string) | 390 | (make-local-variable 'xscheme-runlight-string) |
| 394 | (make-local-variable 'xscheme-runlight) | 391 | (make-local-variable 'xscheme-runlight) |
| 395 | (set (make-local-variable 'xscheme-previous-mode) previous-mode) | 392 | (set (make-local-variable 'xscheme-previous-mode) previous-mode) |
| @@ -397,35 +394,29 @@ with no args, if that value is non-nil. | |||
| 397 | (set (make-local-variable 'xscheme-buffer-name) (buffer-name buffer)) | 394 | (set (make-local-variable 'xscheme-buffer-name) (buffer-name buffer)) |
| 398 | (set (make-local-variable 'xscheme-last-input-end) (make-marker)) | 395 | (set (make-local-variable 'xscheme-last-input-end) (make-marker)) |
| 399 | (let ((process (get-buffer-process buffer))) | 396 | (let ((process (get-buffer-process buffer))) |
| 400 | (if process | 397 | (when process |
| 401 | (progn | 398 | (setq-local xscheme-process-name (process-name process)) |
| 402 | (setq xscheme-process-name (process-name process)) | 399 | ;; FIXME: Use add-function! |
| 403 | (setq xscheme-previous-process-state | 400 | (xscheme-process-filter-initialize t) |
| 404 | (cons (process-filter process) | 401 | (xscheme-mode-line-initialize xscheme-buffer-name) |
| 405 | (process-sentinel process))) | 402 | (add-function :override (process-sentinel process) |
| 406 | (xscheme-process-filter-initialize t) | 403 | #'xscheme-process-sentinel) |
| 407 | (xscheme-mode-line-initialize xscheme-buffer-name) | 404 | (add-function :override (process-filter process) |
| 408 | (set-process-sentinel process 'xscheme-process-sentinel) | 405 | #'xscheme-process-filter)))))) |
| 409 | (set-process-filter process 'xscheme-process-filter)) | ||
| 410 | (setq xscheme-previous-process-state (cons nil nil))))))) | ||
| 411 | (scheme-interaction-mode-initialize) | 406 | (scheme-interaction-mode-initialize) |
| 412 | (scheme-mode-variables) | 407 | (scheme-mode-variables) |
| 413 | (run-mode-hooks 'scheme-mode-hook 'scheme-interaction-mode-hook)) | 408 | (run-mode-hooks 'scheme-mode-hook 'scheme-interaction-mode-hook)) |
| 414 | 409 | ||
| 415 | (defun exit-scheme-interaction-mode () | 410 | (defun exit-scheme-interaction-mode () |
| 416 | "Take buffer out of scheme interaction mode" | 411 | "Take buffer out of scheme interaction mode." |
| 417 | (interactive) | 412 | (interactive) |
| 418 | (if (not (derived-mode-p 'scheme-interaction-mode)) | 413 | (if (not (derived-mode-p 'scheme-interaction-mode)) |
| 419 | (error "Buffer not in scheme interaction mode")) | 414 | (error "Buffer not in scheme interaction mode")) |
| 420 | (let ((previous-state xscheme-previous-process-state)) | 415 | (funcall xscheme-previous-mode) |
| 421 | (funcall xscheme-previous-mode) | 416 | (let ((process (get-buffer-process (current-buffer)))) |
| 422 | (let ((process (get-buffer-process (current-buffer)))) | 417 | (when process |
| 423 | (if process | 418 | (remove-function (process-sentinel process) #'xscheme-process-sentinel) |
| 424 | (progn | 419 | (remove-function (process-filter process) #'xscheme-process-filter)))) |
| 425 | (if (eq (process-filter process) 'xscheme-process-filter) | ||
| 426 | (set-process-filter process (car previous-state))) | ||
| 427 | (if (eq (process-sentinel process) 'xscheme-process-sentinel) | ||
| 428 | (set-process-sentinel process (cdr previous-state)))))))) | ||
| 429 | 420 | ||
| 430 | (defvar scheme-interaction-mode-commands-alist nil) | 421 | (defvar scheme-interaction-mode-commands-alist nil) |
| 431 | (defvar scheme-interaction-mode-map nil) | 422 | (defvar scheme-interaction-mode-map nil) |