aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/progmodes/ada-mode.el1223
1 files changed, 866 insertions, 357 deletions
diff --git a/lisp/progmodes/ada-mode.el b/lisp/progmodes/ada-mode.el
index fd938652450..794a94f2b9b 100644
--- a/lisp/progmodes/ada-mode.el
+++ b/lisp/progmodes/ada-mode.el
@@ -7,7 +7,7 @@
7;; Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de> 7;; Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de>
8;; Emmanuel Briot <briot@gnat.com> 8;; Emmanuel Briot <briot@gnat.com>
9;; Maintainer: Emmanuel Briot <briot@gnat.com> 9;; Maintainer: Emmanuel Briot <briot@gnat.com>
10;; Ada Core Technologies's version: $Revision: 1.47 $ 10;; Ada Core Technologies's version: $Revision: 1.48 $
11;; Keywords: languages ada 11;; Keywords: languages ada
12 12
13;; This file is part of GNU Emacs. 13;; This file is part of GNU Emacs.
@@ -94,6 +94,7 @@
94;;; gse@ocsystems.com (Scott Evans) 94;;; gse@ocsystems.com (Scott Evans)
95;;; comar@gnat.com (Cyrille Comar) 95;;; comar@gnat.com (Cyrille Comar)
96;;; stephen.leake@gsfc.nasa.gov (Stephen Leake) 96;;; stephen.leake@gsfc.nasa.gov (Stephen Leake)
97;;; robin-reply@reagans.org
97;;; and others for their valuable hints. 98;;; and others for their valuable hints.
98 99
99;;; Code: 100;;; Code:
@@ -103,6 +104,28 @@
103;;; the customize mode. They are sorted in alphabetical order in this 104;;; the customize mode. They are sorted in alphabetical order in this
104;;; file. 105;;; file.
105 106
107;;; Supported packages.
108;;; This package supports a number of other Emacs modes. These other modes
109;;; should be loaded before the ada-mode, which will then setup some variables
110;;; to improve the support for Ada code.
111;;; Here is the list of these modes:
112;;; `which-function-mode': Display the name of the subprogram the cursor is
113;;; in in the mode line.
114;;; `outline-mode': Provides the capability to collapse or expand the code
115;;; for specific language constructs, for instance if you want to hide the
116;;; code corresponding to a subprogram
117;;; `align': This mode is now provided with Emacs 21, but can also be
118;;; installed manually for older versions of Emacs. It provides the
119;;; capability to automatically realign the selected region (for instance
120;;; all ':=', ':' and '--' will be aligned on top of each other.
121;;; `imenu': Provides a menu with the list of entities defined in the current
122;;; buffer, and an easy way to jump to any of them
123;;; `speedbar': Provides a separate file browser, and the capability for each
124;;; file to see the list of entities defined in it and to jump to them
125;;; easily
126;;; `abbrev-mode': Provides the capability to define abbreviations, which
127;;; are automatically expanded when you type them. See the Emacs manual.
128
106 129
107;; this function is needed at compile time 130;; this function is needed at compile time
108(eval-and-compile 131(eval-and-compile
@@ -133,7 +156,8 @@ If IS-XEMACS is non-nil, check for XEmacs instead of Emacs."
133 156
134;; This call should not be made in the release that is done for the 157;; This call should not be made in the release that is done for the
135;; official FSF Emacs, since it does nothing useful for the latest version 158;; official FSF Emacs, since it does nothing useful for the latest version
136;; (require 'ada-support) 159(if (not (ada-check-emacs-version 21 1))
160 (require 'ada-support))
137 161
138(defvar ada-mode-hook nil 162(defvar ada-mode-hook nil
139 "*List of functions to call when Ada mode is invoked. 163 "*List of functions to call when Ada mode is invoked.
@@ -179,13 +203,17 @@ It may be `downcase-word', `upcase-word', `ada-loose-case-word',
179 (const ada-no-auto-case)) 203 (const ada-no-auto-case))
180 :group 'ada) 204 :group 'ada)
181 205
182(defcustom ada-case-exception-file '("~/.emacs_case_exceptions") 206(defcustom ada-case-exception-file
207 (list (convert-standard-filename' "~/.emacs_case_exceptions"))
183 "*List of special casing exceptions dictionaries for identifiers. 208 "*List of special casing exceptions dictionaries for identifiers.
184The first file is the one where new exceptions will be saved by Emacs 209The first file is the one where new exceptions will be saved by Emacs
185when you call `ada-create-case-exception'. 210when you call `ada-create-case-exception'.
186 211
187These files should contain one word per line, that gives the casing 212These files should contain one word per line, that gives the casing
188to be used for that word in Ada files. Each line can be terminated by 213to be used for that word in Ada files. If the line starts with the
214character *, then the exception will be used for substrings that either
215start at the beginning of a word or after a _ character, and end either
216at the end of the word or at a _ character. Each line can be terminated by
189a comment." 217a comment."
190 :type '(repeat (file)) 218 :type '(repeat (file))
191 :group 'ada) 219 :group 'ada)
@@ -244,6 +272,29 @@ For instance:
244nil means do not auto-indent comments." 272nil means do not auto-indent comments."
245 :type 'boolean :group 'ada) 273 :type 'boolean :group 'ada)
246 274
275(defcustom ada-indent-handle-comment-special nil
276 "*Non-nil if comment lines should be handled specially inside
277parenthesis.
278By default, if the line that contains the open parenthesis has some
279text following it, then the following lines will be indented in the
280same column as this text. This will not be true if the first line is
281a comment and `ada-indent-handle-comment-special' is t.
282
283type A is
284 ( Value_1, -- common behavior, when not a comment
285 Value_2);
286
287type A is
288 ( -- `ada-indent-handle-comment-special' is nil
289 Value_1,
290 Value_2);
291
292type A is
293 ( -- `ada-indent-handle-comment-special' is non-nil
294 Value_1,
295 Value_2);"
296 :type 'boolean :group 'ada)
297
247(defcustom ada-indent-is-separate t 298(defcustom ada-indent-is-separate t
248 "*Non-nil means indent 'is separate' or 'is abstract' if on a single line." 299 "*Non-nil means indent 'is separate' or 'is abstract' if on a single line."
249 :type 'boolean :group 'ada) 300 :type 'boolean :group 'ada)
@@ -429,6 +480,12 @@ This variable is used to define `ada-83-keywords' and `ada-95-keywords'"))
429(defvar ada-case-exception '() 480(defvar ada-case-exception '()
430 "Alist of words (entities) that have special casing.") 481 "Alist of words (entities) that have special casing.")
431 482
483(defvar ada-case-exception-substring '()
484 "Alist of substrings (entities) that have special casing.
485The substrings are detected for word constituant when the word
486is not itself in ada-case-exception, and only for substrings that
487either are at the beginning or end of the word, or start after '_'.")
488
432(defvar ada-lfd-binding nil 489(defvar ada-lfd-binding nil
433 "Variable to save key binding of LFD when casing is activated.") 490 "Variable to save key binding of LFD when casing is activated.")
434 491
@@ -436,6 +493,56 @@ This variable is used to define `ada-83-keywords' and `ada-95-keywords'"))
436 "Variable used by find-file to find the name of the other package. 493 "Variable used by find-file to find the name of the other package.
437See `ff-other-file-alist'.") 494See `ff-other-file-alist'.")
438 495
496(defvar ada-align-list
497 '(("[^:]\\(\\s-*\\):[^:]" 1 t)
498 ("[^=]\\(\\s-+\\)=[^=]" 1 t)
499 ("\\(\\s-*\\)use\\s-" 1)
500 ("\\(\\s-*\\)--" 1))
501 "Ada support for align.el <= 2.2
502This variable provides regular expressions on which to align different lines.
503See `align-mode-alist' for more information.")
504
505(defvar ada-align-modes
506 '((ada-declaration
507 (regexp . "[^:]\\(\\s-*\\):[^:]")
508 (valid . (lambda() (not (ada-in-comment-p))))
509 (modes . '(ada-mode)))
510 (ada-assignment
511 (regexp . "[^=]\\(\\s-+\\)=[^=]")
512 (valid . (lambda() (not (ada-in-comment-p))))
513 (modes . '(ada-mode)))
514 (ada-comment
515 (regexp . "\\(\\s-*\\)--")
516 (modes . '(ada-mode)))
517 (ada-use
518 (regexp . "\\(\\s-*\\)use\\s-")
519 (valid . (lambda() (not (ada-in-comment-p))))
520 (modes . '(ada-mode)))
521 )
522 "Ada support for align.el >= 2.8
523This variable defines several rules to use to align different lines.")
524
525(defconst ada-align-region-separate
526 (concat
527 "^\\s-*\\($\\|\\("
528 "begin\\|"
529 "declare\\|"
530 "else\\|"
531 "end\\|"
532 "exception\\|"
533 "for\\|"
534 "function\\|"
535 "generic\\|"
536 "if\\|"
537 "is\\|"
538 "procedure\\|"
539 "record\\|"
540 "return\\|"
541 "type\\|"
542 "when"
543 "\\)\\>\\)")
544 "see the variable `align-region-separate' for more information.")
545
439;;; ---- Below are the regexp used in this package for parsing 546;;; ---- Below are the regexp used in this package for parsing
440 547
441(defconst ada-83-keywords 548(defconst ada-83-keywords
@@ -459,8 +566,20 @@ See `ff-other-file-alist'.")
459 "\\(\\sw\\|[_.]\\)+" 566 "\\(\\sw\\|[_.]\\)+"
460 "Regexp matching Ada (qualified) identifiers.") 567 "Regexp matching Ada (qualified) identifiers.")
461 568
569;; "with" needs to be included in the regexp, so that we can insert new lines
570;; after the declaration of the parameter for a generic.
462(defvar ada-procedure-start-regexp 571(defvar ada-procedure-start-regexp
463 "^[ \t]*\\(procedure\\|function\\|task\\)[ \t\n]+\\(\\(\\sw\\|[_.]\\)+\\)" 572 (concat
573 "^[ \t]*\\(with[ \t]+\\)?\\(procedure\\|function\\|task\\)[ \t\n]+"
574
575 ;; subprogram name: operator ("[+/=*]")
576 "\\("
577 "\\(\"[^\"]+\"\\)"
578
579 ;; subprogram name: name
580 "\\|"
581 "\\(\\(\\sw\\|[_.]\\)+\\)"
582 "\\)")
464 "Regexp used to find Ada procedures/functions.") 583 "Regexp used to find Ada procedures/functions.")
465 584
466(defvar ada-package-start-regexp 585(defvar ada-package-start-regexp
@@ -595,8 +714,14 @@ displaying the menu if point was on an identifier."
595;; Support for imenu (see imenu.el) 714;; Support for imenu (see imenu.el)
596;;------------------------------------------------------------------ 715;;------------------------------------------------------------------
597 716
717(defconst ada-imenu-comment-re "\\([ \t]*--.*\\)?")
718
598(defconst ada-imenu-subprogram-menu-re 719(defconst ada-imenu-subprogram-menu-re
599 "^[ \t]*\\(procedure\\|function\\)[ \t\n]+\\(\\(\\sw\\|_\\)+\\)[ \t\n]*\\([ \t\n]\\|([^)]+)\\)[ \t\n]*\\(return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?is[ \t\n]") 720 (concat "^[ \t]*\\(procedure\\|function\\)[ \t\n]+"
721 "\\(\\(\\sw\\|_\\)+\\)[ \t\n]*\\([ \t\n]\\|([^)]+)"
722 ada-imenu-comment-re
723 "\\)[ \t\n]*"
724 "\\(return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?is[ \t\n]"))
600 725
601(defvar ada-imenu-generic-expression 726(defvar ada-imenu-generic-expression
602 (list 727 (list
@@ -605,17 +730,18 @@ displaying the menu if point was on an identifier."
605 (concat 730 (concat
606 "^[ \t]*\\(procedure\\|function\\)[ \t\n]+\\(\\(\\sw\\|_\\)+\\)" 731 "^[ \t]*\\(procedure\\|function\\)[ \t\n]+\\(\\(\\sw\\|_\\)+\\)"
607 "\\(" 732 "\\("
608 "\\([ \t\n]+\\|[ \t\n]*([^)]+)\\)";; parameter list or simple space 733 "\\(" ada-imenu-comment-re "[ \t\n]+\\|[ \t\n]*([^)]+)"
734 ada-imenu-comment-re "\\)";; parameter list or simple space
609 "\\([ \t\n]*return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?" 735 "\\([ \t\n]*return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?"
610 "\\)?;") 2) 736 "\\)?;") 2)
611 '("*Tasks*" "^[ \t]*task[ \t]+\\(\\(body\\|type\\)[ \t]+\\)?\\(\\(\\sw\\|_\\)+\\)" 3) 737 '("*Tasks*" "^[ \t]*task[ \t]+\\(type[ \t]+\\)?\\(\\(body[ \t]+\\)?\\(\\sw\\|_\\)+\\)" 2)
612 '("*Type Defs*" "^[ \t]*\\(sub\\)?type[ \t]+\\(\\(\\sw\\|_\\)+\\)" 2) 738 '("*Type Defs*" "^[ \t]*\\(sub\\)?type[ \t]+\\(\\(\\sw\\|_\\)+\\)" 2)
739 '("*Protected*"
740 "^[ \t]*protected[ \t]+\\(type[ \t]+\\)?\\(\\(body[ \t]+\\)?\\(\\sw\\|_\\)+\\)" 2)
613 '("*Packages*" "^[ \t]*package[ \t]+\\(\\(body[ \t]+\\)?\\(\\sw\\|[_.]\\)+\\)" 1)) 741 '("*Packages*" "^[ \t]*package[ \t]+\\(\\(body[ \t]+\\)?\\(\\sw\\|[_.]\\)+\\)" 1))
614 "Imenu generic expression for Ada mode. 742 "Imenu generic expression for Ada mode.
615See `imenu-generic-expression'. This variable will create two submenus, one 743See `imenu-generic-expression'. This variable will create several submenus for
616for type and subtype definitions, the other for subprograms declarations. 744each type of entity that can be found in an Ada file.")
617The main menu will reference the bodies of the subprograms.")
618
619 745
620 746
621;;------------------------------------------------------------ 747;;------------------------------------------------------------
@@ -959,8 +1085,10 @@ name"
959;;;###autoload 1085;;;###autoload
960(defun ada-mode () 1086(defun ada-mode ()
961 "Ada mode is the major mode for editing Ada code. 1087 "Ada mode is the major mode for editing Ada code.
1088This version was built on $Date: 2001/12/26 14:40:09 $.
962 1089
963Bindings are as follows: (Note: 'LFD' is control-j.) 1090Bindings are as follows: (Note: 'LFD' is control-j.)
1091\\{ada-mode-map}
964 1092
965 Indent line '\\[ada-tab]' 1093 Indent line '\\[ada-tab]'
966 Indent line, insert newline and indent the new line. '\\[newline-and-indent]' 1094 Indent line, insert newline and indent the new line. '\\[newline-and-indent]'
@@ -1005,11 +1133,6 @@ If you use ada-xref.el:
1005 1133
1006 (set (make-local-variable 'require-final-newline) t) 1134 (set (make-local-variable 'require-final-newline) t)
1007 1135
1008 (make-local-variable 'comment-start)
1009 (if ada-fill-comment-prefix
1010 (setq comment-start ada-fill-comment-prefix)
1011 (setq comment-start "-- "))
1012
1013 ;; Set the paragraph delimiters so that one can select a whole block 1136 ;; Set the paragraph delimiters so that one can select a whole block
1014 ;; simply with M-h 1137 ;; simply with M-h
1015 (set (make-local-variable 'paragraph-start) "[ \t\n\f]*$") 1138 (set (make-local-variable 'paragraph-start) "[ \t\n\f]*$")
@@ -1039,12 +1162,18 @@ If you use ada-xref.el:
1039 ;; Emacs 20.3 defines a comment-padding to insert spaces between 1162 ;; Emacs 20.3 defines a comment-padding to insert spaces between
1040 ;; the comment and the text. We do not want any, this is already 1163 ;; the comment and the text. We do not want any, this is already
1041 ;; included in comment-start 1164 ;; included in comment-start
1042 (set (make-local-variable 'comment-padding) 0) 1165 (unless ada-xemacs
1043 (set (make-local-variable 'parse-sexp-ignore-comments) t) 1166 (progn
1044 (set (make-local-variable 'parse-sexp-lookup-properties) t) 1167 (if (ada-check-emacs-version 20 3)
1168 (progn
1169 (set (make-local-variable 'parse-sexp-ignore-comments) t)
1170 (set (make-local-variable 'comment-padding) 0)))
1171 (set (make-local-variable 'parse-sexp-lookup-properties) t)
1172 ))
1045 1173
1046 (setq case-fold-search t) 1174 (set 'case-fold-search t)
1047 (setq imenu-case-fold-search t) 1175 (if (boundp 'imenu-case-fold-search)
1176 (set 'imenu-case-fold-search t))
1048 1177
1049 (set (make-local-variable 'fill-paragraph-function) 1178 (set (make-local-variable 'fill-paragraph-function)
1050 'ada-fill-comment-paragraph) 1179 'ada-fill-comment-paragraph)
@@ -1065,13 +1194,23 @@ If you use ada-xref.el:
1065 (define-key compilation-minor-mode-map "\C-m" 1194 (define-key compilation-minor-mode-map "\C-m"
1066 'ada-compile-goto-error))) 1195 'ada-compile-goto-error)))
1067 1196
1068 ;; font-lock support 1197 ;; font-lock support :
1069 (set (make-local-variable 'font-lock-defaults) 1198 ;; We need to set some properties for XEmacs, and define some variables
1070 '(ada-font-lock-keywords 1199 ;; for Emacs
1071 nil t 1200
1072 ((?\_ . "w") (?# . ".")) 1201 (if ada-xemacs
1073 beginning-of-line 1202 ;; XEmacs
1074 (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords))) 1203 (put 'ada-mode 'font-lock-defaults
1204 '(ada-font-lock-keywords
1205 nil t ((?\_ . "w") (?# . ".")) beginning-of-line))
1206 ;; Emacs
1207 (set (make-local-variable 'font-lock-defaults)
1208 '(ada-font-lock-keywords
1209 nil t
1210 ((?\_ . "w") (?# . "."))
1211 beginning-of-line
1212 (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords)))
1213 )
1075 1214
1076 ;; Set up support for find-file.el. 1215 ;; Set up support for find-file.el.
1077 (set (make-local-variable 'ff-other-file-alist) 1216 (set (make-local-variable 'ff-other-file-alist)
@@ -1094,7 +1233,7 @@ If you use ada-xref.el:
1094 "\\(body[ \t]+\\)?" 1233 "\\(body[ \t]+\\)?"
1095 "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is")) 1234 "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is"))
1096 (lambda () 1235 (lambda ()
1097 (setq fname (ff-get-file 1236 (set 'fname (ff-get-file
1098 ada-search-directories 1237 ada-search-directories
1099 (ada-make-filename-from-adaname 1238 (ada-make-filename-from-adaname
1100 (match-string 3)) 1239 (match-string 3))
@@ -1104,7 +1243,7 @@ If you use ada-xref.el:
1104 (add-to-list 'ff-special-constructs 1243 (add-to-list 'ff-special-constructs
1105 (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))" 1244 (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))"
1106 (lambda () 1245 (lambda ()
1107 (setq fname (ff-get-file 1246 (set 'fname (ff-get-file
1108 ada-search-directories 1247 ada-search-directories
1109 (ada-make-filename-from-adaname 1248 (ada-make-filename-from-adaname
1110 (match-string 1)) 1249 (match-string 1))
@@ -1119,7 +1258,7 @@ If you use ada-xref.el:
1119 (assoc "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)" ff-special-constructs)) 1258 (assoc "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)" ff-special-constructs))
1120 (new-cdr 1259 (new-cdr
1121 (lambda () 1260 (lambda ()
1122 (setq fname (ff-get-file 1261 (set 'fname (ff-get-file
1123 ada-search-directories 1262 ada-search-directories
1124 (ada-make-filename-from-adaname 1263 (ada-make-filename-from-adaname
1125 (match-string 1)) 1264 (match-string 1))
@@ -1138,6 +1277,24 @@ If you use ada-xref.el:
1138 ;; Support for imenu : We want a sorted index 1277 ;; Support for imenu : We want a sorted index
1139 (setq imenu-sort-function 'imenu--sort-by-name) 1278 (setq imenu-sort-function 'imenu--sort-by-name)
1140 1279
1280 ;; Support for ispell : Check only comments
1281 (set (make-local-variable 'ispell-check-comments) 'exclusive)
1282
1283 ;; Support for align.el <= 2.2, if present
1284 ;; align.el is distributed with Emacs 21, but not with earlier versions.
1285 (if (boundp 'align-mode-alist)
1286 (add-to-list 'align-mode-alist '(ada-mode . ada-align-list)))
1287
1288 ;; Support for align.el >= 2.8, if present
1289 (if (boundp 'align-dq-string-modes)
1290 (progn
1291 (add-to-list 'align-dq-string-modes 'ada-mode)
1292 (add-to-list 'align-open-comment-modes 'ada-mode)
1293 (set 'align-mode-rules-list ada-align-modes)
1294 (set (make-variable-buffer-local 'align-region-separate)
1295 ada-align-region-separate)
1296 ))
1297
1141 ;; Support for which-function-mode is provided in ada-support (support 1298 ;; Support for which-function-mode is provided in ada-support (support
1142 ;; for nested subprograms) 1299 ;; for nested subprograms)
1143 1300
@@ -1152,8 +1309,8 @@ If you use ada-xref.el:
1152 ;; Support for indent-new-comment-line (Especially for XEmacs) 1309 ;; Support for indent-new-comment-line (Especially for XEmacs)
1153 (setq comment-multi-line nil) 1310 (setq comment-multi-line nil)
1154 1311
1155 (setq major-mode 'ada-mode) 1312 (setq major-mode 'ada-mode
1156 (setq mode-name "Ada") 1313 mode-name "Ada")
1157 1314
1158 (use-local-map ada-mode-map) 1315 (use-local-map ada-mode-map)
1159 1316
@@ -1171,12 +1328,21 @@ If you use ada-xref.el:
1171 1328
1172 (run-hooks 'ada-mode-hook) 1329 (run-hooks 'ada-mode-hook)
1173 1330
1331 ;; To be run after the hook, in case the user modified
1332 ;; ada-fill-comment-prefix
1333 (make-local-variable 'comment-start)
1334 (if ada-fill-comment-prefix
1335 (set 'comment-start ada-fill-comment-prefix)
1336 (set 'comment-start "-- "))
1337
1174 ;; Run this after the hook to give the users a chance to activate 1338 ;; Run this after the hook to give the users a chance to activate
1175 ;; font-lock-mode 1339 ;; font-lock-mode
1176 1340
1177 (unless ada-xemacs 1341 (unless ada-xemacs
1178 (ada-initialize-properties) 1342 (progn
1179 (add-hook 'font-lock-mode-hook 'ada-deactivate-properties nil t)) 1343 (ada-initialize-properties)
1344 (make-local-hook 'font-lock-mode-hook)
1345 (add-hook 'font-lock-mode-hook 'ada-deactivate-properties nil t)))
1180 1346
1181 ;; the following has to be done after running the ada-mode-hook 1347 ;; the following has to be done after running the ada-mode-hook
1182 ;; because users might want to set the values of these variable 1348 ;; because users might want to set the values of these variable
@@ -1190,6 +1356,15 @@ If you use ada-xref.el:
1190 (if ada-auto-case 1356 (if ada-auto-case
1191 (ada-activate-keys-for-case))) 1357 (ada-activate-keys-for-case)))
1192 1358
1359
1360;; transient-mark-mode and mark-active are not defined in XEmacs
1361(defun ada-region-selected ()
1362 "t if a region has been selected by the user and is still active."
1363 (or (and ada-xemacs (funcall (symbol-function 'region-active-p)))
1364 (and (not ada-xemacs)
1365 (symbol-value 'transient-mark-mode)
1366 (symbol-value 'mark-active))))
1367
1193 1368
1194;;----------------------------------------------------------------- 1369;;-----------------------------------------------------------------
1195;; auto-casing 1370;; auto-casing
@@ -1205,6 +1380,23 @@ If you use ada-xref.el:
1205;; For backward compatibility, this variable can also be a string. 1380;; For backward compatibility, this variable can also be a string.
1206;;----------------------------------------------------------------- 1381;;-----------------------------------------------------------------
1207 1382
1383(defun ada-save-exceptions-to-file (file-name)
1384 "Save the exception lists `ada-case-exception' and
1385`ada-case-exception-substring' to the file FILE-NAME."
1386
1387 ;; Save the list in the file
1388 (find-file (expand-file-name file-name))
1389 (erase-buffer)
1390 (mapcar (lambda (x) (insert (car x) "\n"))
1391 (sort (copy-sequence ada-case-exception)
1392 (lambda(a b) (string< (car a) (car b)))))
1393 (mapcar (lambda (x) (insert "*" (car x) "\n"))
1394 (sort (copy-sequence ada-case-exception-substring)
1395 (lambda(a b) (string< (car a) (car b)))))
1396 (save-buffer)
1397 (kill-buffer nil)
1398 )
1399
1208(defun ada-create-case-exception (&optional word) 1400(defun ada-create-case-exception (&optional word)
1209 "Defines WORD as an exception for the casing system. 1401 "Defines WORD as an exception for the casing system.
1210If WORD is not given, then the current word in the buffer is used instead. 1402If WORD is not given, then the current word in the buffer is used instead.
@@ -1212,7 +1404,6 @@ The new words is added to the first file in `ada-case-exception-file'.
1212The standard casing rules will no longer apply to this word." 1404The standard casing rules will no longer apply to this word."
1213 (interactive) 1405 (interactive)
1214 (let ((previous-syntax-table (syntax-table)) 1406 (let ((previous-syntax-table (syntax-table))
1215 (exception-list '())
1216 file-name 1407 file-name
1217 ) 1408 )
1218 1409
@@ -1221,7 +1412,8 @@ The standard casing rules will no longer apply to this word."
1221 ((listp ada-case-exception-file) 1412 ((listp ada-case-exception-file)
1222 (setq file-name (car ada-case-exception-file))) 1413 (setq file-name (car ada-case-exception-file)))
1223 (t 1414 (t
1224 (error "No exception file specified"))) 1415 (error (concat "No exception file specified. "
1416 "See variable ada-case-exception-file."))))
1225 1417
1226 (set-syntax-table ada-mode-symbol-syntax-table) 1418 (set-syntax-table ada-mode-symbol-syntax-table)
1227 (unless word 1419 (unless word
@@ -1229,55 +1421,76 @@ The standard casing rules will no longer apply to this word."
1229 (skip-syntax-backward "w") 1421 (skip-syntax-backward "w")
1230 (setq word (buffer-substring-no-properties 1422 (setq word (buffer-substring-no-properties
1231 (point) (save-excursion (forward-word 1) (point)))))) 1423 (point) (save-excursion (forward-word 1) (point))))))
1424 (set-syntax-table previous-syntax-table)
1232 1425
1233 ;; Reread the exceptions file, in case it was modified by some other, 1426 ;; Reread the exceptions file, in case it was modified by some other,
1234 ;; and to keep the end-of-line comments that may exist in it. 1427 (ada-case-read-exceptions-from-file file-name)
1235 (if (file-readable-p (expand-file-name file-name))
1236 (let ((buffer (current-buffer)))
1237 (find-file (expand-file-name file-name))
1238 (set-syntax-table ada-mode-symbol-syntax-table)
1239 (widen)
1240 (goto-char (point-min))
1241 (while (not (eobp))
1242 (add-to-list 'exception-list
1243 (list
1244 (buffer-substring-no-properties
1245 (point) (save-excursion (forward-word 1) (point)))
1246 (buffer-substring-no-properties
1247 (save-excursion (forward-word 1) (point))
1248 (save-excursion (end-of-line) (point)))
1249 t))
1250 (forward-line 1))
1251 (kill-buffer nil)
1252 (set-buffer buffer)))
1253 1428
1254 ;; If the word is already in the list, even with a different casing 1429 ;; If the word is already in the list, even with a different casing
1255 ;; we simply want to replace it. 1430 ;; we simply want to replace it.
1256 (if (and (not (equal exception-list '()))
1257 (assoc-ignore-case word exception-list))
1258 (setcar (assoc-ignore-case word exception-list)
1259 word)
1260 (add-to-list 'exception-list (list word "" t))
1261 )
1262
1263 (if (and (not (equal ada-case-exception '())) 1431 (if (and (not (equal ada-case-exception '()))
1264 (assoc-ignore-case word ada-case-exception)) 1432 (assoc-ignore-case word ada-case-exception))
1265 (setcar (assoc-ignore-case word ada-case-exception) 1433 (setcar (assoc-ignore-case word ada-case-exception) word)
1266 word)
1267 (add-to-list 'ada-case-exception (cons word t)) 1434 (add-to-list 'ada-case-exception (cons word t))
1268 ) 1435 )
1269 1436
1270 ;; Save the list in the file 1437 (ada-save-exceptions-to-file file-name)
1271 (find-file (expand-file-name file-name))
1272 (erase-buffer)
1273 (mapcar (lambda (x) (insert (car x) (nth 1 x) "\n"))
1274 (sort exception-list
1275 (lambda(a b) (string< (car a) (car b)))))
1276 (save-buffer)
1277 (kill-buffer nil)
1278 (set-syntax-table previous-syntax-table)
1279 )) 1438 ))
1280 1439
1440(defun ada-create-case-exception-substring (&optional word)
1441 "Defines the substring WORD as an exception for the casing system.
1442If WORD is not given, then the current word in the buffer is used instead,
1443or the selected region if any is active.
1444The new words is added to the first file in `ada-case-exception-file'.
1445When auto-casing a word, this substring will be special-cased, unless the
1446word itself has a special casing."
1447 (interactive)
1448 (let ((file-name
1449 (cond ((stringp ada-case-exception-file)
1450 ada-case-exception-file)
1451 ((listp ada-case-exception-file)
1452 (car ada-case-exception-file))
1453 (t
1454 (error (concat "No exception file specified. "
1455 "See variable ada-case-exception-file."))))))
1456
1457 ;; Find the substring to define as an exception. Order is: the parameter,
1458 ;; if any, or the selected region, or the word under the cursor
1459 (cond
1460 (word nil)
1461
1462 ((ada-region-selected)
1463 (setq word (buffer-substring-no-properties
1464 (region-beginning) (region-end))))
1465
1466 (t
1467 (let ((underscore-syntax (char-syntax ?_)))
1468 (unwind-protect
1469 (progn
1470 (modify-syntax-entry ?_ "." (syntax-table))
1471 (save-excursion
1472 (skip-syntax-backward "w")
1473 (set 'word (buffer-substring-no-properties
1474 (point)
1475 (save-excursion (forward-word 1) (point))))))
1476 (modify-syntax-entry ?_ (make-string 1 underscore-syntax)
1477 (syntax-table))))))
1478
1479 ;; Reread the exceptions file, in case it was modified by some other,
1480 (ada-case-read-exceptions-from-file file-name)
1481
1482 ;; If the word is already in the list, even with a different casing
1483 ;; we simply want to replace it.
1484 (if (and (not (equal ada-case-exception-substring '()))
1485 (assoc-ignore-case word ada-case-exception-substring))
1486 (setcar (assoc-ignore-case word ada-case-exception-substring) word)
1487 (add-to-list 'ada-case-exception-substring (cons word t))
1488 )
1489
1490 (ada-save-exceptions-to-file file-name)
1491
1492 (message (concat "Defining " word " as a casing exception"))))
1493
1281(defun ada-case-read-exceptions-from-file (file-name) 1494(defun ada-case-read-exceptions-from-file (file-name)
1282 "Read the content of the casing exception file FILE-NAME." 1495 "Read the content of the casing exception file FILE-NAME."
1283 (if (file-readable-p (expand-file-name file-name)) 1496 (if (file-readable-p (expand-file-name file-name))
@@ -1293,8 +1506,15 @@ The standard casing rules will no longer apply to this word."
1293 ;; priority should be applied to each casing exception 1506 ;; priority should be applied to each casing exception
1294 (let ((word (buffer-substring-no-properties 1507 (let ((word (buffer-substring-no-properties
1295 (point) (save-excursion (forward-word 1) (point))))) 1508 (point) (save-excursion (forward-word 1) (point)))))
1296 (unless (assoc-ignore-case word ada-case-exception) 1509
1297 (add-to-list 'ada-case-exception (cons word t)))) 1510 ;; Handling a substring ?
1511 (if (char-equal (string-to-char word) ?*)
1512 (progn
1513 (setq word (substring word 1))
1514 (unless (assoc-ignore-case word ada-case-exception-substring)
1515 (add-to-list 'ada-case-exception-substring (cons word t))))
1516 (unless (assoc-ignore-case word ada-case-exception)
1517 (add-to-list 'ada-case-exception (cons word t)))))
1298 1518
1299 (forward-line 1)) 1519 (forward-line 1))
1300 (kill-buffer nil) 1520 (kill-buffer nil)
@@ -1306,7 +1526,8 @@ The standard casing rules will no longer apply to this word."
1306 (interactive) 1526 (interactive)
1307 1527
1308 ;; Reinitialize the casing exception list 1528 ;; Reinitialize the casing exception list
1309 (setq ada-case-exception '()) 1529 (setq ada-case-exception '()
1530 ada-case-exception-substring '())
1310 1531
1311 (cond ((stringp ada-case-exception-file) 1532 (cond ((stringp ada-case-exception-file)
1312 (ada-case-read-exceptions-from-file ada-case-exception-file)) 1533 (ada-case-read-exceptions-from-file ada-case-exception-file))
@@ -1315,6 +1536,34 @@ The standard casing rules will no longer apply to this word."
1315 (mapcar 'ada-case-read-exceptions-from-file 1536 (mapcar 'ada-case-read-exceptions-from-file
1316 ada-case-exception-file)))) 1537 ada-case-exception-file))))
1317 1538
1539(defun ada-adjust-case-substring ()
1540 "Adjust case of substrings in the previous word."
1541 (interactive)
1542 (let ((substrings ada-case-exception-substring)
1543 (max (point))
1544 (case-fold-search t)
1545 (underscore-syntax (char-syntax ?_))
1546 re)
1547
1548 (save-excursion
1549 (forward-word -1)
1550
1551 (unwind-protect
1552 (progn
1553 (modify-syntax-entry ?_ "." (syntax-table))
1554
1555 (while substrings
1556 (setq re (concat "\\b" (regexp-quote (caar substrings)) "\\b"))
1557
1558 (save-excursion
1559 (while (re-search-forward re max t)
1560 (replace-match (caar substrings))))
1561 (setq substrings (cdr substrings))
1562 )
1563 )
1564 (modify-syntax-entry ?_ (make-string 1 underscore-syntax) (syntax-table)))
1565 )))
1566
1318(defun ada-adjust-case-identifier () 1567(defun ada-adjust-case-identifier ()
1319 "Adjust case of the previous identifier. 1568 "Adjust case of the previous identifier.
1320The auto-casing is done according to the value of `ada-case-identifier' and 1569The auto-casing is done according to the value of `ada-case-identifier' and
@@ -1322,7 +1571,9 @@ the exceptions defined in `ada-case-exception-file'."
1322 (interactive) 1571 (interactive)
1323 (if (or (equal ada-case-exception '()) 1572 (if (or (equal ada-case-exception '())
1324 (equal (char-after) ?_)) 1573 (equal (char-after) ?_))
1325 (funcall ada-case-identifier -1) 1574 (progn
1575 (funcall ada-case-identifier -1)
1576 (ada-adjust-case-substring))
1326 1577
1327 (progn 1578 (progn
1328 (let ((end (point)) 1579 (let ((end (point))
@@ -1338,7 +1589,8 @@ the exceptions defined in `ada-case-exception-file'."
1338 (insert (car match))) 1589 (insert (car match)))
1339 1590
1340 ;; Else simply re-case the word 1591 ;; Else simply re-case the word
1341 (funcall ada-case-identifier -1)))))) 1592 (funcall ada-case-identifier -1)
1593 (ada-adjust-case-substring))))))
1342 1594
1343(defun ada-after-keyword-p () 1595(defun ada-after-keyword-p ()
1344 "Returns t if cursor is after a keyword that is not an attribute." 1596 "Returns t if cursor is after a keyword that is not an attribute."
@@ -1352,28 +1604,31 @@ the exceptions defined in `ada-case-exception-file'."
1352(defun ada-adjust-case (&optional force-identifier) 1604(defun ada-adjust-case (&optional force-identifier)
1353 "Adjust the case of the word before the just typed character. 1605 "Adjust the case of the word before the just typed character.
1354If FORCE-IDENTIFIER is non-nil then also adjust keyword as identifier." 1606If FORCE-IDENTIFIER is non-nil then also adjust keyword as identifier."
1355 (forward-char -1) 1607 (if (not (bobp))
1356 (if (and (> (point) 1) 1608 (progn
1357 ;; or if at the end of a character constant 1609 (forward-char -1)
1358 (not (and (eq (char-after) ?') 1610 (if (and (not (bobp))
1359 (eq (char-before (1- (point))) ?'))) 1611 ;; or if at the end of a character constant
1360 ;; or if the previous character was not part of a word 1612 (not (and (eq (following-char) ?')
1361 (eq (char-syntax (char-before)) ?w) 1613 (eq (char-before (1- (point))) ?')))
1362 ;; if in a string or a comment 1614 ;; or if the previous character was not part of a word
1363 (not (ada-in-string-or-comment-p)) 1615 (eq (char-syntax (char-before)) ?w)
1364 ) 1616 ;; if in a string or a comment
1365 (if (save-excursion 1617 (not (ada-in-string-or-comment-p))
1366 (forward-word -1) 1618 )
1367 (or (= (point) (point-min)) 1619 (if (save-excursion
1368 (backward-char 1)) 1620 (forward-word -1)
1369 (= (char-after) ?')) 1621 (or (= (point) (point-min))
1370 (funcall ada-case-attribute -1) 1622 (backward-char 1))
1371 (if (and 1623 (= (following-char) ?'))
1372 (not force-identifier) ; (MH) 1624 (funcall ada-case-attribute -1)
1373 (ada-after-keyword-p)) 1625 (if (and
1374 (funcall ada-case-keyword -1) 1626 (not force-identifier) ; (MH)
1375 (ada-adjust-case-identifier)))) 1627 (ada-after-keyword-p))
1376 (forward-char 1) 1628 (funcall ada-case-keyword -1)
1629 (ada-adjust-case-identifier))))
1630 (forward-char 1)
1631 ))
1377 ) 1632 )
1378 1633
1379(defun ada-adjust-case-interactive (arg) 1634(defun ada-adjust-case-interactive (arg)
@@ -1880,20 +2135,23 @@ This function is intended to be bound to the \C-m and \C-j keys."
1880 2135
1881 (let ((cur-indent (ada-indent-current))) 2136 (let ((cur-indent (ada-indent-current)))
1882 2137
1883 (message nil) 2138 (let ((line (save-excursion
1884 (if (equal (cdr cur-indent) '(0)) 2139 (goto-char (car cur-indent))
1885 (message "same indentation") 2140 (count-lines (point-min) (point)))))
1886 (message (mapconcat (lambda(x) 2141
1887 (cond 2142 (if (equal (cdr cur-indent) '(0))
1888 ((symbolp x) 2143 (message (concat "same indentation as line " (number-to-string line)))
1889 (symbol-name x)) 2144 (message (mapconcat (lambda(x)
1890 ((numberp x) 2145 (cond
1891 (number-to-string x)) 2146 ((symbolp x)
1892 ((listp x) 2147 (symbol-name x))
1893 (concat "- " (symbol-name (cadr x)))) 2148 ((numberp x)
1894 )) 2149 (number-to-string x))
1895 (cdr cur-indent) 2150 ((listp x)
1896 " + "))) 2151 (concat "- " (symbol-name (cadr x))))
2152 ))
2153 (cdr cur-indent)
2154 " + "))))
1897 (save-excursion 2155 (save-excursion
1898 (goto-char (car cur-indent)) 2156 (goto-char (car cur-indent))
1899 (sit-for 1)))) 2157 (sit-for 1))))
@@ -2016,13 +2274,41 @@ offset."
2016 ;; check if we have something like this (Table_Component_Type => 2274 ;; check if we have something like this (Table_Component_Type =>
2017 ;; Source_File_Record) 2275 ;; Source_File_Record)
2018 (save-excursion 2276 (save-excursion
2019 (if (and (skip-chars-backward " \t") 2277
2020 (= (char-before) ?\n) 2278 ;; Align the closing parenthesis on the opening one
2021 (not (forward-comment -10000)) 2279 (if (= (following-char) ?\))
2022 (= (char-before) ?>)) 2280 (save-excursion
2023 ;; ??? Could use a different variable 2281 (goto-char column)
2024 (list column 'ada-broken-indent) 2282 (skip-chars-backward " \t")
2025 (list column 0)))) 2283 (list (1- (point)) 0))
2284
2285 (if (and (skip-chars-backward " \t")
2286 (= (char-before) ?\n)
2287 (not (forward-comment -10000))
2288 (= (char-before) ?>))
2289 ;; ??? Could use a different variable
2290 (list column 'ada-broken-indent)
2291
2292 ;; Correctly indent named parameter lists ("name => ...") for
2293 ;; all the following lines
2294 (goto-char column)
2295 (if (and (progn (forward-comment 1000)
2296 (looking-at "\\sw+\\s *=>"))
2297 (progn (goto-char orgpoint)
2298 (forward-comment 1000)
2299 (not (looking-at "\\sw+\\s *=>"))))
2300 (list column 'ada-broken-indent)
2301
2302 ;; ??? Would be nice that lines like
2303 ;; A
2304 ;; (B,
2305 ;; C
2306 ;; (E)); -- would be nice if this was correctly indented
2307; (if (= (char-before (1- orgpoint)) ?,)
2308 (list column 0)
2309; (list column 'ada-broken-indent)
2310; )
2311 )))))
2026 2312
2027 ;;--------------------------- 2313 ;;---------------------------
2028 ;; at end of buffer 2314 ;; at end of buffer
@@ -2035,7 +2321,7 @@ offset."
2035 ;; starting with e 2321 ;; starting with e
2036 ;;--------------------------- 2322 ;;---------------------------
2037 2323
2038 ((= (char-after) ?e) 2324 ((= (downcase (char-after)) ?e)
2039 (cond 2325 (cond
2040 2326
2041 ;; ------- end ------ 2327 ;; ------- end ------
@@ -2068,8 +2354,25 @@ offset."
2068 (beginning-of-line) 2354 (beginning-of-line)
2069 (if (looking-at ada-named-block-re) 2355 (if (looking-at ada-named-block-re)
2070 (setq label (- ada-label-indent)))))))) 2356 (setq label (- ada-label-indent))))))))
2071 2357
2072 (list (+ (save-excursion (back-to-indentation) (point)) label) 0)))) 2358 ;; found 'record' =>
2359 ;; if the keyword is found at the beginning of a line (or just
2360 ;; after limited, we indent on it, otherwise we indent on the
2361 ;; beginning of the type declaration)
2362 ;; type A is (B : Integer;
2363 ;; C : Integer) is record
2364 ;; end record; -- This is badly indented otherwise
2365 (if (looking-at "record")
2366 (if (save-excursion
2367 (beginning-of-line)
2368 (looking-at "^[ \t]*\\(record\\|limited record\\)"))
2369 (list (save-excursion (back-to-indentation) (point)) 0)
2370 (list (save-excursion
2371 (car (ada-search-ignore-string-comment "\\<type\\>" t)))
2372 0))
2373
2374 ;; Else keep the same indentation as the beginning statement
2375 (list (+ (save-excursion (back-to-indentation) (point)) label) 0)))))
2073 2376
2074 ;; ------ exception ---- 2377 ;; ------ exception ----
2075 2378
@@ -2089,7 +2392,7 @@ offset."
2089 (list (progn (back-to-indentation) (point)) 0)))) 2392 (list (progn (back-to-indentation) (point)) 0))))
2090 2393
2091 ;; elsif 2394 ;; elsif
2092 2395
2093 ((looking-at "elsif\\>") 2396 ((looking-at "elsif\\>")
2094 (save-excursion 2397 (save-excursion
2095 (ada-goto-matching-start 1 nil t) 2398 (ada-goto-matching-start 1 nil t)
@@ -2100,8 +2403,8 @@ offset."
2100 ;;--------------------------- 2403 ;;---------------------------
2101 ;; starting with w (when) 2404 ;; starting with w (when)
2102 ;;--------------------------- 2405 ;;---------------------------
2103 2406
2104 ((and (= (char-after) ?w) 2407 ((and (= (downcase (char-after)) ?w)
2105 (looking-at "when\\>")) 2408 (looking-at "when\\>"))
2106 (save-excursion 2409 (save-excursion
2107 (ada-goto-matching-start 1) 2410 (ada-goto-matching-start 1)
@@ -2112,7 +2415,7 @@ offset."
2112 ;; starting with t (then) 2415 ;; starting with t (then)
2113 ;;--------------------------- 2416 ;;---------------------------
2114 2417
2115 ((and (= (char-after) ?t) 2418 ((and (= (downcase (char-after)) ?t)
2116 (looking-at "then\\>")) 2419 (looking-at "then\\>"))
2117 (if (save-excursion (ada-goto-previous-word) 2420 (if (save-excursion (ada-goto-previous-word)
2118 (looking-at "and\\>")) 2421 (looking-at "and\\>"))
@@ -2127,8 +2430,8 @@ offset."
2127 ;;--------------------------- 2430 ;;---------------------------
2128 ;; starting with l (loop) 2431 ;; starting with l (loop)
2129 ;;--------------------------- 2432 ;;---------------------------
2130 2433
2131 ((and (= (char-after) ?l) 2434 ((and (= (downcase (char-after)) ?l)
2132 (looking-at "loop\\>")) 2435 (looking-at "loop\\>"))
2133 (setq pos (point)) 2436 (setq pos (point))
2134 (save-excursion 2437 (save-excursion
@@ -2143,11 +2446,29 @@ offset."
2143 (ada-indent-on-previous-lines nil orgpoint orgpoint) 2446 (ada-indent-on-previous-lines nil orgpoint orgpoint)
2144 (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent))))) 2447 (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent)))))
2145 2448
2449 ;;----------------------------
2450 ;; starting with l (limited) or r (record)
2451 ;;----------------------------
2452
2453 ((or (and (= (downcase (char-after)) ?l)
2454 (looking-at "limited\\>"))
2455 (and (= (downcase (char-after)) ?r)
2456 (looking-at "record\\>")))
2457
2458 (save-excursion
2459 (ada-search-ignore-string-comment
2460 "\\<\\(type\\|use\\)\\>" t nil)
2461 (if (looking-at "\\<use\\>")
2462 (ada-search-ignore-string-comment "for" t nil nil
2463 'word-search-backward))
2464 (list (progn (back-to-indentation) (point))
2465 'ada-indent-record-rel-type)))
2466
2146 ;;--------------------------- 2467 ;;---------------------------
2147 ;; starting with b (begin) 2468 ;; starting with b (begin)
2148 ;;--------------------------- 2469 ;;---------------------------
2149 2470
2150 ((and (= (char-after) ?b) 2471 ((and (= (downcase (char-after)) ?b)
2151 (looking-at "begin\\>")) 2472 (looking-at "begin\\>"))
2152 (save-excursion 2473 (save-excursion
2153 (if (ada-goto-matching-decl-start t) 2474 (if (ada-goto-matching-decl-start t)
@@ -2158,7 +2479,7 @@ offset."
2158 ;; starting with i (is) 2479 ;; starting with i (is)
2159 ;;--------------------------- 2480 ;;---------------------------
2160 2481
2161 ((and (= (char-after) ?i) 2482 ((and (= (downcase (char-after)) ?i)
2162 (looking-at "is\\>")) 2483 (looking-at "is\\>"))
2163 2484
2164 (if (and ada-indent-is-separate 2485 (if (and ada-indent-is-separate
@@ -2175,93 +2496,79 @@ offset."
2175 (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent)))) 2496 (list (progn (back-to-indentation) (point)) 'ada-stmt-end-indent))))
2176 2497
2177 ;;--------------------------- 2498 ;;---------------------------
2178 ;; starting with r (record, return, renames) 2499 ;; starting with r (return, renames)
2179 ;;--------------------------- 2500 ;;---------------------------
2180 2501
2181 ((= (char-after) ?r) 2502 ((and (= (downcase (char-after)) ?r)
2182 2503 (looking-at "re\\(turn\\|names\\)\\>"))
2183 (cond 2504
2184 2505 (save-excursion
2185 ;; ----- record ------ 2506 (let ((var 'ada-indent-return))
2186 2507 ;; If looking at a renames, skip the 'return' statement too
2187 ((looking-at "record\\>") 2508 (if (looking-at "renames")
2188 (save-excursion 2509 (let (pos)
2189 (ada-search-ignore-string-comment 2510 (save-excursion
2190 "\\<\\(type\\|use\\)\\>" t nil) 2511 (set 'pos (ada-search-ignore-string-comment ";\\|return\\>" t)))
2191 (if (looking-at "\\<use\\>") 2512 (if (and pos
2192 (ada-search-ignore-string-comment "for" t nil nil 'word-search-backward)) 2513 (= (downcase (char-after (car pos))) ?r))
2193 (list (progn (back-to-indentation) (point)) 'ada-indent-record-rel-type))) 2514 (goto-char (car pos)))
2194 2515 (set 'var 'ada-indent-renames)))
2195 ;; ----- return or renames ------ 2516
2196 2517 (forward-comment -1000)
2197 ((looking-at "re\\(turn\\|names\\)\\>") 2518 (if (= (char-before) ?\))
2198 (save-excursion 2519 (forward-sexp -1)
2199 (let ((var 'ada-indent-return)) 2520 (forward-word -1))
2200 ;; If looking at a renames, skip the 'return' statement too 2521
2201 (if (looking-at "renames") 2522 ;; If there is a parameter list, and we have a function declaration
2202 (let (pos) 2523 ;; or a access to subprogram declaration
2203 (save-excursion 2524 (let ((num-back 1))
2204 (setq pos (ada-search-ignore-string-comment ";\\|return\\>" t))) 2525 (if (and (= (following-char) ?\()
2205 (if (and pos 2526 (save-excursion
2206 (= (char-after (car pos)) ?r)) 2527 (or (progn
2207 (goto-char (car pos))) 2528 (backward-word 1)
2208 (setq var 'ada-indent-renames))) 2529 (looking-at "\\(function\\|procedure\\)\\>"))
2209 2530 (progn
2210 (forward-comment -1000) 2531 (backward-word 1)
2211 (if (= (char-before) ?\)) 2532 (set 'num-back 2)
2212 (forward-sexp -1) 2533 (looking-at "\\(function\\|procedure\\)\\>")))))
2213 (forward-word -1)) 2534
2214 2535 ;; The indentation depends of the value of ada-indent-return
2215 ;; If there is a parameter list, and we have a function declaration 2536 (if (<= (eval var) 0)
2216 ;; or a access to subprogram declaration 2537 (list (point) (list '- var))
2217 (let ((num-back 1)) 2538 (list (progn (backward-word num-back) (point))
2218 (if (and (= (char-after) ?\() 2539 var))
2219 (save-excursion 2540
2220 (or (progn 2541 ;; Else there is no parameter list, but we have a function
2221 (backward-word 1) 2542 ;; Only do something special if the user want to indent
2222 (looking-at "function\\>")) 2543 ;; relative to the "function" keyword
2223 (progn 2544 (if (and (> (eval var) 0)
2224 (backward-word 1) 2545 (save-excursion (forward-word -1)
2225 (setq num-back 2) 2546 (looking-at "function\\>")))
2226 (looking-at "function\\>"))))) 2547 (list (progn (forward-word -1) (point)) var)
2227 2548
2228 ;; The indentation depends of the value of ada-indent-return 2549 ;; Else...
2229 (if (<= (eval var) 0) 2550 (ada-indent-on-previous-lines nil orgpoint orgpoint)))))))
2230 (list (point) (list '- var)) 2551
2231 (list (progn (backward-word num-back) (point))
2232 var))
2233
2234 ;; Else there is no parameter list, but we have a function
2235 ;; Only do something special if the user want to indent
2236 ;; relative to the "function" keyword
2237 (if (and (> (eval var) 0)
2238 (save-excursion (forward-word -1)
2239 (looking-at "function\\>")))
2240 (list (progn (forward-word -1) (point)) var)
2241
2242 ;; Else...
2243 (ada-indent-on-previous-lines nil orgpoint orgpoint)))))))
2244 ))
2245
2246 ;;-------------------------------- 2552 ;;--------------------------------
2247 ;; starting with 'o' or 'p' 2553 ;; starting with 'o' or 'p'
2248 ;; 'or' as statement-start 2554 ;; 'or' as statement-start
2249 ;; 'private' as statement-start 2555 ;; 'private' as statement-start
2250 ;;-------------------------------- 2556 ;;--------------------------------
2251 2557
2252 ((and (or (= (char-after) ?o) 2558 ((and (or (= (downcase (char-after)) ?o)
2253 (= (char-after) ?p)) 2559 (= (downcase (char-after)) ?p))
2254 (or (ada-looking-at-semi-or) 2560 (or (ada-looking-at-semi-or)
2255 (ada-looking-at-semi-private))) 2561 (ada-looking-at-semi-private)))
2256 (save-excursion 2562 (save-excursion
2257 (ada-goto-matching-start 1) 2563 ;; ??? Wasn't this done already in ada-looking-at-semi-or ?
2258 (list (progn (back-to-indentation) (point)) 0))) 2564 (ada-goto-matching-start 1)
2565 (list (progn (back-to-indentation) (point)) 0)))
2259 2566
2260 ;;-------------------------------- 2567 ;;--------------------------------
2261 ;; starting with 'd' (do) 2568 ;; starting with 'd' (do)
2262 ;;-------------------------------- 2569 ;;--------------------------------
2263 2570
2264 ((and (= (char-after) ?d) 2571 ((and (= (downcase (char-after)) ?d)
2265 (looking-at "do\\>")) 2572 (looking-at "do\\>"))
2266 (save-excursion 2573 (save-excursion
2267 (ada-goto-stmt-start) 2574 (ada-goto-stmt-start)
@@ -2329,7 +2636,7 @@ offset."
2329 ;; package/function/procedure 2636 ;; package/function/procedure
2330 ;;--------------------------------- 2637 ;;---------------------------------
2331 2638
2332 ((and (or (= (char-after) ?p) (= (char-after) ?f)) 2639 ((and (or (= (downcase (char-after)) ?p) (= (downcase (char-after)) ?f))
2333 (looking-at "\\<\\(package\\|function\\|procedure\\)\\>")) 2640 (looking-at "\\<\\(package\\|function\\|procedure\\)\\>"))
2334 (save-excursion 2641 (save-excursion
2335 ;; Go up until we find either a generic section, or the end of the 2642 ;; Go up until we find either a generic section, or the end of the
@@ -2467,11 +2774,17 @@ if INITIAL-POS is non-nil, moves point to INITIAL-POS before calculation."
2467 (ada-goto-next-non-ws) 2774 (ada-goto-next-non-ws)
2468 (list (point) 0)) 2775 (list (point) 0))
2469 2776
2777 ;; After an affectation (default parameter value in subprogram
2778 ;; declaration)
2779 ((and (= (following-char) ?=) (= (preceding-char) ?:))
2780 (back-to-indentation)
2781 (list (point) 'ada-broken-indent))
2782
2470 ;; inside a parameter declaration 2783 ;; inside a parameter declaration
2471 (t 2784 (t
2472 (goto-char (cdr (ada-search-ignore-string-comment "(\\|;" t nil t))) 2785 (goto-char (cdr (ada-search-ignore-string-comment "(\\|;" t nil t)))
2473 (ada-goto-next-non-ws) 2786 (ada-goto-next-non-ws)
2474 (list (point) 'ada-broken-indent))))) 2787 (list (point) 0)))))
2475 2788
2476(defun ada-get-indent-end (orgpoint) 2789(defun ada-get-indent-end (orgpoint)
2477 "Calculates the indentation when point is just before an end_statement. 2790 "Calculates the indentation when point is just before an end_statement.
@@ -2526,7 +2839,9 @@ ORGPOINT is the limit position used in the calculation."
2526 (setq indent (list (point) 0)) 2839 (setq indent (list (point) 0))
2527 (if (ada-goto-matching-decl-start t) 2840 (if (ada-goto-matching-decl-start t)
2528 (list (progn (back-to-indentation) (point)) 0) 2841 (list (progn (back-to-indentation) (point)) 0)
2529 indent))))) 2842 indent))
2843 (list (progn (back-to-indentation) (point)) 0)
2844 )))
2530 ;; 2845 ;;
2531 ;; anything else - should maybe signal an error ? 2846 ;; anything else - should maybe signal an error ?
2532 ;; 2847 ;;
@@ -2599,7 +2914,7 @@ ORGPOINT is the limit position used in the calculation."
2599 (while (and (setq match-cons (ada-search-ignore-string-comment 2914 (while (and (setq match-cons (ada-search-ignore-string-comment
2600 "\\<\\(then\\|and[ \t]*then\\)\\>" 2915 "\\<\\(then\\|and[ \t]*then\\)\\>"
2601 nil orgpoint)) 2916 nil orgpoint))
2602 (= (char-after (car match-cons)) ?a))) 2917 (= (downcase (char-after (car match-cons))) ?a)))
2603 ;; If "then" was found (we are looking at it) 2918 ;; If "then" was found (we are looking at it)
2604 (if match-cons 2919 (if match-cons
2605 (progn 2920 (progn
@@ -2630,6 +2945,23 @@ ORGPOINT is the limit position used in the calculation."
2630 (save-excursion 2945 (save-excursion
2631 (ada-indent-on-previous-lines t orgpoint))) 2946 (ada-indent-on-previous-lines t orgpoint)))
2632 2947
2948 ;; Special case for record types, for instance for:
2949 ;; type A is (B : Integer;
2950 ;; C : Integer) is record
2951 ;; null; -- This is badly indented otherwise
2952 ((looking-at "record")
2953
2954 ;; If record is at the beginning of the line, indent from there
2955 (if (save-excursion
2956 (beginning-of-line)
2957 (looking-at "^[ \t]*\\(record\\|limited record\\)"))
2958 (list (save-excursion (back-to-indentation) (point)) 'ada-indent)
2959
2960 ;; else indent relative to the type command
2961 (list (save-excursion
2962 (car (ada-search-ignore-string-comment "\\<type\\>" t)))
2963 'ada-indent)))
2964
2633 ;; nothing follows the block-start 2965 ;; nothing follows the block-start
2634 (t 2966 (t
2635 (list (save-excursion (back-to-indentation) (point)) 'ada-indent))))) 2967 (list (save-excursion (back-to-indentation) (point)) 'ada-indent)))))
@@ -3154,6 +3486,9 @@ Moves point to the beginning of the declaration."
3154 "Moves point to the matching declaration start of the current 'begin'. 3486 "Moves point to the matching declaration start of the current 'begin'.
3155If NOERROR is non-nil, it only returns nil if no match was found." 3487If NOERROR is non-nil, it only returns nil if no match was found."
3156 (let ((nest-count 1) 3488 (let ((nest-count 1)
3489
3490 ;; first should be set to t if we should stop at the first
3491 ;; "begin" we encounter.
3157 (first (not recursive)) 3492 (first (not recursive))
3158 (count-generic nil) 3493 (count-generic nil)
3159 (stop-at-when nil) 3494 (stop-at-when nil)
@@ -3210,7 +3545,8 @@ If NOERROR is non-nil, it only returns nil if no match was found."
3210 t) 3545 t)
3211 3546
3212 (if (looking-at "end") 3547 (if (looking-at "end")
3213 (ada-goto-matching-decl-start noerror t) 3548 (ada-goto-matching-start 1 noerror t)
3549 ;; (ada-goto-matching-decl-start noerror t)
3214 3550
3215 (setq loop-again nil) 3551 (setq loop-again nil)
3216 (unless (looking-at "begin") 3552 (unless (looking-at "begin")
@@ -3235,7 +3571,7 @@ If NOERROR is non-nil, it only returns nil if no match was found."
3235 ;; 3571 ;;
3236 ((looking-at "declare\\|generic") 3572 ((looking-at "declare\\|generic")
3237 (setq nest-count (1- nest-count)) 3573 (setq nest-count (1- nest-count))
3238 (setq first nil)) 3574 (setq first t))
3239 ;; 3575 ;;
3240 ((looking-at "is") 3576 ((looking-at "is")
3241 ;; check if it is only a type definition, but not a protected 3577 ;; check if it is only a type definition, but not a protected
@@ -3279,9 +3615,16 @@ If NOERROR is non-nil, it only returns nil if no match was found."
3279 (setq nest-count 0)) 3615 (setq nest-count 0))
3280 ;; 3616 ;;
3281 ((looking-at "when") 3617 ((looking-at "when")
3282 (if stop-at-when 3618 (save-excursion
3283 (setq nest-count (1- nest-count))) 3619 (forward-word -1)
3284 (setq first nil)) 3620 (unless (looking-at "\\<exit[ \t\n]*when\\>")
3621 (progn
3622 (if stop-at-when
3623 (setq nest-count (1- nest-count)))
3624 (setq first nil)))))
3625 ;;
3626 ((looking-at "begin")
3627 (setq first nil))
3285 ;; 3628 ;;
3286 (t 3629 (t
3287 (setq nest-count (1+ nest-count)) 3630 (setq nest-count (1+ nest-count))
@@ -3340,9 +3683,9 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
3340 (ada-goto-previous-word) 3683 (ada-goto-previous-word)
3341 (if (looking-at "\\<end\\>[ \t]*[^;]") 3684 (if (looking-at "\\<end\\>[ \t]*[^;]")
3342 ;; it ends a block => increase nest depth 3685 ;; it ends a block => increase nest depth
3343 (progn 3686 (setq nest-count (1+ nest-count)
3344 (setq nest-count (1+ nest-count)) 3687 pos (point))
3345 (setq pos (point))) 3688
3346 ;; it starts a block => decrease nest depth 3689 ;; it starts a block => decrease nest depth
3347 (setq nest-count (1- nest-count)))) 3690 (setq nest-count (1- nest-count))))
3348 (goto-char pos)) 3691 (goto-char pos))
@@ -3366,7 +3709,11 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
3366 (forward-word 1) 3709 (forward-word 1)
3367 (ada-goto-next-non-ws) 3710 (ada-goto-next-non-ws)
3368 ;; ignore it if it is only a declaration with 'new' 3711 ;; ignore it if it is only a declaration with 'new'
3369 (if (not (looking-at "\\<\\(new\\|separate\\)\\>")) 3712 ;; We could have package Foo is new ....
3713 ;; or package Foo is separate;
3714 ;; or package Foo is begin null; end Foo
3715 ;; for elaboration code (elaboration)
3716 (if (not (looking-at "\\<\\(new\\|separate\\|begin\\)\\>"))
3370 (setq nest-count (1- nest-count))))))) 3717 (setq nest-count (1- nest-count)))))))
3371 ;; found task start => check if it has a body 3718 ;; found task start => check if it has a body
3372 ((looking-at "task") 3719 ((looking-at "task")
@@ -3408,73 +3755,116 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
3408 ;; 3755 ;;
3409 (setq found (zerop nest-count))))) ; end of loop 3756 (setq found (zerop nest-count))))) ; end of loop
3410 3757
3411 (if found 3758 (if (bobp)
3412 ;; 3759 (point)
3413 ;; match found => is there anything else to do ? 3760 (if found
3414 ;; 3761 ;;
3415 (progn 3762 ;; match found => is there anything else to do ?
3416 (cond 3763 ;;
3417 ;; 3764 (progn
3418 ;; found 'if' => skip to 'then', if it's on a separate line 3765 (cond
3419 ;; and GOTOTHEN is non-nil 3766 ;;
3420 ;; 3767 ;; found 'if' => skip to 'then', if it's on a separate line
3421 ((and 3768 ;; and GOTOTHEN is non-nil
3422 gotothen 3769 ;;
3423 (looking-at "if") 3770 ((and
3424 (save-excursion 3771 gotothen
3425 (ada-search-ignore-string-comment "then" nil nil nil 3772 (looking-at "if")
3426 'word-search-forward) 3773 (save-excursion
3427 (back-to-indentation) 3774 (ada-search-ignore-string-comment "then" nil nil nil
3428 (looking-at "\\<then\\>"))) 3775 'word-search-forward)
3429 (goto-char (match-beginning 0))) 3776 (back-to-indentation)
3430 ;; 3777 (looking-at "\\<then\\>")))
3431 ;; found 'do' => skip back to 'accept' 3778 (goto-char (match-beginning 0)))
3432 ;; 3779
3433 ((looking-at "do") 3780 ;;
3434 (unless (ada-search-ignore-string-comment "accept" t nil nil 3781 ;; found 'do' => skip back to 'accept'
3435 'word-search-backward) 3782 ;;
3436 (error "missing 'accept' in front of 'do'")))) 3783 ((looking-at "do")
3437 (point)) 3784 (unless (ada-search-ignore-string-comment
3438 3785 "accept" t nil nil
3439 (if noerror 3786 'word-search-backward)
3440 nil 3787 (error "missing 'accept' in front of 'do'"))))
3441 (error "no matching start"))))) 3788 (point))
3789
3790 (if noerror
3791 nil
3792 (error "no matching start"))))))
3442 3793
3443 3794
3444(defun ada-goto-matching-end (&optional nest-level noerror) 3795(defun ada-goto-matching-end (&optional nest-level noerror)
3445 "Moves point to the end of a block. 3796 "Moves point to the end of a block.
3446Which block depends on the value of NEST-LEVEL, which defaults to zero. 3797Which block depends on the value of NEST-LEVEL, which defaults to zero.
3447If NOERROR is non-nil, it only returns nil if found no matching start." 3798If NOERROR is non-nil, it only returns nil if found no matching start."
3448 (let ((nest-count (if nest-level nest-level 0)) 3799 (let ((nest-count (or nest-level 0))
3449 (found nil)) 3800 (regex (eval-when-compile
3801 (concat "\\<"
3802 (regexp-opt '("end" "loop" "select" "begin" "case"
3803 "if" "task" "package" "record" "do"
3804 "procedure" "function") t)
3805 "\\>")))
3806 found
3807
3808 ;; First is used for subprograms: they are generally handled
3809 ;; recursively, but of course we do not want to do that the
3810 ;; first time (see comment below about subprograms)
3811 (first (not (looking-at "declare"))))
3812
3813 ;; If we are already looking at one of the keywords, this shouldn't count
3814 ;; in the nesting loop below, so we just make sure we don't count it.
3815 ;; "declare" is a special case because we need to look after the "begin"
3816 ;; keyword
3817 (if (and (not first) (looking-at regex))
3818 (forward-char 1))
3450 3819
3451 ;; 3820 ;;
3452 ;; search forward for interesting keywords 3821 ;; search forward for interesting keywords
3453 ;; 3822 ;;
3454 (while (and 3823 (while (and
3455 (not found) 3824 (not found)
3456 (ada-search-ignore-string-comment 3825 (ada-search-ignore-string-comment regex nil))
3457 (eval-when-compile
3458 (concat "\\<"
3459 (regexp-opt '("end" "loop" "select" "begin" "case"
3460 "if" "task" "package" "record" "do") t)
3461 "\\>")) nil))
3462 3826
3463 ;; 3827 ;;
3464 ;; calculate nest-depth 3828 ;; calculate nest-depth
3465 ;; 3829 ;;
3466 (backward-word 1) 3830 (backward-word 1)
3467 (cond 3831 (cond
3832 ;; procedures and functions need to be processed recursively, in
3833 ;; case they are defined in a declare/begin block, as in:
3834 ;; declare -- NL 0 (nested level)
3835 ;; A : Boolean;
3836 ;; procedure B (C : D) is
3837 ;; begin -- NL 1
3838 ;; null;
3839 ;; end B; -- NL 0, and we would exit
3840 ;; begin
3841 ;; end; -- we should exit here
3842 ;; processing them recursively avoids the need for any special
3843 ;; handling.
3844 ;; Nothing should be done if we have only the specs or a
3845 ;; generic instantion.
3846
3847 ((and (looking-at "\\<procedure\\|function\\>"))
3848 (if first
3849 (forward-word 1)
3850 (ada-search-ignore-string-comment "is\\|;")
3851 (ada-goto-next-non-ws)
3852 (unless (looking-at "\\<new\\>")
3853 (ada-goto-matching-end 0 t))))
3854
3468 ;; found block end => decrease nest depth 3855 ;; found block end => decrease nest depth
3469 ((looking-at "\\<end\\>") 3856 ((looking-at "\\<end\\>")
3470 (setq nest-count (1- nest-count)) 3857 (setq nest-count (1- nest-count)
3471 ;; skip the following keyword 3858 found (<= nest-count 0))
3472 (if (progn 3859 ;; skip the following keyword
3473 (skip-chars-forward "end") 3860 (if (progn
3474 (ada-goto-next-non-ws) 3861 (skip-chars-forward "end")
3475 (looking-at "\\<\\(loop\\|select\\|record\\|case\\|if\\)\\>")) 3862 (ada-goto-next-non-ws)
3476 (forward-word 1))) 3863 (looking-at "\\<\\(loop\\|select\\|record\\|case\\|if\\)\\>"))
3477 ;; found package start => check if it really starts a block 3864 (forward-word 1)))
3865
3866 ;; found package start => check if it really starts a block, and is not
3867 ;; in fact a generic instantiation for instance
3478 ((looking-at "\\<package\\>") 3868 ((looking-at "\\<package\\>")
3479 (ada-search-ignore-string-comment "is" nil nil nil 3869 (ada-search-ignore-string-comment "is" nil nil nil
3480 'word-search-forward) 3870 'word-search-forward)
@@ -3482,15 +3872,16 @@ If NOERROR is non-nil, it only returns nil if found no matching start."
3482 ;; ignore and skip it if it is only a 'new' package 3872 ;; ignore and skip it if it is only a 'new' package
3483 (if (looking-at "\\<new\\>") 3873 (if (looking-at "\\<new\\>")
3484 (goto-char (match-end 0)) 3874 (goto-char (match-end 0))
3485 (setq nest-count (1+ nest-count)))) 3875 (setq nest-count (1+ nest-count)
3876 found (<= nest-count 0))))
3877
3486 ;; all the other block starts 3878 ;; all the other block starts
3487 (t 3879 (t
3488 (setq nest-count (1+ nest-count)) 3880 (setq nest-count (1+ nest-count)
3881 found (<= nest-count 0))
3489 (forward-word 1))) ; end of 'cond' 3882 (forward-word 1))) ; end of 'cond'
3490 3883
3491 ;; match is found, if nest-depth is zero 3884 (setq first nil))
3492 ;;
3493 (setq found (zerop nest-count))) ; end of loop
3494 3885
3495 (if found 3886 (if found
3496 t 3887 t
@@ -3622,10 +4013,15 @@ Returns nil if the private is part of the package name, as in
3622 ;; Make sure this is the start of a private section (ie after 4013 ;; Make sure this is the start of a private section (ie after
3623 ;; a semicolon or just after the package declaration, but not 4014 ;; a semicolon or just after the package declaration, but not
3624 ;; after a 'type ... is private' or 'is new ... with private' 4015 ;; after a 'type ... is private' or 'is new ... with private'
4016 ;;
4017 ;; Note that a 'private' statement at the beginning of the buffer
4018 ;; does not indicate a private section, since this is instead a
4019 ;; 'private procedure ...'
3625 (progn (forward-comment -1000) 4020 (progn (forward-comment -1000)
3626 (or (= (char-before) ?\;) 4021 (and (not (bobp))
3627 (and (forward-word -3) 4022 (or (= (char-before) ?\;)
3628 (looking-at "\\<package\\>"))))))) 4023 (and (forward-word -3)
4024 (looking-at "\\<package\\>"))))))))
3629 4025
3630 4026
3631(defun ada-in-paramlist-p () 4027(defun ada-in-paramlist-p ()
@@ -3641,7 +4037,7 @@ Returns nil if the private is part of the package name, as in
3641 ;; subprogram definition: procedure .... ( 4037 ;; subprogram definition: procedure .... (
3642 ;; Let's skip back over the first one 4038 ;; Let's skip back over the first one
3643 (progn 4039 (progn
3644 (skip-syntax-backward " ") 4040 (skip-chars-backward " \t\n")
3645 (if (= (char-before) ?\") 4041 (if (= (char-before) ?\")
3646 (backward-char 3) 4042 (backward-char 3)
3647 (backward-word 1)) 4043 (backward-word 1))
@@ -3692,7 +4088,18 @@ parenthesis, or nil."
3692 (if (nth 1 parse) 4088 (if (nth 1 parse)
3693 (progn 4089 (progn
3694 (goto-char (1+ (nth 1 parse))) 4090 (goto-char (1+ (nth 1 parse)))
3695 (skip-chars-forward " \t") 4091
4092 ;; Skip blanks, if they are not followed by a comment
4093 ;; See:
4094 ;; type A is ( Value_0,
4095 ;; Value_1);
4096 ;; type B is ( -- comment
4097 ;; Value_2);
4098
4099 (if (or (not ada-indent-handle-comment-special)
4100 (not (looking-at "[ \t]+--")))
4101 (skip-chars-forward " \t"))
4102
3696 (point)))))) 4103 (point))))))
3697 4104
3698 4105
@@ -3707,11 +4114,7 @@ of the region. Otherwise, operates only on the current line."
3707 (interactive) 4114 (interactive)
3708 (cond ((eq ada-tab-policy 'indent-rigidly) (ada-tab-hard)) 4115 (cond ((eq ada-tab-policy 'indent-rigidly) (ada-tab-hard))
3709 ((eq ada-tab-policy 'indent-auto) 4116 ((eq ada-tab-policy 'indent-auto)
3710 ;; transient-mark-mode and mark-active are not defined in XEmacs 4117 (if (ada-region-selected)
3711 (if (or (and ada-xemacs (funcall (symbol-function 'region-active-p)))
3712 (and (not ada-xemacs)
3713 (symbol-value 'transient-mark-mode)
3714 (symbol-value 'mark-active)))
3715 (ada-indent-region (region-beginning) (region-end)) 4118 (ada-indent-region (region-beginning) (region-end))
3716 (ada-indent-current))) 4119 (ada-indent-current)))
3717 ((eq ada-tab-policy 'always-tab) (error "not implemented")) 4120 ((eq ada-tab-policy 'always-tab) (error "not implemented"))
@@ -3758,44 +4161,87 @@ of the region. Otherwise, operates only on the current line."
3758;; -- Miscellaneous 4161;; -- Miscellaneous
3759;; ------------------------------------------------------------ 4162;; ------------------------------------------------------------
3760 4163
4164;; Not needed any more for Emacs 21.2, but still needed for backward
4165;; compatibility
4166(defun ada-remove-trailing-spaces ()
4167 "Remove trailing spaces in the whole buffer."
4168 (interactive)
4169 (save-match-data
4170 (save-excursion
4171 (save-restriction
4172 (widen)
4173 (goto-char (point-min))
4174 (while (re-search-forward "[ \t]+$" (point-max) t)
4175 (replace-match "" nil nil))))))
4176
3761(defun ada-gnat-style () 4177(defun ada-gnat-style ()
3762 "Clean up comments, `(' and `,' for GNAT style checking switch." 4178 "Clean up comments, `(' and `,' for GNAT style checking switch."
3763 (interactive) 4179 (interactive)
3764 (save-excursion 4180 (save-excursion
4181
4182 ;; The \n is required, or the line after an empty comment line is
4183 ;; simply ignored.
3765 (goto-char (point-min)) 4184 (goto-char (point-min))
3766 (while (re-search-forward "--[ \t]*\\([^-]\\)" nil t) 4185 (while (re-search-forward "--[ \t]*\\([^-\n]\\)" nil t)
3767 (replace-match "-- \\1")) 4186 (replace-match "-- \\1")
4187 (forward-line 1)
4188 (beginning-of-line))
4189
3768 (goto-char (point-min)) 4190 (goto-char (point-min))
3769 (while (re-search-forward "\\>(" nil t) 4191 (while (re-search-forward "\\>(" nil t)
3770 (replace-match " (")) 4192 (if (not (ada-in-string-or-comment-p))
4193 (replace-match " (")))
4194 (goto-char (point-min))
4195 (while (re-search-forward ";--" nil t)
4196 (forward-char -1)
4197 (if (not (ada-in-string-or-comment-p))
4198 (replace-match "; --")))
3771 (goto-char (point-min)) 4199 (goto-char (point-min))
3772 (while (re-search-forward "([ \t]+" nil t) 4200 (while (re-search-forward "([ \t]+" nil t)
3773 (replace-match "(")) 4201 (if (not (ada-in-string-or-comment-p))
4202 (replace-match "(")))
3774 (goto-char (point-min)) 4203 (goto-char (point-min))
3775 (while (re-search-forward ")[ \t]+)" nil t) 4204 (while (re-search-forward ")[ \t]+)" nil t)
3776 (replace-match "))")) 4205 (if (not (ada-in-string-or-comment-p))
4206 (replace-match "))")))
3777 (goto-char (point-min)) 4207 (goto-char (point-min))
3778 (while (re-search-forward "\\>:" nil t) 4208 (while (re-search-forward "\\>:" nil t)
3779 (replace-match " :")) 4209 (if (not (ada-in-string-or-comment-p))
3780 (goto-char (point-min)) 4210 (replace-match " :")))
3781 (while (re-search-forward ",\\<" nil t) 4211
3782 (replace-match ", ")) 4212 ;; Make sure there is a space after a ','.
4213 ;; Always go back to the beginning of the match, since otherwise
4214 ;; a statement like ('F','D','E') is incorrectly modified.
3783 (goto-char (point-min)) 4215 (goto-char (point-min))
3784 (while (re-search-forward "[ \t]*\\.\\.[ \t]*" nil t) 4216 (while (re-search-forward ",[ \t]*\\(.\\)" nil t)
3785 (replace-match " .. ")) 4217 (if (not (save-excursion
4218 (goto-char (match-beginning 0))
4219 (ada-in-string-or-comment-p)))
4220 (replace-match ", \\1")))
4221
4222 ;; Operators should be surrounded by spaces.
3786 (goto-char (point-min)) 4223 (goto-char (point-min))
3787 (while (re-search-forward "[ \t]*\\([-:+*/]\\)[ \t]*" nil t) 4224 (while (re-search-forward
3788 (if (not (ada-in-string-or-comment-p)) 4225 "[ \t]*\\(/=\\|\\*\\*\\|:=\\|\\.\\.\\|[-:+*/]\\)[ \t]*"
4226 nil t)
4227 (goto-char (match-beginning 1))
4228 (if (or (looking-at "--")
4229 (ada-in-string-or-comment-p))
3789 (progn 4230 (progn
3790 (forward-char -1) 4231 (forward-line 1)
3791 (cond 4232 (beginning-of-line))
3792 ((looking-at "/=") 4233 (cond
3793 (replace-match " /= ")) 4234 ((string= (match-string 1) "/=")
3794 ((looking-at ":=") 4235 (replace-match " /= "))
3795 (replace-match ":= ")) 4236 ((string= (match-string 1) "..")
3796 ((not (looking-at "--")) 4237 (replace-match " .. "))
3797 (replace-match " \\1 "))) 4238 ((string= (match-string 1) "**")
3798 (forward-char 2)))) 4239 (replace-match " ** "))
4240 ((string= (match-string 1) ":=")
4241 (replace-match " := "))
4242 (t
4243 (replace-match " \\1 ")))
4244 (forward-char 1)))
3799 )) 4245 ))
3800 4246
3801 4247
@@ -3813,7 +4259,6 @@ of the region. Otherwise, operates only on the current line."
3813 (progn 4259 (progn
3814 (set-syntax-table ada-mode-symbol-syntax-table) 4260 (set-syntax-table ada-mode-symbol-syntax-table)
3815 4261
3816 (message "searching for block start ...")
3817 (save-excursion 4262 (save-excursion
3818 ;; 4263 ;;
3819 ;; do nothing if in string or comment or not on 'end ...;' 4264 ;; do nothing if in string or comment or not on 'end ...;'
@@ -3842,8 +4287,7 @@ of the region. Otherwise, operates only on the current line."
3842 ) ; end of save-excursion 4287 ) ; end of save-excursion
3843 4288
3844 ;; now really move to the found position 4289 ;; now really move to the found position
3845 (goto-char pos) 4290 (goto-char pos))
3846 (message "searching for block start ... done"))
3847 4291
3848 ;; restore syntax-table 4292 ;; restore syntax-table
3849 (set-syntax-table previous-syntax-table)))) 4293 (set-syntax-table previous-syntax-table))))
@@ -3853,27 +4297,34 @@ of the region. Otherwise, operates only on the current line."
3853Moves to 'begin' if in a declarative part." 4297Moves to 'begin' if in a declarative part."
3854 (interactive) 4298 (interactive)
3855 (let ((pos (point)) 4299 (let ((pos (point))
4300 decl-start
3856 (previous-syntax-table (syntax-table))) 4301 (previous-syntax-table (syntax-table)))
3857 (unwind-protect 4302 (unwind-protect
3858 (progn 4303 (progn
3859 (set-syntax-table ada-mode-symbol-syntax-table) 4304 (set-syntax-table ada-mode-symbol-syntax-table)
3860 4305
3861 (message "searching for block end ...")
3862 (save-excursion 4306 (save-excursion
3863 4307
3864 (forward-char 1)
3865 (cond 4308 (cond
3866 ;; directly on 'begin' 4309 ;; directly on 'begin'
3867 ((save-excursion 4310 ((save-excursion
3868 (ada-goto-previous-word) 4311 (ada-goto-previous-word)
3869 (looking-at "\\<begin\\>")) 4312 (looking-at "\\<begin\\>"))
3870 (ada-goto-matching-end 1)) 4313 (ada-goto-matching-end 1))
3871 ;; on first line of defun declaration 4314
3872 ((save-excursion 4315 ;; on first line of subprogram body
3873 (and (ada-goto-stmt-start) 4316 ;; Do nothing for specs or generic instantion, since these are
3874 (looking-at "\\<function\\>\\|\\<procedure\\>" ))) 4317 ;; handled as the general case (find the enclosing block)
3875 (ada-search-ignore-string-comment "begin" nil nil nil 4318 ;; We also need to make sure that we ignore nested subprograms
3876 'word-search-forward)) 4319 ((save-excursion
4320 (and (skip-syntax-backward "w")
4321 (looking-at "\\<function\\>\\|\\<procedure\\>" )
4322 (ada-search-ignore-string-comment "is\\|;")
4323 (not (= (char-before) ?\;))
4324 ))
4325 (skip-syntax-backward "w")
4326 (ada-goto-matching-end 0 t))
4327
3877 ;; on first line of task declaration 4328 ;; on first line of task declaration
3878 ((save-excursion 4329 ((save-excursion
3879 (and (ada-goto-stmt-start) 4330 (and (ada-goto-stmt-start)
@@ -3890,14 +4341,15 @@ Moves to 'begin' if in a declarative part."
3890 (ada-goto-matching-end 0)) 4341 (ada-goto-matching-end 0))
3891 ;; package start 4342 ;; package start
3892 ((save-excursion 4343 ((save-excursion
3893 (and (ada-goto-matching-decl-start t) 4344 (setq decl-start (and (ada-goto-matching-decl-start t) (point)))
3894 (looking-at "\\<package\\>"))) 4345 (and decl-start (looking-at "\\<package\\>")))
3895 (ada-goto-matching-end 1)) 4346 (ada-goto-matching-end 1))
4347
3896 ;; inside a 'begin' ... 'end' block 4348 ;; inside a 'begin' ... 'end' block
3897 ((save-excursion 4349 (decl-start
3898 (ada-goto-matching-decl-start t)) 4350 (goto-char decl-start)
3899 (ada-search-ignore-string-comment "begin" nil nil nil 4351 (ada-goto-matching-end 0 t))
3900 'word-search-forward)) 4352
3901 ;; (hopefully ;-) everything else 4353 ;; (hopefully ;-) everything else
3902 (t 4354 (t
3903 (ada-goto-matching-end 1))) 4355 (ada-goto-matching-end 1)))
@@ -3905,8 +4357,7 @@ Moves to 'begin' if in a declarative part."
3905 ) 4357 )
3906 4358
3907 ;; now really move to the position found 4359 ;; now really move to the position found
3908 (goto-char pos) 4360 (goto-char pos))
3909 (message "searching for block end ... done"))
3910 4361
3911 ;; restore syntax-table 4362 ;; restore syntax-table
3912 (set-syntax-table previous-syntax-table)))) 4363 (set-syntax-table previous-syntax-table))))
@@ -3916,7 +4367,7 @@ Moves to 'begin' if in a declarative part."
3916 (interactive) 4367 (interactive)
3917 (end-of-line) 4368 (end-of-line)
3918 (if (re-search-forward ada-procedure-start-regexp nil t) 4369 (if (re-search-forward ada-procedure-start-regexp nil t)
3919 (goto-char (match-beginning 1)) 4370 (goto-char (match-beginning 2))
3920 (error "No more functions/procedures/tasks"))) 4371 (error "No more functions/procedures/tasks")))
3921 4372
3922(defun ada-previous-procedure () 4373(defun ada-previous-procedure ()
@@ -3924,7 +4375,7 @@ Moves to 'begin' if in a declarative part."
3924 (interactive) 4375 (interactive)
3925 (beginning-of-line) 4376 (beginning-of-line)
3926 (if (re-search-backward ada-procedure-start-regexp nil t) 4377 (if (re-search-backward ada-procedure-start-regexp nil t)
3927 (goto-char (match-beginning 1)) 4378 (goto-char (match-beginning 2))
3928 (error "No more functions/procedures/tasks"))) 4379 (error "No more functions/procedures/tasks")))
3929 4380
3930(defun ada-next-package () 4381(defun ada-next-package ()
@@ -3957,7 +4408,9 @@ Moves to 'begin' if in a declarative part."
3957 (define-key ada-mode-map "\t" 'ada-tab) 4408 (define-key ada-mode-map "\t" 'ada-tab)
3958 (define-key ada-mode-map "\C-c\t" 'ada-justified-indent-current) 4409 (define-key ada-mode-map "\C-c\t" 'ada-justified-indent-current)
3959 (define-key ada-mode-map "\C-c\C-l" 'ada-indent-region) 4410 (define-key ada-mode-map "\C-c\C-l" 'ada-indent-region)
3960 (define-key ada-mode-map [(shift tab)] 'ada-untab) 4411 (if ada-xemacs
4412 (define-key ada-mode-map '(shift tab) 'ada-untab)
4413 (define-key ada-mode-map [(shift tab)] 'ada-untab))
3961 (define-key ada-mode-map "\C-c\C-f" 'ada-format-paramlist) 4414 (define-key ada-mode-map "\C-c\C-f" 'ada-format-paramlist)
3962 ;; We don't want to make meta-characters case-specific. 4415 ;; We don't want to make meta-characters case-specific.
3963 4416
@@ -3975,6 +4428,7 @@ Moves to 'begin' if in a declarative part."
3975 (define-key ada-mode-map "\C-c\C-b" 'ada-adjust-case-buffer) 4428 (define-key ada-mode-map "\C-c\C-b" 'ada-adjust-case-buffer)
3976 (define-key ada-mode-map "\C-c\C-t" 'ada-case-read-exceptions) 4429 (define-key ada-mode-map "\C-c\C-t" 'ada-case-read-exceptions)
3977 (define-key ada-mode-map "\C-c\C-y" 'ada-create-case-exception) 4430 (define-key ada-mode-map "\C-c\C-y" 'ada-create-case-exception)
4431 (define-key ada-mode-map "\C-c\C-\M-y" 'ada-create-case-exception-substring)
3978 4432
3979 ;; On XEmacs, you can easily specify whether DEL should deletes 4433 ;; On XEmacs, you can easily specify whether DEL should deletes
3980 ;; one character forward or one character backward. Take this into 4434 ;; one character forward or one character backward. Take this into
@@ -4030,8 +4484,10 @@ can add its own items."
4030 ["Fill Comment Paragraph Postfix" ada-fill-comment-paragraph-postfix t] 4484 ["Fill Comment Paragraph Postfix" ada-fill-comment-paragraph-postfix t]
4031 ["---" nil nil] 4485 ["---" nil nil]
4032 ["Adjust Case Selection" ada-adjust-case-region t] 4486 ["Adjust Case Selection" ada-adjust-case-region t]
4033 ["Adjust Case Buffer" ada-adjust-case-buffer t] 4487 ["Adjust Case in File" ada-adjust-case-buffer t]
4034 ["Create Case Exception" ada-create-case-exception t] 4488 ["Create Case Exception" ada-create-case-exception t]
4489 ["Create Case Exception Substring"
4490 ada-create-case-exception-substring t]
4035 ["Reload Case Exceptions" ada-case-read-exceptions t] 4491 ["Reload Case Exceptions" ada-case-read-exceptions t]
4036 ["----" nil nil] 4492 ["----" nil nil]
4037 ["Make body for subprogram" ada-make-subprogram-body t])) 4493 ["Make body for subprogram" ada-make-subprogram-body t]))
@@ -4040,7 +4496,7 @@ can add its own items."
4040 4496
4041 ;; Option menu present only if in Ada mode 4497 ;; Option menu present only if in Ada mode
4042 (setq m (append m (list (append '("Options" 4498 (setq m (append m (list (append '("Options"
4043 :included (eq major-mode 'ada-mode)) 4499 :included '(eq major-mode 'ada-mode))
4044 option)))) 4500 option))))
4045 4501
4046 ;; Customize menu always present 4502 ;; Customize menu always present
@@ -4060,7 +4516,7 @@ can add its own items."
4060 (when ada-xemacs 4516 (when ada-xemacs
4061 ;; This looks bogus to me! -stef 4517 ;; This looks bogus to me! -stef
4062 (define-key ada-mode-map [menu-bar] ada-mode-menu) 4518 (define-key ada-mode-map [menu-bar] ada-mode-menu)
4063 (setq mode-popup-menu (cons "Ada mode" ada-mode-menu))))) 4519 (set 'mode-popup-menu (cons "Ada mode" ada-mode-menu)))))
4064 4520
4065 4521
4066;; ------------------------------------------------------- 4522;; -------------------------------------------------------
@@ -4076,7 +4532,8 @@ can add its own items."
4076 4532
4077(defadvice comment-region (before ada-uncomment-anywhere) 4533(defadvice comment-region (before ada-uncomment-anywhere)
4078 (if (and arg 4534 (if (and arg
4079 (< arg 0) 4535 (listp arg) ;; a prefix with \C-u is of the form '(4), whereas
4536 ;; \C-u 2 sets arg to '2' (fixed by S.Leake)
4080 (string= mode-name "Ada")) 4537 (string= mode-name "Ada"))
4081 (save-excursion 4538 (save-excursion
4082 (let ((cs (concat "^[ \t]*" (regexp-quote comment-start)))) 4539 (let ((cs (concat "^[ \t]*" (regexp-quote comment-start))))
@@ -4094,9 +4551,9 @@ can add its own items."
4094 (if (or (<= emacs-major-version 20) (boundp 'running-xemacs)) 4551 (if (or (<= emacs-major-version 20) (boundp 'running-xemacs))
4095 (progn 4552 (progn
4096 (ad-activate 'comment-region) 4553 (ad-activate 'comment-region)
4097 (comment-region beg end (- (or arg 1))) 4554 (comment-region beg end (- (or arg 2)))
4098 (ad-deactivate 'comment-region)) 4555 (ad-deactivate 'comment-region))
4099 (comment-region beg end (list (- (or arg 1)))))) 4556 (comment-region beg end (list (- (or arg 2))))))
4100 4557
4101(defun ada-fill-comment-paragraph-justify () 4558(defun ada-fill-comment-paragraph-justify ()
4102 "Fills current comment paragraph and justifies each line as well." 4559 "Fills current comment paragraph and justifies each line as well."
@@ -4141,7 +4598,7 @@ The paragraph is indented on the first line."
4141 4598
4142 ;; If we were at the last line in the buffer, create a dummy empty 4599 ;; If we were at the last line in the buffer, create a dummy empty
4143 ;; line at the end of the buffer. 4600 ;; line at the end of the buffer.
4144 (if (eolp) 4601 (if (eobp)
4145 (insert "\n") 4602 (insert "\n")
4146 (back-to-indentation))) 4603 (back-to-indentation)))
4147 (beginning-of-line) 4604 (beginning-of-line)
@@ -4149,13 +4606,16 @@ The paragraph is indented on the first line."
4149 (goto-char opos) 4606 (goto-char opos)
4150 4607
4151 ;; Find beginning of paragraph 4608 ;; Find beginning of paragraph
4152 (beginning-of-line) 4609 (back-to-indentation)
4153 (while (and (not (bobp)) (looking-at "[ \t]*--[ \t]*[^ \t\n]")) 4610 (while (and (not (bobp)) (looking-at "--[ \t]*[^ \t\n]"))
4154 (forward-line -1)) 4611 (forward-line -1)
4155 ;; If we found a paragraph-separating line, 4612 (back-to-indentation))
4156 ;; don't actually include it in the paragraph. 4613
4157 (unless (looking-at "[ \t]*--[ \t]*[^ \t\n]") 4614 ;; We want one line to above the first one, unless we are at the beginning
4615 ;; of the buffer
4616 (unless (bobp)
4158 (forward-line 1)) 4617 (forward-line 1))
4618 (beginning-of-line)
4159 (setq from (point-marker)) 4619 (setq from (point-marker))
4160 4620
4161 ;; Calculate the indentation we will need for the paragraph 4621 ;; Calculate the indentation we will need for the paragraph
@@ -4276,8 +4736,20 @@ otherwise."
4276 (setq is-spec name) 4736 (setq is-spec name)
4277 4737
4278 (while suffixes 4738 (while suffixes
4279 (if (file-exists-p (concat name (car suffixes))) 4739
4280 (setq is-spec (concat name (car suffixes)))) 4740 ;; If we are using project file, search for the other file in all
4741 ;; the possible src directories.
4742
4743 (if (functionp 'ada-find-src-file-in-dir)
4744 (let ((other
4745 (ada-find-src-file-in-dir
4746 (file-name-nondirectory (concat name (car suffixes))))))
4747 (if other
4748 (set 'is-spec other)))
4749
4750 ;; Else search in the current directory
4751 (if (file-exists-p (concat name (car suffixes)))
4752 (setq is-spec (concat name (car suffixes)))))
4281 (setq suffixes (cdr suffixes))) 4753 (setq suffixes (cdr suffixes)))
4282 4754
4283 is-spec))) 4755 is-spec)))
@@ -4306,14 +4778,12 @@ Redefines the function `ff-which-function-are-we-in'."
4306 "Returns the name of the function whose body the point is in. 4778 "Returns the name of the function whose body the point is in.
4307This function works even in the case of nested subprograms, whereas the 4779This function works even in the case of nested subprograms, whereas the
4308standard Emacs function which-function does not. 4780standard Emacs function which-function does not.
4309Note that this function expects subprogram bodies to be terminated by
4310'end <name>;', not 'end;'.
4311Since the search can be long, the results are cached." 4781Since the search can be long, the results are cached."
4312 4782
4313 (let ((line (count-lines (point-min) (point))) 4783 (let ((line (count-lines (point-min) (point)))
4314 (pos (point)) 4784 (pos (point))
4315 end-pos 4785 end-pos
4316 func-name 4786 func-name indent
4317 found) 4787 found)
4318 4788
4319 ;; If this is the same line as before, simply return the same result 4789 ;; If this is the same line as before, simply return the same result
@@ -4323,28 +4793,46 @@ Since the search can be long, the results are cached."
4323 (save-excursion 4793 (save-excursion
4324 ;; In case the current line is also the beginning of the body 4794 ;; In case the current line is also the beginning of the body
4325 (end-of-line) 4795 (end-of-line)
4326 (while (and (ada-in-paramlist-p)
4327 (= (forward-line 1) 0))
4328 (end-of-line))
4329 4796
4797 ;; Are we looking at "function Foo\n (paramlist)"
4798 (skip-chars-forward " \t\n(")
4799
4800 (condition-case nil
4801 (up-list)
4802 (error nil))
4803
4804 (skip-chars-forward " \t\n")
4805 (if (looking-at "return")
4806 (progn
4807 (forward-word 1)
4808 (skip-chars-forward " \t\n")
4809 (skip-chars-forward "a-zA-Z0-9_'")))
4810
4330 ;; Can't simply do forward-word, in case the "is" is not on the 4811 ;; Can't simply do forward-word, in case the "is" is not on the
4331 ;; same line as the closing parenthesis 4812 ;; same line as the closing parenthesis
4332 (skip-chars-forward "is \t\n") 4813 (skip-chars-forward "is \t\n")
4333 4814
4334 ;; No look for the closest subprogram body that has not ended yet. 4815 ;; No look for the closest subprogram body that has not ended yet.
4335 ;; Not that we expect all the bodies to be finished by "end <name", 4816 ;; Not that we expect all the bodies to be finished by "end <name>",
4336 ;; not simply "end" 4817 ;; or a simple "end;" indented in the same column as the start of
4818 ;; the subprogram. The goal is to be as efficient as possible.
4337 4819
4338 (while (and (not found) 4820 (while (and (not found)
4339 (re-search-backward ada-imenu-subprogram-menu-re nil t)) 4821 (re-search-backward ada-imenu-subprogram-menu-re nil t))
4340 (setq func-name (match-string 2)) 4822
4823 ;; Get the function name, but not the properties, or this changes
4824 ;; the face in the modeline on Emacs 21
4825 (setq func-name (match-string-no-properties 2))
4341 (if (and (not (ada-in-comment-p)) 4826 (if (and (not (ada-in-comment-p))
4342 (not (save-excursion 4827 (not (save-excursion
4343 (goto-char (match-end 0)) 4828 (goto-char (match-end 0))
4344 (looking-at "[ \t\n]*new")))) 4829 (looking-at "[ \t\n]*new"))))
4345 (save-excursion 4830 (save-excursion
4831 (back-to-indentation)
4832 (setq indent (current-column))
4346 (if (ada-search-ignore-string-comment 4833 (if (ada-search-ignore-string-comment
4347 (concat "end[ \t]+" func-name "[ \t]*;")) 4834 (concat "end[ \t]+" func-name "[ \t]*;\\|^"
4835 (make-string indent ? ) "end;"))
4348 (setq end-pos (point)) 4836 (setq end-pos (point))
4349 (setq end-pos (point-max))) 4837 (setq end-pos (point-max)))
4350 (if (>= end-pos pos) 4838 (if (>= end-pos pos)
@@ -4378,6 +4866,18 @@ Returns nil if no body was found."
4378 4866
4379 (unless spec-name (setq spec-name (buffer-file-name))) 4867 (unless spec-name (setq spec-name (buffer-file-name)))
4380 4868
4869 ;; Remove the spec extension. We can not simply remove the file extension,
4870 ;; but we need to take into account the specific non-GNAT extensions that the
4871 ;; user might have specified.
4872
4873 (let ((suffixes ada-spec-suffixes)
4874 end)
4875 (while suffixes
4876 (setq end (- (length spec-name) (length (car suffixes))))
4877 (if (string-equal (car suffixes) (substring spec-name end))
4878 (setq spec-name (substring spec-name 0 end)))
4879 (setq suffixes (cdr suffixes))))
4880
4381 ;; If find-file.el was available, use its functions 4881 ;; If find-file.el was available, use its functions
4382 (if (functionp 'ff-get-file) 4882 (if (functionp 'ff-get-file)
4383 (ff-get-file-name ada-search-directories 4883 (ff-get-file-name ada-search-directories
@@ -4411,7 +4911,7 @@ Returns nil if no body was found."
4411 ;; a string 4911 ;; a string
4412 ;; This sets the properties of the characters, so that ada-in-string-p 4912 ;; This sets the properties of the characters, so that ada-in-string-p
4413 ;; correctly handles '"' too... 4913 ;; correctly handles '"' too...
4414 '(("\\('\\)[^'\n]\\('\\)" (1 (7 . ?')) (2 (7 . ?'))) 4914 '(("[^a-zA-Z0-9)]\\('\\)[^'\n]\\('\\)" (1 (7 . ?')) (2 (7 . ?')))
4415 ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n))) 4915 ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n)))
4416 )) 4916 ))
4417 4917
@@ -4449,7 +4949,7 @@ Returns nil if no body was found."
4449 ;; 4949 ;;
4450 ;; Optional keywords followed by a type name. 4950 ;; Optional keywords followed by a type name.
4451 (list (concat ; ":[ \t]*" 4951 (list (concat ; ":[ \t]*"
4452 "\\<\\(access[ \t]+all\\|access\\|constant\\|in[ \t]+out\\|in\\|out\\)\\>" 4952 "\\<\\(access[ \t]+all\\|access[ \t]+constant\\|access\\|constant\\|in[ \t]+reverse\\|\\|in[ \t]+out\\|in\\|out\\)\\>"
4453 "[ \t]*" 4953 "[ \t]*"
4454 "\\(\\sw+\\(\\.\\sw*\\)*\\)?") 4954 "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
4455 '(1 font-lock-keyword-face nil t) '(2 font-lock-type-face nil t)) 4955 '(1 font-lock-keyword-face nil t) '(2 font-lock-type-face nil t))
@@ -4482,12 +4982,21 @@ Returns nil if no body was found."
4482 font-lock-type-face) nil t)) 4982 font-lock-type-face) nil t))
4483 ;; 4983 ;;
4484 ;; Keywords followed by a (comma separated list of) reference. 4984 ;; Keywords followed by a (comma separated list of) reference.
4485 (list (concat "\\<\\(goto\\|raise\\|use\\|with\\)\\>" ; "when" removed 4985 ;; Note that font-lock only works on single lines, thus we can not
4486 "[ \t\n]*\\(\\(\\sw\\|[_.|, \t\n]\\)+\\)\\W") 4986 ;; correctly highlight a with_clause that spans multiple lines.
4987 (list (concat "\\<\\(goto\\|raise\\|use\\|with\\)"
4988 "[ \t]+\\([a-zA-Z0-9_., \t]+\\)\\W")
4487 '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t)) 4989 '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t))
4488 ;; 4990 ;;
4489 ;; Goto tags. 4991 ;; Goto tags.
4490 '("<<\\(\\sw+\\)>>" 1 font-lock-reference-face) 4992 '("<<\\(\\sw+\\)>>" 1 font-lock-reference-face)
4993
4994 ;; Highlight based-numbers (R. Reagan <robin-reply@reagans.org>)
4995 (list "\\([0-9]+#[0-9a-fA-F_]+#\\)" '(1 font-lock-constant-face t))
4996
4997 ;; Ada unnamed numerical constants
4998 (list "\\W\\([-+]?[0-9._]+\\)\\>" '(1 font-lock-constant-face))
4999
4491 )) 5000 ))
4492 "Default expressions to highlight in Ada mode.") 5001 "Default expressions to highlight in Ada mode.")
4493 5002