aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/progmodes/ada-mode.el1332
1 files changed, 650 insertions, 682 deletions
diff --git a/lisp/progmodes/ada-mode.el b/lisp/progmodes/ada-mode.el
index 740dcd1ca97..4385a94f141 100644
--- a/lisp/progmodes/ada-mode.el
+++ b/lisp/progmodes/ada-mode.el
@@ -21,13 +21,13 @@
21;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 22
23;;; This mode is a complete rewrite of a major mode for editing Ada 83 23;;; This mode is a complete rewrite of a major mode for editing Ada 83
24;;; and Ada 94 source code under Emacs-19. It contains completely new 24;;; and Ada 95 source code under Emacs-19. It contains completely new
25;;; indenting code and support for code browsing (see ada-xref). 25;;; indenting code and support for code browsing (see ada-xref).
26 26
27 27
28;;; USAGE 28;;; USAGE
29;;; ===== 29;;; =====
30;;; Emacs should enter ada-mode when you load an ada source (*.ada). 30;;; Emacs should enter ada-mode when you load an ada source (*.ad[abs]).
31;;; 31;;;
32;;; When you have entered ada-mode, you may get more info by pressing 32;;; When you have entered ada-mode, you may get more info by pressing
33;;; C-h m. You may also get online help describing various functions by: 33;;; C-h m. You may also get online help describing various functions by:
@@ -57,66 +57,77 @@
57;;; to his version. 57;;; to his version.
58 58
59 59
60;;; KNOWN BUGS / BUGREPORTS 60;;; KNOWN BUGS
61;;; ======================= 61;;; ==========
62;;; 62;;;
63;;; In the presence of comments and/or incorrect syntax 63;;; In the presence of comments and/or incorrect syntax
64;;; ada-format-paramlist produces weird results. 64;;; ada-format-paramlist produces weird results.
65;;; 65;;;
66;;; Indentation is sometimes wrong at the very beginning of the buffer. 66;;; Indenting of some tasking constructs is still buggy.
67;;; So please try it on different locations. If it's still wrong then 67;;; -------------------
68;;; report the bug. 68;;; For tagged types the problem comes from the keyword abstract:
69
70;;; type T2 is abstract tagged record
71;;; X : Integer;
72;;; Y : Float;
73;;; end record;
74;;; -------------------
75;;; In Emacs FSF 19.28, ada-mode will correctly indent comments at the
76;;; very beginning of the buffer (_before_ any code) when I go M-; but
77;;; when I press TAB I'd expect the comments to be placed at the beginning
78;;; of the line, just as the first line of _code_ would be indented.
79
80;;; This does not happen but the comment stays put :-( I end up going
81;;; M-; C-a M-\
82;;; -------------------
83;;; package Test is
84;;; -- If I hit return on the "type" line it will indent the next line
85;;; -- in another 3 space instead of heading out to the "(". If I hit
86;;; -- tab or return it reindents the line correctly but does not initially.
87;;; type Wait_Return is (Read_Success, Read_Timeout, Wait_Timeout,
88;;; Nothing_To_Wait_For_In_Wait_List);
69;;; 89;;;
70;;; At the moment the browsing functions are limited to the use of the 90;;; -- The following line will be wrongly reindented after typing it in after
71;;; separate packages "find-file.el" and "ada-xref.el" (ada-xref.el is 91;;; -- the initial indent for the line was correct after type return after
72;;; only for GNAT users). 92;;; -- this line. Subsequent lines will show the same problem.
73;;; 93;;; Unused: constant Queue_ID := 0;
74;;; indenting of some tasking constructs is not yet supported. 94;;; -------------------
75;;; 95;;; -- If I do the following I get
76;;; `reformat-region' sometimes generates some weird indentation. 96;;; -- "no matching procedure/function/task/declare/package"
97;;; -- when I do return (I reverse the mappings of ^j and ^m) after "private".
98;;; package Package1 is
99;;; package Package1_1 is
100;;; type The_Type is private;
101;;; private
102;;; -------------------
103;;; -- But what about this:
104;;; package G is
105;;; type T1 is new Integer;
106;;; type T2 is new Integer; --< incorrect, correct if subtype
107;;; package H is
108;;; type T3 is new Integer;
109;;; type --< Indentation is incorrect
110;;; -------------------
111
112
113
114;;; CREDITS
115;;; =======
77;;; 116;;;
78;;;> I have the following suggestions for the function template: 1) I 117;;; Many thanks to
79;;;> don't want it automatically assigning it a name for the return variable. I 118;;; Philippe Warroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular,
80;;;> never want it to be called "Result" because that is nondescriptive. If you 119;;; woodruff@stc.llnl.gov (John Woodruff)
81;;;> must define a variable, give me the ability to specify its name. 120;;; jj@ddci.dk (Jesper Joergensen)
82;;;> 121;;; gse@ocsystems.com (Scott Evans)
83;;;> 2) You do not provide a type for variable 'Result'. Its type is the same 122;;; comar@LANG8.CS.NYU.EDU (Cyrille Comar)
84;;;> as the function's return type, which the template knows, so why force me 123;;; and others for their valuable hints.
85;;;> to type it in?
86;;;>
87
88;;;As always, different users have different tastes.
89;;;It would be nice if one could configure such layout details separately
90;;;without patching the LISP code. Maybe the metalanguage used in ada-stmt.el
91;;;could be taken even further, providing the user with some nice syntax
92;;;for describing layout. Then my own hacks would survive the next
93;;;update of the package :-)
94
95;;;By the way, there are some more quirks:
96
97;;;1) text entered in prompt mode (*) is not converted to upper case (I have
98;;; choosen upper case for indentifiers).
99;;; (*) I would like to suggest the term "template code" instead of
100;;; "pseudo code".
101
102;;; There are quite a few problems in the crossreferencing part. These
103;;; are partly due to errors in gnatf. One of the major bugs in
104;;; ada-xref is, that we do not wait for gnatf to rebuild the xref file.
105;;; We start the job, but do not wait for finishing.
106
107 124
108;;; LCD Archive Entry: 125;;; LCD Archive Entry:
109;;; ada-mode|Rolf Ebert|<ebert@inf.enst.fr> 126;;; ada-mode|Rolf Ebert|<ebert@inf.enst.fr>
110;;; |Major-mode for Ada 127;;; |Major-mode for Ada
111;;; |$Date: 1995/04/07 00:14:59 $|$Revision: 1.5 $| 128;;; |$Date: 1995/05/24 17:02:23 $|$Revision: 2.17 $|
112 129
113 130
114(defconst ada-mode-version (substring "$Revision: 1.5 $" 11 -2)
115 "$Id: ada-mode.el,v 1.5 1995/04/07 00:14:59 kwzh Exp kwzh $
116
117Report bugs to: Rolf Ebert <ebert@inf.enst.fr>")
118
119
120;;;-------------------- 131;;;--------------------
121;;; USER OPTIONS 132;;; USER OPTIONS
122;;;-------------------- 133;;;--------------------
@@ -153,9 +164,8 @@ indented.")
153 "*If non-nil, following lines get indented according to the innermost 164 "*If non-nil, following lines get indented according to the innermost
154open parenthesis.") 165open parenthesis.")
155 166
156(defvar ada-search-paren-line-count-limit 5 167(defvar ada-search-paren-char-count-limit 3000
157 "*Search that many non-blank non-comment lines for an open parenthesis. 168 "*Search that many characters for an open parenthesis.")
158Values higher than about 5 horribly slow down the indenting.")
159 169
160 170
161;; ---- other user options 171;; ---- other user options
@@ -166,7 +176,7 @@ Must be one of 'indent-rigidly, 'indent-auto, 'gei, 'indent-af or 'always-tab.
166 176
167'indent-rigidly : always adds ada-indent blanks at the beginning of the line. 177'indent-rigidly : always adds ada-indent blanks at the beginning of the line.
168'indent-auto : use indentation functions in this file. 178'indent-auto : use indentation functions in this file.
169'gei : use David K}gedal's Generic Indentation Engine. 179'gei : use David Kågedal's Generic Indentation Engine.
170'indent-af : use Gary E. Barnes' ada-format.el 180'indent-af : use Gary E. Barnes' ada-format.el
171'always-tab : do indent-relative.") 181'always-tab : do indent-relative.")
172 182
@@ -180,8 +190,8 @@ not to 'begin'.")
180(defvar ada-body-suffix ".adb" 190(defvar ada-body-suffix ".adb"
181 "*Suffix of Ada body files.") 191 "*Suffix of Ada body files.")
182 192
183(defvar ada-language-version 'ada94 193(defvar ada-language-version 'ada95
184 "*Do we program in 'ada83 or 'ada94?") 194 "*Do we program in 'ada83 or 'ada95?")
185 195
186(defvar ada-case-keyword 'downcase-word 196(defvar ada-case-keyword 'downcase-word
187 "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word 197 "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word
@@ -191,6 +201,10 @@ to adjust ada keywords case.")
191 "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word 201 "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word
192to adjust ada identifier case.") 202to adjust ada identifier case.")
193 203
204(defvar ada-case-attribute 'capitalize-word
205 "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word
206to adjust ada identifier case.")
207
194(defvar ada-auto-case t 208(defvar ada-auto-case t
195 "*Non-nil automatically changes casing of preceeding word while typing. 209 "*Non-nil automatically changes casing of preceeding word while typing.
196Casing is done according to ada-case-keyword and ada-case-identifier.") 210Casing is done according to ada-case-keyword and ada-case-identifier.")
@@ -215,9 +229,9 @@ This is a good place to add Ada environment specific bindings.")
215 "*This is inserted at the end of each line when filling a comment paragraph 229 "*This is inserted at the end of each line when filling a comment paragraph
216with ada-fill-comment-paragraph postfix.") 230with ada-fill-comment-paragraph postfix.")
217 231
218(defvar ada-krunch-args "250" 232(defvar ada-krunch-args "0"
219 "*Argument of gnatk8, a string containing the max number of characters. 233 "*Argument of gnatk8, a string containing the max number of characters.
220Set to a big number, if you dont use crunched filenames.") 234Set to 0, if you dont use crunched filenames.")
221 235
222;;; ---- end of user configurable variables 236;;; ---- end of user configurable variables
223 237
@@ -232,6 +246,9 @@ Set to a big number, if you dont use crunched filenames.")
232(defvar ada-mode-syntax-table nil 246(defvar ada-mode-syntax-table nil
233 "Syntax table to be used for editing Ada source code.") 247 "Syntax table to be used for editing Ada source code.")
234 248
249(defvar ada-mode-symbol-syntax-table nil
250 "Syntax table for Ada, where `_' is a word constituent.")
251
235(defconst ada-83-keywords 252(defconst ada-83-keywords
236 "\\<\\(abort\\|abs\\|accept\\|access\\|all\\|and\\|array\\|\ 253 "\\<\\(abort\\|abs\\|accept\\|access\\|all\\|and\\|array\\|\
237at\\|begin\\|body\\|case\\|constant\\|declare\\|delay\\|delta\\|\ 254at\\|begin\\|body\\|case\\|constant\\|declare\\|delay\\|delta\\|\
@@ -243,7 +260,7 @@ return\\|reverse\\|select\\|separate\\|subtype\\|task\\|terminate\\|\
243then\\|type\\|use\\|when\\|while\\|with\\|xor\\)\\>" 260then\\|type\\|use\\|when\\|while\\|with\\|xor\\)\\>"
244 "regular expression for looking at Ada83 keywords.") 261 "regular expression for looking at Ada83 keywords.")
245 262
246(defconst ada-94-keywords 263(defconst ada-95-keywords
247 "\\<\\(abort\\|abs\\|abstract\\|accept\\|access\\|aliased\\|\ 264 "\\<\\(abort\\|abs\\|abstract\\|accept\\|access\\|aliased\\|\
248all\\|and\\|array\\|at\\|begin\\|body\\|case\\|constant\\|declare\\|\ 265all\\|and\\|array\\|at\\|begin\\|body\\|case\\|constant\\|declare\\|\
249delay\\|delta\\|digits\\|do\\|else\\|elsif\\|end\\|entry\\|\ 266delay\\|delta\\|digits\\|do\\|else\\|elsif\\|end\\|entry\\|\
@@ -253,9 +270,9 @@ out\\|package\\|pragma\\|private\\|procedure\\|protected\\|raise\\|\
253range\\|record\\|rem\\|renames\\|requeue\\|return\\|reverse\\|\ 270range\\|record\\|rem\\|renames\\|requeue\\|return\\|reverse\\|\
254select\\|separate\\|subtype\\|tagged\\|task\\|terminate\\|then\\|\ 271select\\|separate\\|subtype\\|tagged\\|task\\|terminate\\|then\\|\
255type\\|until\\|use\\|when\\|while\\|with\\|xor\\)\\>" 272type\\|until\\|use\\|when\\|while\\|with\\|xor\\)\\>"
256 "regular expression for looking at Ad94 keywords.") 273 "regular expression for looking at Ada95 keywords.")
257 274
258(defvar ada-keywords ada-94-keywords 275(defvar ada-keywords ada-95-keywords
259 "regular expression for looking at Ada keywords.") 276 "regular expression for looking at Ada keywords.")
260 277
261(defvar ada-ret-binding nil 278(defvar ada-ret-binding nil
@@ -266,6 +283,10 @@ type\\|until\\|use\\|when\\|while\\|with\\|xor\\)\\>"
266 283
267;;; ---- Regexps to find procedures/functions/packages 284;;; ---- Regexps to find procedures/functions/packages
268 285
286(defconst ada-ident-re
287 "[a-zA-Z0-9_\\.]+"
288 "Regexp matching Ada identifiers.")
289
269(defvar ada-procedure-start-regexp 290(defvar ada-procedure-start-regexp
270 "^[ \t]*\\(procedure\\|function\\|task\\)[ \t\n]+\\([a-zA-Z0-9_\\.]+\\)" 291 "^[ \t]*\\(procedure\\|function\\|task\\)[ \t\n]+\\([a-zA-Z0-9_\\.]+\\)"
271 "Regexp used to find Ada procedures/functions.") 292 "Regexp used to find Ada procedures/functions.")
@@ -279,12 +300,15 @@ type\\|until\\|use\\|when\\|while\\|with\\|xor\\)\\>"
279 300
280(defvar ada-block-start-re 301(defvar ada-block-start-re
281 "\\<\\(begin\\|select\\|declare\\|private\\|or\\|generic\\|\ 302 "\\<\\(begin\\|select\\|declare\\|private\\|or\\|generic\\|\
282exception\\|loop\\|record\\|else\\)\\>" 303exception\\|loop\\|else\\|\
304\\(\\(limited\\|abstract\\|tagged\\)[ \t]+\\)*record\\)\\>"
283 "Regexp for keywords starting ada-blocks.") 305 "Regexp for keywords starting ada-blocks.")
284 306
285(defvar ada-end-stmt-re 307(defvar ada-end-stmt-re
286 "\\(;\\|=>\\|\\<\\(begin\\|record\\|loop\\|select\\|do\\|\ 308 "\\(;\\|=>\\|^[ \t]*separate[ \t]+([a-zA-Z0-9_\\.]+)\\|\
287exception\\|declare\\|generic\\|private\\)\\>\\)" 309\\<\\(begin\\|else\\|record\\|loop\\|select\\|do\\|\
310^[ \t]*package[ \ta-zA-Z0-9_\\.]+is\\|\
311^[ \t]*exception\\|declare\\|generic\\|private\\)\\>\\)"
288 "Regexp of possible ends for a non-broken statement. 312 "Regexp of possible ends for a non-broken statement.
289'end' means that there has to start a new statement after these.") 313'end' means that there has to start a new statement after these.")
290 314
@@ -293,7 +317,8 @@ exception\\|declare\\|generic\\|private\\)\\>\\)"
293 "Regexp for the start of a loop.") 317 "Regexp for the start of a loop.")
294 318
295(defvar ada-subprog-start-re 319(defvar ada-subprog-start-re
296 "\\<\\(procedure\\|function\\|task\\|accept\\)\\>" 320 "\\<\\(procedure\\|protected\\|package[ \t]+body\\|function\\|\
321task\\|accept\\|entry\\)\\>"
297 "Regexp for the start of a subprogram.") 322 "Regexp for the start of a subprogram.")
298 323
299 324
@@ -301,17 +326,16 @@ exception\\|declare\\|generic\\|private\\)\\>\\)"
301;;; functions 326;;; functions
302;;;------------- 327;;;-------------
303 328
329(defun ada-xemacs ()
330 (or (string-match "Lucid" emacs-version)
331 (string-match "XEmacs" emacs-version)))
332
304(defun ada-create-syntax-table () 333(defun ada-create-syntax-table ()
305 "Create the syntax table for ada-mode." 334 "Create the syntax table for ada-mode."
306 ;; This syntax table is a merge of two syntax tables I found 335 ;; There are two different syntax-tables. The standard one declares
307 ;; in the two ada modes in the old ada.el and the old 336 ;; `_' a symbol constituent, in the second one, it is a word
308 ;; electric-ada.el. (jsl) 337 ;; constituent. For some search and replacing routines we
309 ;; There still remains the problem, if the underscore '_' is a word 338 ;; temporarily switch between the two.
310 ;; constituent or not. (re)
311 ;; The Emacs doc clearly states that it is a symbol, and that is what most
312 ;; on the ada-mode list prefer. (re)
313 ;; For some functions, the syntactical meaning of '_' is temporaryly
314 ;; changed to 'w'. (mh)
315 (setq ada-mode-syntax-table (make-syntax-table)) 339 (setq ada-mode-syntax-table (make-syntax-table))
316 (set-syntax-table ada-mode-syntax-table) 340 (set-syntax-table ada-mode-syntax-table)
317 341
@@ -353,6 +377,9 @@ exception\\|declare\\|generic\\|private\\)\\>\\)"
353 ;; define parentheses to match 377 ;; define parentheses to match
354 (modify-syntax-entry ?\( "()" ada-mode-syntax-table) 378 (modify-syntax-entry ?\( "()" ada-mode-syntax-table)
355 (modify-syntax-entry ?\) ")(" ada-mode-syntax-table) 379 (modify-syntax-entry ?\) ")(" ada-mode-syntax-table)
380
381 (setq ada-mode-symbol-syntax-table (copy-syntax-table ada-mode-syntax-table))
382 (modify-syntax-entry ?_ "w" ada-mode-symbol-syntax-table)
356 ) 383 )
357 384
358 385
@@ -378,8 +405,8 @@ Bindings are as follows: (Note: 'LFD' is control-j.)
378 Fill comment paragraph and justify each line '\\[ada-fill-comment-paragraph-justify]' 405 Fill comment paragraph and justify each line '\\[ada-fill-comment-paragraph-justify]'
379 Fill comment paragraph, justify and append postfix '\\[ada-fill-comment-paragraph-postfix]' 406 Fill comment paragraph, justify and append postfix '\\[ada-fill-comment-paragraph-postfix]'
380 407
381 Next func/proc/task '\\[ada-next-procedure]' Previous func/proc/task '\\[ada-previous-procedure]' 408 Next func/proc/task '\\[ada-next-procedure]' Previous func/proc/task '\\[ada-previous-procedure]'
382 Next package '\\[ada-next-package]' Previous package '\\[ada-previous-package]' 409 Next package '\\[ada-next-package]' Previous package '\\[ada-previous-package]'
383 410
384 Goto matching start of current 'end ...;' '\\[ada-move-to-start]' 411 Goto matching start of current 'end ...;' '\\[ada-move-to-start]'
385 Goto end of current block '\\[ada-move-to-end]' 412 Goto end of current block '\\[ada-move-to-end]'
@@ -398,6 +425,8 @@ If you use find-file.el:
398 or '\\[ff-mouse-find-other-file] 425 or '\\[ff-mouse-find-other-file]
399 Switch to other file in other window '\\[ada-ff-other-window]' 426 Switch to other file in other window '\\[ada-ff-other-window]'
400 or '\\[ff-mouse-find-other-file-other-window] 427 or '\\[ff-mouse-find-other-file-other-window]
428 If you use this function in a spec and no body is available, it gets created
429 with body stubs.
401 430
402If you use ada-xref.el: 431If you use ada-xref.el:
403 Goto declaration: '\\[ada-point-and-xref]' on the identifier 432 Goto declaration: '\\[ada-point-and-xref]' on the identifier
@@ -473,8 +502,8 @@ If you use ada-xref.el:
473 502
474 (cond ((eq ada-language-version 'ada83) 503 (cond ((eq ada-language-version 'ada83)
475 (setq ada-keywords ada-83-keywords)) 504 (setq ada-keywords ada-83-keywords))
476 ((eq ada-language-version 'ada94) 505 ((eq ada-language-version 'ada95)
477 (setq ada-keywords ada-94-keywords))) 506 (setq ada-keywords ada-95-keywords)))
478 507
479 (if ada-auto-case 508 (if ada-auto-case
480 (ada-activate-keys-for-case))) 509 (ada-activate-keys-for-case)))
@@ -719,7 +748,8 @@ ada-tmp-directory."
719 (looking-at (concat ada-keywords "[^_]"))))) 748 (looking-at (concat ada-keywords "[^_]")))))
720 749
721(defun ada-after-char-p () 750(defun ada-after-char-p ()
722 ;; returns t if after ada character "'". 751 ;; returns t if after ada character "'". This is interpreted as being
752 ;; in a character constant.
723 (save-excursion 753 (save-excursion
724 (if (> (point) 2) 754 (if (> (point) 2)
725 (progn 755 (progn
@@ -738,11 +768,17 @@ identifier." ; (MH)
738 (ada-in-comment-p) 768 (ada-in-comment-p)
739 (ada-after-char-p)))) 769 (ada-after-char-p))))
740 (if (eq (char-syntax (char-after (1- (point)))) ?w) 770 (if (eq (char-syntax (char-after (1- (point)))) ?w)
741 (if (and 771 (if (save-excursion
742 (not force-identifier) ; (MH) 772 (forward-word -1)
743 (ada-after-keyword-p)) 773 (or (= (point) (point-min))
744 (funcall ada-case-keyword -1) 774 (backward-char 1))
745 (funcall ada-case-identifier -1)))) 775 (looking-at "'"))
776 (funcall ada-case-attribute -1)
777 (if (and
778 (not force-identifier) ; (MH)
779 (ada-after-keyword-p))
780 (funcall ada-case-keyword -1)
781 (funcall ada-case-identifier -1)))))
746 (forward-char 1)) 782 (forward-char 1))
747 783
748 784
@@ -818,40 +854,43 @@ ATTENTION: This function might take very long for big regions !"
818 (end nil) 854 (end nil)
819 (keywordp nil) 855 (keywordp nil)
820 (reldiff nil)) 856 (reldiff nil))
821 (save-excursion 857 (unwind-protect
822 (goto-char to) 858 (save-excursion
823 ;; 859 (set-syntax-table ada-mode-symbol-syntax-table)
824 ;; loop: look for all identifiers and keywords 860 (goto-char to)
825 ;; 861 ;;
826 (while (re-search-backward 862 ;; loop: look for all identifiers and keywords
827 "[^a-zA-Z0-9_]\\([a-zA-Z0-9_]+\\)[^a-zA-Z0-9_]" 863 ;;
828 from 864 (while (re-search-backward
829 t) 865 "[^a-zA-Z0-9_]\\([a-zA-Z0-9_]+\\)[^a-zA-Z0-9_]"
830 ;; 866 from
831 ;; print status message 867 t)
832 ;; 868 ;;
833 (setq reldiff (- (point) from)) 869 ;; print status message
834 (message (format "adjusting case ... %5d characters left" 870 ;;
835 (- (point) from))) 871 (setq reldiff (- (point) from))
836 (forward-char 1) 872 (message (format "adjusting case ... %5d characters left"
837 (or 873 (- (point) from)))
838 ;; do nothing if it is a string or comment 874 (forward-char 1)
839 (ada-in-string-or-comment-p) 875 (or
840 (progn 876 ;; do nothing if it is a string or comment
841 ;; 877 (ada-in-string-or-comment-p)
842 ;; get the identifier or keyword 878 (progn
843 ;; 879 ;;
844 (setq begin (point)) 880 ;; get the identifier or keyword
845 (setq keywordp (looking-at (concat ada-keywords "[^_]"))) 881 ;;
846 (skip-chars-forward "a-zA-Z0-9_") 882 (setq begin (point))
847 ;; 883 (setq keywordp (looking-at (concat ada-keywords "[^_]")))
848 ;; casing according to user-option 884 (skip-chars-forward "a-zA-Z0-9_")
849 ;; 885 ;;
850 (if keywordp 886 ;; casing according to user-option
851 (funcall ada-case-keyword -1) 887 ;;
852 (funcall ada-case-identifier -1)) 888 (if keywordp
853 (goto-char begin)))) 889 (funcall ada-case-keyword -1)
854 (message "adjusting case ... done")))) 890 (funcall ada-case-identifier -1))
891 (goto-char begin))))
892 (message "adjusting case ... done"))
893 (set-syntax-table ada-mode-syntax-table))))
855 894
856 895
857;; 896;;
@@ -860,7 +899,7 @@ ATTENTION: This function might take very long for big regions !"
860(defun ada-adjust-case-buffer () 899(defun ada-adjust-case-buffer ()
861 "Adjusts the case of all identifiers and keywords in the whole buffer. 900 "Adjusts the case of all identifiers and keywords in the whole buffer.
862ATTENTION: This function might take very long for big buffers !" 901ATTENTION: This function might take very long for big buffers !"
863 (interactive) 902 (interactive "*")
864 (ada-adjust-case-region (point-min) (point-max))) 903 (ada-adjust-case-region (point-min) (point-max)))
865 904
866 905
@@ -880,59 +919,59 @@ In such a case, use 'undo', correct the syntax and try again."
880 (end nil) 919 (end nil)
881 (delend nil) 920 (delend nil)
882 (paramlist nil)) 921 (paramlist nil))
883 ;; 922 (unwind-protect
884 ;; ATTENTION: modify sntax-table temporary ! 923 (progn
885 ;; 924 (set-syntax-table ada-mode-symbol-syntax-table)
886 (modify-syntax-entry ?_ "w") 925
887 926 ;; check if really inside parameter list
888 ;; check if really inside parameter list 927 (or (ada-in-paramlist-p)
889 (or (ada-in-paramlist-p) 928 (error "not in parameter list"))
890 (error "not in parameter list")) 929 ;;
891 ;; 930 ;; find start of current parameter-list
892 ;; find start of current parameter-list 931 ;;
893 ;; 932 (ada-search-ignore-string-comment
894 (ada-search-ignore-string-comment 933 (concat "\\<\\("
895 (concat "\\<\\(" 934 "procedure\\|function\\|body\\|package\\|task\\|entry\\|accept"
896 "procedure\\|function\\|body\\|package\\|task\\|entry\\|accept" 935 "\\)\\>") t nil)
897 "\\)\\>") t nil) 936 (ada-search-ignore-string-comment "(" nil nil t)
898 (ada-search-ignore-string-comment "(" nil nil t) 937 (backward-char 1)
899 (backward-char 1) 938 (setq begin (point))
900 (setq begin (point)) 939
901 940 ;;
902 ;; 941 ;; find end of parameter-list
903 ;; find end of parameter-list 942 ;;
904 ;; 943 (forward-sexp 1)
905 (forward-sexp 1) 944 (setq delend (point))
906 (setq delend (point)) 945 (delete-char -1)
907 (delete-char -1) 946
908 947 ;;
909 ;; 948 ;; find end of last parameter-declaration
910 ;; find end of last parameter-declaration 949 ;;
911 ;; 950 (ada-search-ignore-string-comment "[^ \t\n]" t nil t)
912 (ada-search-ignore-string-comment "[^ \t\n]" t nil t) 951 (forward-char 1)
913 (forward-char 1) 952 (setq end (point))
914 (setq end (point)) 953
915 954 ;;
916 ;; 955 ;; build a list of all elements of the parameter-list
917 ;; build a list of all elements of the parameter-list 956 ;;
918 ;; 957 (setq paramlist (ada-scan-paramlist (1+ begin) end))
919 (setq paramlist (ada-scan-paramlist (1+ begin) end)) 958
920 959 ;;
921 ;; 960 ;; delete the original parameter-list
922 ;; delete the original parameter-list 961 ;;
923 ;; 962 (delete-region begin (1- delend))
924 (delete-region begin (1- delend)) 963
925 964 ;;
926 ;; 965 ;; insert the new parameter-list
927 ;; insert the new parameter-list 966 ;;
928 ;; 967 (goto-char begin)
929 (goto-char begin) 968 (ada-insert-paramlist paramlist))
930 (ada-insert-paramlist paramlist) 969
931 970 ;;
932 ;; 971 ;; restore syntax-table
933 ;; restore syntax-table 972 ;;
934 ;; 973 (set-syntax-table ada-mode-syntax-table)
935 (modify-syntax-entry ?_ "_"))) 974 )))
936 975
937 976
938(defun ada-scan-paramlist (begin end) 977(defun ada-scan-paramlist (begin end)
@@ -1246,47 +1285,46 @@ In such a case, use 'undo', correct the syntax and try again."
1246 "Moves point to the matching start of the current end ... around point." 1285 "Moves point to the matching start of the current end ... around point."
1247 (interactive) 1286 (interactive)
1248 (let ((pos (point))) 1287 (let ((pos (point)))
1249 ;; 1288 (unwind-protect
1250 ;; ATTENTION: modify sntax-table temporary ! 1289 (progn
1251 ;; 1290 (set-syntax-table ada-mode-symbol-syntax-table)
1252 (modify-syntax-entry ?_ "w") 1291
1253 1292 (message "searching for block start ...")
1254 (message "searching for block start ...") 1293 (save-excursion
1255 (save-excursion 1294 ;;
1256 ;; 1295 ;; do nothing if in string or comment or not on 'end ...;'
1257 ;; do nothing if in string or comment or not on 'end ...;' 1296 ;; or if an error occurs during processing
1258 ;; or if an error occurs during processing 1297 ;;
1259 ;; 1298 (or
1260 (or 1299 (ada-in-string-or-comment-p)
1261 (ada-in-string-or-comment-p) 1300 (and (progn
1262 (and (progn 1301 (or (looking-at "[ \t]*\\<end\\>")
1263 (or (looking-at "[ \t]*\\<end\\>") 1302 (backward-word 1))
1264 (backward-word 1)) 1303 (or (looking-at "[ \t]*\\<end\\>")
1265 (or (looking-at "[ \t]*\\<end\\>") 1304 (backward-word 1))
1266 (backward-word 1)) 1305 (or (looking-at "[ \t]*\\<end\\>")
1267 (or (looking-at "[ \t]*\\<end\\>") 1306 (error "not on end ...;")))
1268 (error "not on end ...;"))) 1307 (ada-goto-matching-start 1)
1269 (ada-goto-matching-start 1) 1308 (setq pos (point))
1270 (setq pos (point)) 1309
1271 1310 ;;
1272 ;; 1311 ;; on 'begin' => go on, according to user option
1273 ;; on 'begin' => go on, according to user option 1312 ;;
1274 ;; 1313 ada-move-to-declaration
1275 ada-move-to-declaration 1314 (looking-at "\\<begin\\>")
1276 (looking-at "\\<begin\\>") 1315 (ada-goto-matching-decl-start)
1277 (ada-goto-matching-decl-start) 1316 (setq pos (point))))
1278 (setq pos (point)))) 1317
1279 1318 ) ; end of save-excursion
1280 ) ; end of save-excursion 1319
1281 1320 ;; now really move to the found position
1282 ;; now really move to the found position 1321 (goto-char pos)
1283 (goto-char pos) 1322 (message "searching for block start ... done"))
1284 (message "searching for block start ... done") 1323
1285 1324 ;;
1286 ;; 1325 ;; restore syntax-table
1287 ;; restore syntax-table 1326 ;;
1288 ;; 1327 (set-syntax-table ada-mode-syntax-table))))
1289 (modify-syntax-entry ?_ "_")))
1290 1328
1291 1329
1292(defun ada-move-to-end () 1330(defun ada-move-to-end ()
@@ -1296,64 +1334,63 @@ Moves to 'begin' if in a declarative part."
1296 (let ((pos (point)) 1334 (let ((pos (point))
1297 (decstart nil) 1335 (decstart nil)
1298 (packdecl nil)) 1336 (packdecl nil))
1299 ;; 1337 (unwind-protect
1300 ;; ATTENTION: modify sntax-table temporary ! 1338 (progn
1301 ;; 1339 (set-syntax-table ada-mode-symbol-syntax-table)
1302 (modify-syntax-entry ?_ "w") 1340
1303 1341 (message "searching for block end ...")
1304 (message "searching for block end ...") 1342 (save-excursion
1305 (save-excursion 1343
1306 1344 (forward-char 1)
1307 (forward-char 1) 1345 (cond
1308 (cond 1346 ;; directly on 'begin'
1309 ;; directly on 'begin' 1347 ((save-excursion
1310 ((save-excursion 1348 (ada-goto-previous-word)
1311 (ada-goto-previous-word) 1349 (looking-at "\\<begin\\>"))
1312 (looking-at "\\<begin\\>")) 1350 (ada-goto-matching-end 1))
1313 (ada-goto-matching-end 1)) 1351 ;; on first line of defun declaration
1314 ;; on first line of defun declaration 1352 ((save-excursion
1315 ((save-excursion 1353 (and (ada-goto-stmt-start)
1316 (and (ada-goto-stmt-start) 1354 (looking-at "\\<function\\>\\|\\<procedure\\>" )))
1317 (looking-at "\\<function\\>\\|\\<procedure\\>" ))) 1355 (ada-search-ignore-string-comment "\\<begin\\>"))
1318 (ada-search-ignore-string-comment "\\<begin\\>")) 1356 ;; on first line of task declaration
1319 ;; on first line of task declaration 1357 ((save-excursion
1320 ((save-excursion 1358 (and (ada-goto-stmt-start)
1321 (and (ada-goto-stmt-start) 1359 (looking-at "\\<task\\>" )
1322 (looking-at "\\<task\\>" ) 1360 (forward-word 1)
1323 (forward-word 1) 1361 (ada-search-ignore-string-comment "[^ \n\t]")
1324 (ada-search-ignore-string-comment "[^ \n\t]") 1362 (not (backward-char 1))
1325 (not (backward-char 1)) 1363 (looking-at "\\<body\\>")))
1326 (looking-at "\\<body\\>"))) 1364 (ada-search-ignore-string-comment "\\<begin\\>"))
1327 (ada-search-ignore-string-comment "\\<begin\\>")) 1365 ;; accept block start
1328 ;; accept block start 1366 ((save-excursion
1329 ((save-excursion 1367 (and (ada-goto-stmt-start)
1330 (and (ada-goto-stmt-start) 1368 (looking-at "\\<accept\\>" )))
1331 (looking-at "\\<accept\\>" ))) 1369 (ada-goto-matching-end 0))
1332 (ada-goto-matching-end 0)) 1370 ;; package start
1333 ;; package start 1371 ((save-excursion
1334 ((save-excursion 1372 (and (ada-goto-matching-decl-start t)
1335 (and (ada-goto-matching-decl-start t) 1373 (looking-at "\\<package\\>")))
1336 (looking-at "\\<package\\>"))) 1374 (ada-goto-matching-end 1))
1337 (ada-goto-matching-end 1)) 1375 ;; inside a 'begin' ... 'end' block
1338 ;; inside a 'begin' ... 'end' block 1376 ((save-excursion
1339 ((save-excursion 1377 (ada-goto-matching-decl-start t))
1340 (ada-goto-matching-decl-start t)) 1378 (ada-search-ignore-string-comment "\\<begin\\>"))
1341 (ada-search-ignore-string-comment "\\<begin\\>")) 1379 ;; (hopefully ;-) everything else
1342 ;; (hopefully ;-) everything else 1380 (t
1343 (t 1381 (ada-goto-matching-end 1)))
1344 (ada-goto-matching-end 1))) 1382 (setq pos (point))
1345 (setq pos (point)) 1383
1346 1384 ) ; end of save-excursion
1347 ) ; end of save-excursion 1385
1348 1386 ;; now really move to the found position
1349 ;; now really move to the found position 1387 (goto-char pos)
1350 (goto-char pos) 1388 (message "searching for block end ... done"))
1351 (message "searching for block end ... done") 1389
1352 1390 ;;
1353 ;; 1391 ;; restore syntax-table
1354 ;; restore syntax-table 1392 ;;
1355 ;; 1393 (set-syntax-table ada-mode-syntax-table))))
1356 (modify-syntax-entry ?_ "_")))
1357 1394
1358 1395
1359;;;-----------------------------;;; 1396;;;-----------------------------;;;
@@ -1366,19 +1403,28 @@ Moves to 'begin' if in a declarative part."
1366 "Indents the region using ada-indent-current on each line." 1403 "Indents the region using ada-indent-current on each line."
1367 (interactive "*r") 1404 (interactive "*r")
1368 (goto-char beg) 1405 (goto-char beg)
1369 ;; catch errors while indenting 1406 (let ((block-done 0)
1370 (condition-case err 1407 (lines-remaining (count-lines beg end))
1371 (while (< (point) end) 1408 (msg (format "indenting %4d lines %%4d lines remaining ..."
1372 (message (format "indenting ... %4d lines left" 1409 (count-lines beg end)))
1373 (count-lines (point) end))) 1410 (endmark (copy-marker end)))
1374 (ada-indent-current) 1411 ;; catch errors while indenting
1375 (forward-line 1)) 1412 (condition-case err
1376 ;; show line number where the error occured 1413 (while (< (point) endmark)
1377 (error 1414 (if (> block-done 9)
1378 (error (format "line %d: %s" 1415 (progn (message (format msg lines-remaining))
1379 (1+ (count-lines (point-min) (point))) 1416 (setq block-done 0)))
1380 err) nil))) 1417 (if (looking-at "^$") nil
1381 (message "indenting ... done")) 1418 (ada-indent-current))
1419 (forward-line 1)
1420 (setq block-done (1+ block-done))
1421 (setq lines-remaining (1- lines-remaining)))
1422 ;; show line number where the error occured
1423 (error
1424 (error (format "line %d: %s"
1425 (1+ (count-lines (point-min) (point)))
1426 err) nil)))
1427 (message "indenting ... done")))
1382 1428
1383 1429
1384(defun ada-indent-newline-indent () 1430(defun ada-indent-newline-indent ()
@@ -1392,18 +1438,17 @@ Moves to 'begin' if in a declarative part."
1392 (delete-horizontal-space) 1438 (delete-horizontal-space)
1393 (setq orgpoint (point)) 1439 (setq orgpoint (point))
1394 1440
1395 ;; 1441 (unwind-protect
1396 ;; ATTENTION: modify syntax-table temporary ! 1442 (progn
1397 ;; 1443 (set-syntax-table ada-mode-symbol-syntax-table)
1398 (modify-syntax-entry ?_ "w")
1399 1444
1400 (setq column (save-excursion 1445 (setq column (save-excursion
1401 (funcall (ada-indent-function) orgpoint))) 1446 (funcall (ada-indent-function) orgpoint))))
1402 1447
1403 ;; 1448 ;;
1404 ;; restore syntax-table 1449 ;; restore syntax-table
1405 ;; 1450 ;;
1406 (modify-syntax-entry ?_ "_") 1451 (set-syntax-table ada-mode-syntax-table))
1407 1452
1408 (indent-to column) 1453 (indent-to column)
1409 1454
@@ -1438,57 +1483,59 @@ This works by two steps:
1438 1483
1439 (interactive) 1484 (interactive)
1440 1485
1441 ;; 1486 (unwind-protect
1442 ;; ATTENTION: modify sntax-table temporary ! 1487 (progn
1443 ;; 1488 (set-syntax-table ada-mode-symbol-syntax-table)
1444 (modify-syntax-entry ?_ "w") 1489
1445 1490 (let ((line-end)
1446 (let ((line-end) 1491 (orgpoint (point-marker))
1447 (orgpoint (point-marker)) 1492 (cur-indent)
1448 (cur-indent) 1493 (prev-indent)
1449 (prev-indent) 1494 (prevline t))
1450 (prevline t)) 1495
1496 ;;
1497 ;; first step
1498 ;;
1499 (save-excursion
1500 (if (ada-goto-prev-nonblank-line t)
1501 ;;
1502 ;; we are not in the first accessible line in the buffer
1503 ;;
1504 (progn
1505 ;;(end-of-line)
1506 ;;(forward-char 1)
1507 ;; we are already at the BOL
1508 (forward-line 1)
1509 (setq line-end (point))
1510 (setq prev-indent
1511 (save-excursion
1512 (funcall (ada-indent-function) line-end))))
1513 (setq prevline nil)))
1514
1515 (if prevline
1516 ;;
1517 ;; we are not in the first accessible line in the buffer
1518 ;;
1519 (progn
1520 ;;
1521 ;; second step
1522 ;;
1523 (back-to-indentation)
1524 (setq cur-indent (ada-get-current-indent prev-indent))
1525 (delete-horizontal-space)
1526 (indent-to cur-indent)
1527
1528 ;;
1529 ;; restore position of point
1530 ;;
1531 (goto-char orgpoint)
1532 (if (< (current-column) (current-indentation))
1533 (back-to-indentation))))))
1451 1534
1452 ;; 1535 ;;
1453 ;; first step 1536 ;; restore syntax-table
1454 ;; 1537 ;;
1455 (save-excursion 1538 (set-syntax-table ada-mode-syntax-table)))
1456 (if (ada-goto-prev-nonblank-line t)
1457 ;;
1458 ;; we are not in the first accessible line in the buffer
1459 ;;
1460 (progn
1461 (end-of-line)
1462 (forward-char 1)
1463 (setq line-end (point))
1464 (setq prev-indent (save-excursion
1465 (funcall (ada-indent-function) line-end))))
1466 (setq prevline nil)))
1467
1468 (if prevline
1469 ;;
1470 ;; we are not in the first accessible line in the buffer
1471 ;;
1472 (progn
1473 ;;
1474 ;; second step
1475 ;;
1476 (back-to-indentation)
1477 (setq cur-indent (ada-get-current-indent prev-indent))
1478 (delete-horizontal-space)
1479 (indent-to cur-indent)
1480
1481 ;;
1482 ;; restore position of point
1483 ;;
1484 (goto-char orgpoint)
1485 (if (< (current-column) (current-indentation))
1486 (back-to-indentation)))))
1487
1488 ;;
1489 ;; restore syntax-table
1490 ;;
1491 (modify-syntax-entry ?_ "_"))
1492 1539
1493 1540
1494(defun ada-get-current-indent (prev-indent) 1541(defun ada-get-current-indent (prev-indent)
@@ -1785,13 +1832,9 @@ This works by two steps:
1785 ((looking-at "\\<type\\>") 1832 ((looking-at "\\<type\\>")
1786 (setq func 'ada-get-indent-type)) 1833 (setq func 'ada-get-indent-type))
1787 ;; 1834 ;;
1788 ((looking-at "\\<if\\>") 1835 ((looking-at "\\<\\(els\\)?if\\>")
1789 (setq func 'ada-get-indent-if)) 1836 (setq func 'ada-get-indent-if))
1790 ;; 1837 ;;
1791 ((looking-at "\\<elsif\\>")
1792 (setq func 'ada-get-indent-if)) ; maybe it needs a special
1793 ; function sometimes ?
1794 ;;
1795 ((looking-at "\\<case\\>") 1838 ((looking-at "\\<case\\>")
1796 (setq func 'ada-get-indent-case)) 1839 (setq func 'ada-get-indent-case))
1797 ;; 1840 ;;
@@ -1804,6 +1847,8 @@ This works by two steps:
1804 ((looking-at "[a-zA-Z0-9_]+[ \t\n]*:[^=]") 1847 ((looking-at "[a-zA-Z0-9_]+[ \t\n]*:[^=]")
1805 (setq func 'ada-get-indent-label)) 1848 (setq func 'ada-get-indent-label))
1806 ;; 1849 ;;
1850 ((looking-at "\\<separate\\>")
1851 (setq func 'ada-get-indent-nochange))
1807 (t 1852 (t
1808 (setq func 'ada-get-indent-noindent)))))) 1853 (setq func 'ada-get-indent-noindent))))))
1809 1854
@@ -1904,7 +1949,7 @@ This works by two steps:
1904 ;; 1949 ;;
1905 ;; a named block end 1950 ;; a named block end
1906 ;; 1951 ;;
1907 ((looking-at "[a-zA-Z0-9_]+") 1952 ((looking-at ada-ident-re)
1908 (setq defun-name (buffer-substring (match-beginning 0) 1953 (setq defun-name (buffer-substring (match-beginning 0)
1909 (match-end 0))) 1954 (match-end 0)))
1910 (save-excursion 1955 (save-excursion
@@ -2307,10 +2352,12 @@ This works by two steps:
2307 (ada-search-ignore-string-comment ";" nil orgpoint)) 2352 (ada-search-ignore-string-comment ";" nil orgpoint))
2308 (current-indentation)) 2353 (current-indentation))
2309 ;; 2354 ;;
2310 ;; type ... is 2355 ;; "type ... is", but not "type ... is ...", which is broken
2311 ;; 2356 ;;
2312 ((save-excursion 2357 ((save-excursion
2313 (ada-search-ignore-string-comment "\\<is\\>" nil orgpoint)) 2358 (and
2359 (ada-search-ignore-string-comment "\\<is\\>" nil orgpoint)
2360 (not (ada-search-ignore-string-comment "[^ \t\n]" nil orgpoint))))
2314 (+ (current-indentation) ada-indent)) 2361 (+ (current-indentation) ada-indent))
2315 ;; 2362 ;;
2316 ;; broken statement 2363 ;; broken statement
@@ -2475,7 +2522,7 @@ This works by two steps:
2475 ;; 2522 ;;
2476 ;; 'accept' or 'package' ? 2523 ;; 'accept' or 'package' ?
2477 ;; 2524 ;;
2478 (if (not (looking-at "\\<\\(accept\\|package\\|task\\)\\>")) 2525 (if (not (looking-at "\\<\\(accept\\|package\\|task\\|protected\\)\\>"))
2479 (ada-goto-matching-decl-start)) 2526 (ada-goto-matching-decl-start))
2480 ;; 2527 ;;
2481 ;; 'begin' of 'procedure'/'function'/'task' or 'declare' 2528 ;; 'begin' of 'procedure'/'function'/'task' or 'declare'
@@ -2487,13 +2534,13 @@ This works by two steps:
2487 (if (looking-at "\\<declare\\>") 2534 (if (looking-at "\\<declare\\>")
2488 (ada-goto-stmt-start) 2535 (ada-goto-stmt-start)
2489 ;; 2536 ;;
2490 ;; no, => 'procedure'/'function'/'task' 2537 ;; no, => 'procedure'/'function'/'task'/'protected'
2491 ;; 2538 ;;
2492 (progn 2539 (progn
2493 (forward-word 2) 2540 (forward-word 2)
2494 (backward-word 1) 2541 (backward-word 1)
2495 ;; 2542 ;;
2496 ;; skip 'body' or 'type' 2543 ;; skip 'body' 'protected' 'type'
2497 ;; 2544 ;;
2498 (if (looking-at "\\<\\(body\\|type\\)\\>") 2545 (if (looking-at "\\<\\(body\\|type\\)\\>")
2499 (forward-word 1)) 2546 (forward-word 1))
@@ -2536,8 +2583,7 @@ This works by two steps:
2536 ;; 2583 ;;
2537 ((looking-at "end") 2584 ((looking-at "end")
2538 (ada-goto-matching-start 1 noerror) 2585 (ada-goto-matching-start 1 noerror)
2539 (if (progn 2586 (if (looking-at "begin")
2540 (looking-at "begin"))
2541 (setq nest-count (1+ nest-count)))) 2587 (setq nest-count (1+ nest-count))))
2542 ;; 2588 ;;
2543 ((looking-at "declare\\|generic") 2589 ((looking-at "declare\\|generic")
@@ -2590,7 +2636,7 @@ This works by two steps:
2590 (progn 2636 (progn
2591 (if (looking-at "is") 2637 (if (looking-at "is")
2592 (ada-search-ignore-string-comment 2638 (ada-search-ignore-string-comment
2593 "\\<\\(procedure\\|function\\|task\\|package\\)\\>" t) 2639 ada-subprog-start-re t)
2594 (looking-at "declare\\|generic"))))) 2640 (looking-at "declare\\|generic")))))
2595 (if noerror nil 2641 (if noerror nil
2596 (error "no matching procedure/function/task/declare/package")) 2642 (error "no matching procedure/function/task/declare/package"))
@@ -2614,8 +2660,8 @@ This works by two steps:
2614 (not found) 2660 (not found)
2615 (ada-search-ignore-string-comment 2661 (ada-search-ignore-string-comment
2616 (concat "\\<\\(" 2662 (concat "\\<\\("
2617 "end\\|loop\\|select\\|begin\\|case\\|" 2663 "end\\|loop\\|select\\|begin\\|case\\|do\\|"
2618 "if\\|task\\|package\\|record\\|do\\)\\>") 2664 "if\\|task\\|package\\|record\\|protected\\)\\>")
2619 t)) 2665 t))
2620 2666
2621 ;; 2667 ;;
@@ -2798,9 +2844,9 @@ This works by two steps:
2798 ((ada-in-string-p) 2844 ((ada-in-string-p)
2799 (if backward 2845 (if backward
2800 (progn 2846 (progn
2801 (re-search-backward "\"\\|#" nil 1) 2847 (re-search-backward "\"" nil 1) ; "\"\\|#" don't treat #
2802 (goto-char (match-beginning 0)))) 2848 (goto-char (match-beginning 0))))
2803 (re-search-forward "\"\\|#" nil 1)) 2849 (re-search-forward "\"" nil 1))
2804 ;; 2850 ;;
2805 ;; found character constant => ignore it 2851 ;; found character constant => ignore it
2806 ;; 2852 ;;
@@ -2905,7 +2951,7 @@ This works by two steps:
2905 2951
2906 2952
2907(defun ada-goto-prev-nonblank-line ( &optional ignore-comment) 2953(defun ada-goto-prev-nonblank-line ( &optional ignore-comment)
2908 ;; Moves point to previous non-blank line, 2954 ;; Moves point to the beginning of previous non-blank line,
2909 ;; ignoring comments if IGNORE-COMMENT is non-nil. 2955 ;; ignoring comments if IGNORE-COMMENT is non-nil.
2910 ;; It returns t if a matching line was found. 2956 ;; It returns t if a matching line was found.
2911 (let ((notfound t) 2957 (let ((notfound t)
@@ -2930,9 +2976,9 @@ This works by two steps:
2930 (or (looking-at "[ \t]*$") 2976 (or (looking-at "[ \t]*$")
2931 (and (looking-at "[ \t]*--") 2977 (and (looking-at "[ \t]*--")
2932 ignore-comment))) 2978 ignore-comment)))
2933 (not (in-limit-line-p))) 2979 (not (ada-in-limit-line-p)))
2934 (forward-line -1) 2980 (forward-line -1)
2935 (beginning-of-line) 2981 ;;(beginning-of-line)
2936 (setq newpoint (point))) ; end of loop 2982 (setq newpoint (point))) ; end of loop
2937 2983
2938 )) ; end of if 2984 )) ; end of if
@@ -2971,7 +3017,7 @@ This works by two steps:
2971 (or (looking-at "[ \t]*$") 3017 (or (looking-at "[ \t]*$")
2972 (and (looking-at "[ \t]*--") 3018 (and (looking-at "[ \t]*--")
2973 ignore-comment))) 3019 ignore-comment)))
2974 (not (in-limit-line-p))) 3020 (not (ada-in-limit-line-p)))
2975 (forward-line 1) 3021 (forward-line 1)
2976 (beginning-of-line) 3022 (beginning-of-line)
2977 (setq newpoint (point))) ; end of loop 3023 (setq newpoint (point))) ; end of loop
@@ -3017,11 +3063,11 @@ This works by two steps:
3017 (looking-at "\\<private\\>"))))) 3063 (looking-at "\\<private\\>")))))
3018 3064
3019 3065
3020(defun in-limit-line-p () 3066;;; make a faster??? ada-in-limit-line-p not using count-lines
3021 ;; Returns t if point is in first or last accessible line. 3067(defun ada-in-limit-line-p ()
3022 (or 3068 ;; return t if point is in first or last accessible line.
3023 (>= 1 (count-lines (point-min) (point))) 3069 (or (save-excursion (beginning-of-line) (= (point-min) (point)))
3024 (>= 1 (count-lines (point) (point-max))))) 3070 (save-excursion (end-of-line) (= (point-max) (point)))))
3025 3071
3026 3072
3027(defun ada-in-comment-p () 3073(defun ada-in-comment-p ()
@@ -3041,7 +3087,7 @@ This works by two steps:
3041 (point)) (point))) 3087 (point)) (point)))
3042 ;; check if 'string quote' is only a character constant 3088 ;; check if 'string quote' is only a character constant
3043 (progn 3089 (progn
3044 (re-search-backward "\"\\|#" nil t) 3090 (re-search-backward "\"" nil t) ; # not a string delimiter anymore
3045 (not (= (char-after (1- (point))) ?')))))) 3091 (not (= (char-after (1- (point))) ?'))))))
3046 3092
3047 3093
@@ -3075,168 +3121,26 @@ This works by two steps:
3075 ;; If point is somewhere behind an open parenthesis not yet closed, 3121 ;; If point is somewhere behind an open parenthesis not yet closed,
3076 ;; it returns the column # of the first non-ws behind this open 3122 ;; it returns the column # of the first non-ws behind this open
3077 ;; parenthesis, otherwise nil." 3123 ;; parenthesis, otherwise nil."
3078 (let ((nest-count 1)
3079 (limit nil)
3080 (found nil)
3081 (pos nil)
3082 (col nil)
3083 (counter ada-search-paren-line-count-limit))
3084
3085 ;;
3086 ;; get search-limit
3087 ;;
3088 (if ada-search-paren-line-count-limit
3089 (setq limit
3090 (save-excursion
3091 (while (not (zerop counter))
3092 (ada-goto-prev-nonblank-line)
3093 (setq counter (1- counter)))
3094 (beginning-of-line)
3095 (point))))
3096
3097 (save-excursion
3098
3099 ;;
3100 ;; loop until found or limit
3101 ;;
3102 (while (and
3103 (not found)
3104 (ada-search-ignore-string-comment "(\\|)" t limit t))
3105 (setq nest-count
3106 (if (looking-at ")")
3107 (1+ nest-count)
3108 (1- nest-count)))
3109 (setq found (zerop nest-count))) ; end of loop
3110
3111 (if found
3112 ;; if found => return column of first non-ws after the parenthesis
3113 (progn
3114 (forward-char 1)
3115 (if (save-excursion
3116 (re-search-forward "[^ \t]" nil 1)
3117 (backward-char 1)
3118 (and
3119 (not (looking-at "\n"))
3120 (setq col (current-column))))
3121 col
3122 (current-column)))
3123 nil))))
3124
3125
3126;;;-----------------------------;;;
3127;;; Simple Completion Functions ;;;
3128;;;-----------------------------;;;
3129
3130;; These are my first steps in Emacs-Lisp ... :-) They can be replaced
3131;; by functions based on the output of the Gnatf Tool that comes with
3132;; the GNAT Ada compiler. See the file ada-xref.el (MH) But you might
3133;; use these functions if you don't use GNAT
3134
3135(defun ada-use-last-with ()
3136 "Inserts the package name of the last 'with' statement after use."
3137 (interactive)
3138 (let ((pakname nil))
3139 (save-excursion
3140 (forward-word -1)
3141 (if (looking-at "use")
3142 ;;
3143 ;; find last 'with'
3144 ;;
3145 (progn (re-search-backward
3146 "\\(\\<with\\s-+\\)\\([a-zA-Z0-9_.]+\\)\\(\\s-*;\\)")
3147 ;;
3148 ;; get the name of the package
3149 ;;
3150 (setq pakname (concat
3151 (buffer-substring (match-beginning 2)
3152 (match-end 2))
3153 ";")))
3154 (setq pakname "")))
3155 (insert pakname)))
3156
3157
3158(defun ada-complete-symbol (symboldef position symalist)
3159 ;; Tries to complete a symbol in the buffer.
3160 ;; SYMBOLDEF is the regexp to find the definition of the desired symbol.
3161 ;; POSITION is the position of the subexpression in SYMBOLDEF to match
3162 ;; the symbol itself.
3163 ;; SYMALIST is an alist with possibly predefined completions."
3164 (let ((sofar nil)
3165 (completed nil)
3166 (insertpos nil))
3167 (save-excursion
3168 ;;
3169 ;; get the part of the symbol already typed
3170 ;;
3171 (re-search-backward "\\([^a-zA-Z0-9_\\.]\\)\\([a-zA-Z0-9_\\.]+\\)")
3172 (setq sofar (buffer-substring (match-beginning 2)
3173 (match-end 2)))
3174 ;;
3175 ;; delete it
3176 ;;
3177 (delete-region (setq insertpos (match-beginning 2))
3178 (match-end 2))
3179 ;;
3180 ;; find all possible completions by searching for definitions of
3181 ;; this kind of symbol
3182 ;;
3183 (while (re-search-backward symboldef nil t)
3184 ;;
3185 ;; build an alist of these possible completions
3186 ;;
3187 (setq symalist (cons (cons (buffer-substring (match-beginning position)
3188 (match-end position))
3189 nil)
3190 symalist)))
3191
3192 (or
3193 ;;
3194 ;; symbol gets completed as far as possible
3195 ;;
3196 (stringp (setq completed (try-completion sofar symalist)))
3197 ;;
3198 ;; or is already complete
3199 ;;
3200 (setq completed sofar)))
3201 ;;
3202 ;; insert the completed symbol
3203 ;;
3204 (goto-char insertpos)
3205 (insert completed)))
3206
3207
3208(defun ada-complete-use ()
3209 "Tries to complete the package name in an 'use' statement in the buffer.
3210Searches through former 'with' statements for possible completions."
3211 (interactive)
3212 (ada-complete-symbol
3213 "\\(\\<with\\s-+\\)\\([a-zA-Z0-9_.]+\\)\\(\\s-*;\\)" 2 nil)
3214 (insert ";"))
3215
3216
3217(defun ada-complete-procedure ()
3218 "Tries to complete a procedure/function name in the buffer."
3219 (interactive)
3220 (ada-complete-symbol ada-procedure-start-regexp 2 nil))
3221
3222
3223(defun ada-complete-variable ()
3224 "Tries to complete a variable name in the buffer."
3225 (interactive)
3226 (ada-complete-symbol
3227 "\\([^a-zA-Z0-9_]\\)\\([a-zA-Z0-9_]+\\)[ \t\n]+\\(:\\)" 2 nil))
3228 3124
3125 (let ((start (if (< (point) ada-search-paren-char-count-limit)
3126 1
3127 (- (point) ada-search-paren-char-count-limit)))
3128 parse-result
3129 (col nil))
3130 (setq parse-result (parse-partial-sexp start (point)))
3131 (if (nth 1 parse-result)
3132 (save-excursion
3133 (goto-char (1+ (nth 1 parse-result)))
3134 (if (save-excursion
3135 (re-search-forward "[^ \t]" nil 1)
3136 (backward-char 1)
3137 (and
3138 (not (looking-at "\n"))
3139 (setq col (current-column))))
3140 col
3141 (current-column)))
3142 nil)))
3229 3143
3230(defun ada-complete-type ()
3231 "Tries to complete a type name in the buffer."
3232 (interactive)
3233 (ada-complete-symbol "\\(type\\)[ \t\n]+\\([a-zA-Z0-9_\\.]+\\)"
3234 2
3235 '(("Integer" nil)
3236 ("Long_Integer" nil)
3237 ("Natural" nil)
3238 ("Positive" nil)
3239 ("Short_Integer" nil))))
3240 3144
3241 3145
3242;;;----------------------;;; 3146;;;----------------------;;;
@@ -3269,7 +3173,7 @@ Searches through former 'with' statements for possible completions."
3269 3173
3270 3174
3271(defun ada-indent-current-function () 3175(defun ada-indent-current-function ()
3272 "ada-mode version of the indent-line-function." 3176 "Ada Mode version of the indent-line-function."
3273 (interactive "*") 3177 (interactive "*")
3274 (let ((starting-point (point-marker))) 3178 (let ((starting-point (point-marker)))
3275 (ada-beginning-of-line) 3179 (ada-beginning-of-line)
@@ -3280,8 +3184,6 @@ Searches through former 'with' statements for possible completions."
3280 )) 3184 ))
3281 3185
3282 3186
3283
3284
3285(defun ada-tab-hard () 3187(defun ada-tab-hard ()
3286 "Indent current line to next tab stop." 3188 "Indent current line to next tab stop."
3287 (interactive) 3189 (interactive)
@@ -3300,11 +3202,6 @@ Searches through former 'with' statements for possible completions."
3300 (indent-rigidly bol eol (- 0 ada-indent)))) 3202 (indent-rigidly bol eol (- 0 ada-indent))))
3301 3203
3302 3204
3303(defun ada-tabsize (s)
3304 "changes spacing used for indentation. Reads spacing from minibuffer."
3305 (interactive "nnew indentation spacing: ")
3306 (setq ada-indent s))
3307
3308 3205
3309;;;---------------;;; 3206;;;---------------;;;
3310;;; Miscellaneous ;;; 3207;;; Miscellaneous ;;;
@@ -3389,8 +3286,9 @@ Searches through former 'with' statements for possible completions."
3389 (define-key ada-mode-map "\C-j" 'ada-indent-newline-indent) 3286 (define-key ada-mode-map "\C-j" 'ada-indent-newline-indent)
3390 (define-key ada-mode-map "\t" 'ada-tab) 3287 (define-key ada-mode-map "\t" 'ada-tab)
3391 (define-key ada-mode-map "\C-c\C-l" 'ada-indent-region) 3288 (define-key ada-mode-map "\C-c\C-l" 'ada-indent-region)
3392 ;; How do I write this for working with Lucid Emacs? 3289 (if (ada-xemacs)
3393 (define-key ada-mode-map [S-tab] 'ada-untab) 3290 (define-key ada-mode-map '(shift tab) 'ada-untab)
3291 (define-key ada-mode-map [S-tab] 'ada-untab))
3394 (define-key ada-mode-map "\C-c\C-f" 'ada-format-paramlist) 3292 (define-key ada-mode-map "\C-c\C-f" 'ada-format-paramlist)
3395 (define-key ada-mode-map "\C-c\C-p" 'ada-call-pretty-printer) 3293 (define-key ada-mode-map "\C-c\C-p" 'ada-call-pretty-printer)
3396;;; We don't want to make meta-characters case-specific. 3294;;; We don't want to make meta-characters case-specific.
@@ -3399,10 +3297,10 @@ Searches through former 'with' statements for possible completions."
3399 3297
3400 ;; Movement 3298 ;; Movement
3401;;; It isn't good to redefine these. What should be done instead? -- rms. 3299;;; It isn't good to redefine these. What should be done instead? -- rms.
3402;;; (define-key ada-mode-map "\M-e" 'ada-next-procedure) 3300;;; (define-key ada-mode-map "\M-e" 'ada-next-package)
3403;;; (define-key ada-mode-map "\M-a" 'ada-previous-procedure) 3301;;; (define-key ada-mode-map "\M-a" 'ada-previous-package)
3404 (define-key ada-mode-map "\M-\C-e" 'ada-next-package) 3302 (define-key ada-mode-map "\M-\C-e" 'ada-next-procedure)
3405 (define-key ada-mode-map "\M-\C-a" 'ada-previous-package) 3303 (define-key ada-mode-map "\M-\C-a" 'ada-previous-procedure)
3406 (define-key ada-mode-map "\C-c\C-a" 'ada-move-to-start) 3304 (define-key ada-mode-map "\C-c\C-a" 'ada-move-to-start)
3407 (define-key ada-mode-map "\C-c\C-e" 'ada-move-to-end) 3305 (define-key ada-mode-map "\C-c\C-e" 'ada-move-to-end)
3408 3306
@@ -3420,13 +3318,24 @@ Searches through former 'with' statements for possible completions."
3420 (define-key ada-mode-map "\C-c:" 'ada-uncomment-region) 3318 (define-key ada-mode-map "\C-c:" 'ada-uncomment-region)
3421 3319
3422 ;; Change basic functionality 3320 ;; Change basic functionality
3423 (mapcar (lambda (pair) 3321
3424 (substitute-key-definition (car pair) (cdr pair) 3322 ;; substitute-key-definition is not defined equally in GNU Emacs
3425 ada-mode-map global-map)) 3323 ;; and XEmacs, you cannot put in an optional 4th parameter in
3426 '((beginning-of-line . ada-beginning-of-line) 3324 ;; XEmacs. I don't think it's necessary, so I leave it out for
3427 (end-of-line . ada-end-of-line) 3325 ;; GNU Emacs as well. If you encounter any problems with the
3428 (forward-to-indentation . ada-forward-to-indentation) 3326 ;; following three functions, please tell me. RE
3429 )) 3327 (mapcar (function (lambda (pair)
3328 (substitute-key-definition (car pair) (cdr pair)
3329 ada-mode-map)))
3330 '((beginning-of-line . ada-beginning-of-line)
3331 (end-of-line . ada-end-of-line)
3332 (forward-to-indentation . ada-forward-to-indentation)
3333 ))
3334 ;; else GNU Emacs
3335 ;;(mapcar (lambda (pair)
3336 ;; (substitute-key-definition (car pair) (cdr pair)
3337 ;; ada-mode-map global-map))
3338
3430 )) 3339 ))
3431 3340
3432 3341
@@ -3434,45 +3343,51 @@ Searches through former 'with' statements for possible completions."
3434;;; define menu 'Ada' 3343;;; define menu 'Ada'
3435;;;------------------- 3344;;;-------------------
3436 3345
3346(require 'easymenu)
3347
3437(defun ada-add-ada-menu () 3348(defun ada-add-ada-menu ()
3438 "Adds the menu 'Ada' to the menu-bar in Ada Mode." 3349 "Adds the menu 'Ada' to the menu-bar in Ada Mode."
3439 (easy-menu-define ada-mode-menu ada-mode-map "Menu keymap for Ada mode." 3350 (easy-menu-define ada-mode-menu ada-mode-map "Menu keymap for Ada mode."
3440 '("Ada" 3351 '("Ada"
3441 ["next package" ada-next-package t] 3352 ["Next Package" ada-next-package t]
3442 ["previous package" ada-previous-package t] 3353 ["Previous Package" ada-previous-package t]
3443 ["next procedure" ada-next-procedure t] 3354 ["Next Procedure" ada-next-procedure t]
3444 ["previous procedure" ada-previous-procedure t] 3355 ["Previous Procedure" ada-previous-procedure t]
3445 ["goto start" ada-move-to-start t] 3356 ["Goto Start" ada-move-to-start t]
3446 ["goto end" ada-move-to-end t] 3357 ["Goto End" ada-move-to-end t]
3447 ["------------------" nil nil] 3358 ["------------------" nil nil]
3448 ["indent current line (TAB)" 3359 ["Indent Current Line (TAB)"
3449 ada-indent-current-function t] 3360 ada-indent-current-function t]
3450 ["indent lines in region" ada-indent-region t] 3361 ["Indent Lines in Region" ada-indent-region t]
3451 ["format parameter list" ada-format-paramlist t] 3362 ["Format Parameter List" ada-format-paramlist t]
3452 ["pretty print buffer" ada-call-pretty-printer t] 3363 ["Pretty Print Buffer" ada-call-pretty-printer t]
3453 ["------------" nil nil] 3364 ["------------" nil nil]
3454 ["fill comment paragraph" 3365 ["Fill Comment Paragraph"
3455 ada-fill-comment-paragraph t] 3366 ada-fill-comment-paragraph t]
3456 ["justify comment paragraph" 3367 ["Justify Comment Paragraph"
3457 ada-fill-comment-paragraph-justify t] 3368 ada-fill-comment-paragraph-justify t]
3458 ["postfix comment paragraph" 3369 ["Postfix Comment Paragraph"
3459 ada-fill-comment-paragraph-postfix t] 3370 ada-fill-comment-paragraph-postfix t]
3460 ["------------" nil nil] 3371 ["------------" nil nil]
3461 ["adjust case region" ada-adjust-case-region t] 3372 ["Adjust Case Region" ada-adjust-case-region t]
3462 ["adjust case buffer" ada-adjust-case-buffer t] 3373 ["Adjust Case Buffer" ada-adjust-case-buffer t]
3463 ["----------" nil nil] 3374 ["----------" nil nil]
3464 ["comment region" comment-region t] 3375 ["Comment Region" comment-region t]
3465 ["uncomment region" ada-uncomment-region t] 3376 ["Uncomment Region" ada-uncomment-region t]
3466 ["----------------" nil nil] 3377 ["----------------" nil nil]
3467 ["compile" compile (fboundp 'compile)] 3378 ["Compile" compile (fboundp 'compile)]
3468 ["next error" next-error (fboundp 'next-error)] 3379 ["Next Error" next-error (fboundp 'next-error)]
3469 ["---------------" nil nil] 3380 ["---------------" nil nil]
3470 ["Index" imenu (fboundp 'imenu)] 3381 ["Index" imenu (fboundp 'imenu)]
3471 ["--------------" nil nil] 3382 ["--------------" nil nil]
3472 ["other file other window" ada-ff-other-window 3383 ["Other File Other Window" ada-ff-other-window
3473 (fboundp 'ff-find-other-file)] 3384 (fboundp 'ff-find-other-file)]
3474 ["other file" ff-find-other-file 3385 ["Other File" ff-find-other-file
3475 (fboundp 'ff-find-other-file)]))) 3386 (fboundp 'ff-find-other-file)]))
3387 (if (ada-xemacs) (progn
3388 (easy-menu-add ada-mode-menu)
3389 (setq mode-popup-menu (cons "Ada Mode" ada-mode-menu)))))
3390
3476 3391
3477 3392
3478;;;------------------------------- 3393;;;-------------------------------
@@ -3510,10 +3425,8 @@ Searches through former 'with' statements for possible completions."
3510;;; support for find-file 3425;;; support for find-file
3511;;;--------------------------------------------------- 3426;;;---------------------------------------------------
3512 3427
3513(defvar ada-krunch-args "8"
3514 "*Argument of gnatk8, a string containing the max number of characters.
3515Set to a big number, if you dont use crunched filenames.")
3516 3428
3429;;;###autoload
3517(defun ada-make-filename-from-adaname (adaname) 3430(defun ada-make-filename-from-adaname (adaname)
3518 "determine the filename of a package/procedure from its own Ada name." 3431 "determine the filename of a package/procedure from its own Ada name."
3519 ;; this is done simply by calling gkrunch, when we work with GNAT. It 3432 ;; this is done simply by calling gkrunch, when we work with GNAT. It
@@ -3521,21 +3434,23 @@ Set to a big number, if you dont use crunched filenames.")
3521 (interactive "s") 3434 (interactive "s")
3522 3435
3523 ;; things that should really be done by the external process 3436 ;; things that should really be done by the external process
3437 ;; since gnat-2.0, gnatk8 can do these things. If you still use a
3438 ;; previous version, just uncomment the following lines.
3524 (let (krunch-buf) 3439 (let (krunch-buf)
3525 (setq krunch-buf (generate-new-buffer "*gkrunch*")) 3440 (setq krunch-buf (generate-new-buffer "*gkrunch*"))
3526 (save-excursion 3441 (save-excursion
3527 (set-buffer krunch-buf) 3442 (set-buffer krunch-buf)
3528 (insert (downcase adaname)) 3443; (insert (downcase adaname))
3529 (goto-char (point-min)) 3444; (goto-char (point-min))
3530 (while (search-forward "." nil t) 3445; (while (search-forward "." nil t)
3531 (replace-match "-" nil t)) 3446; (replace-match "-" nil t))
3532 (setq adaname (buffer-substring (point-min) 3447; (setq adaname (buffer-substring (point-min)
3533 (progn 3448; (progn
3534 (goto-char (point-min)) 3449; (goto-char (point-min))
3535 (end-of-line) 3450; (end-of-line)
3536 (point)))) 3451; (point))))
3537 ;; clean the buffer 3452; ;; clean the buffer
3538 (delete-region (point-min) (point-max)) 3453; (delete-region (point-min) (point-max))
3539 ;; send adaname to external process "gnatk8" 3454 ;; send adaname to external process "gnatk8"
3540 (call-process "gnatk8" nil krunch-buf nil 3455 (call-process "gnatk8" nil krunch-buf nil
3541 adaname ada-krunch-args) 3456 adaname ada-krunch-args)
@@ -3550,6 +3465,25 @@ Set to a big number, if you dont use crunched filenames.")
3550 (setq adaname adaname) ;; can I avoid this statement? 3465 (setq adaname adaname) ;; can I avoid this statement?
3551 ) 3466 )
3552 3467
3468
3469;;; functions for placing the cursor on the corresponding subprogram
3470(defun ada-which-function-are-we-in ()
3471 "Determine whether we are on a function definition/declaration and remember
3472the name of that function."
3473
3474 (setq ff-function-name nil)
3475
3476 (save-excursion
3477 (if (re-search-backward ada-procedure-start-regexp nil t)
3478 (setq ff-function-name (buffer-substring (match-beginning 0)
3479 (match-end 0)))
3480 ; we didn't find a procedure start, perhaps there is a package
3481 (if (re-search-backward ada-package-start-regexp nil t)
3482 (setq ff-function-name (buffer-substring (match-beginning 0)
3483 (match-end 0)))
3484 ))))
3485
3486
3553;;;--------------------------------------------------- 3487;;;---------------------------------------------------
3554;;; support for imenu 3488;;; support for imenu
3555;;;--------------------------------------------------- 3489;;;---------------------------------------------------
@@ -3566,21 +3500,23 @@ Set to a big number, if you dont use crunched filenames.")
3566 (or regexp ada-procedure-start-regexp) 3500 (or regexp ada-procedure-start-regexp)
3567 nil t) 3501 nil t)
3568 ;(imenu-progress-message prev-pos) 3502 ;(imenu-progress-message prev-pos)
3569 ;;(backward-up-list 1) ;; needed in Ada ????
3570 ;; do not store forward definitions 3503 ;; do not store forward definitions
3504 ;; right now we store them. We want to avoid them only in
3505 ;; package bodies, not in the specs!! ???RE???
3571 (save-match-data 3506 (save-match-data
3572 (if (not (looking-at (concat 3507; (if (not (looking-at (concat
3573 "[ \t\n]*" ; WS 3508; "[ \t\n]*" ; WS
3574 "\([^)]+\)" ; parameterlist 3509; "\([^)]+\)" ; parameterlist
3575 "\\([ \n\t]+return[ \n\t]+"; potential return 3510; "\\([ \n\t]+return[ \n\t]+"; potential return
3576 "[a-zA-Z0-9_\\.]+\\)?" 3511; "[a-zA-Z0-9_\\.]+\\)?"
3577 "[ \t]*" ; WS 3512; "[ \t]*" ; WS
3578 ";" ;; THIS is what we really look for 3513; ";" ;; THIS is what we really look for
3579 ))) 3514; )))
3580 ; (push (imenu-example--name-and-position) index-alist) 3515; ; (push (imenu-example--name-and-position) index-alist)
3581 (setq index-alist (cons (imenu-example--name-and-position) 3516 (setq index-alist (cons (imenu-example--name-and-position)
3582 index-alist)) 3517 index-alist))
3583 )) 3518; )
3519 )
3584 ;(imenu-progress-message 100) 3520 ;(imenu-progress-message 100)
3585 )) 3521 ))
3586 (nreverse index-alist))) 3522 (nreverse index-alist)))
@@ -3598,13 +3534,28 @@ Set to a big number, if you dont use crunched filenames.")
3598(defconst ada-font-lock-keywords-1 3534(defconst ada-font-lock-keywords-1
3599 (list 3535 (list
3600 ;; 3536 ;;
3601 ;; Function, package (body), pragma, procedure, task (body) plus name. 3537 ;; accept, entry, function, package (body), protected (body|type),
3602 (list (concat "\\<\\(" 3538 ;; pragma, procedure, task (body) plus name.
3603 "function\\|" 3539 (list (concat
3604 "p\\(ackage\\(\\|[ \t]+body\\)\\|r\\(agma\\|ocedure\\)\\)\\|" 3540 "\\<\\("
3605 "task\\(\\|[ \t]+body\\)" 3541 "accept\\|"
3606 "\\)\\>[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?") 3542 "entry\\|"
3607 '(1 font-lock-keyword-face) '(6 font-lock-function-name-face nil t))) 3543 "function\\|"
3544 "package\\|"
3545 "package[ \t]+body\\|"
3546 "procedure\\|"
3547 "protected\\|"
3548 "protected[ \t]+body\\|"
3549 "protected[ \t]+type\\|"
3550;; "p\\(\\(ackage\\|rotected\\)\\(\\|[ \t]+\\(body\\|type\\)\\)\
3551;;\\|r\\(agma\\|ocedure\\)\\)\\|"
3552 "task\\|"
3553 "task[ \t]+body\\|"
3554 "task[ \t]+type"
3555;; "task\\(\\|[ \t]+body\\)"
3556 "\\)\\>[ \t]*"
3557 "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
3558 '(1 font-lock-keyword-face) '(2 font-lock-function-name-face nil t)))
3608 "For consideration as a value of `ada-font-lock-keywords'. 3559 "For consideration as a value of `ada-font-lock-keywords'.
3609This does fairly subdued highlighting.") 3560This does fairly subdued highlighting.")
3610 3561
@@ -3630,11 +3581,12 @@ This does fairly subdued highlighting.")
3630 "o\\(r\\|thers\\|ut\\)\\|pr\\(ivate\\|otected\\)\\|" 3581 "o\\(r\\|thers\\|ut\\)\\|pr\\(ivate\\|otected\\)\\|"
3631 "r\\(ange\\|e\\(cord\\|m\\|names\\|queue\\|turn\\|verse\\)\\)\\|" 3582 "r\\(ange\\|e\\(cord\\|m\\|names\\|queue\\|turn\\|verse\\)\\)\\|"
3632 "se\\(lect\\|parate\\)\\|" 3583 "se\\(lect\\|parate\\)\\|"
3633 "t\\(a\\(gged\\|sk\\)\\|erminate\\|hen\\)\\|until\\|while\\|xor" 3584 "t\\(agged\\|erminate\\|hen\\)\\|until\\|" ; task removed
3585 "wh\\(ile\\|en\\)\\|xor" ; "when" added
3634 "\\)\\>") 3586 "\\)\\>")
3635 ;; 3587 ;;
3636 ;; Anything following end and not already fontified is a body name. 3588 ;; Anything following end and not already fontified is a body name.
3637 '("\\<\\(end\\)\\>[ \t]*\\(\\sw+\\)?" 3589 '("\\<\\(end\\)\\>[ \t]+\\(\\sw+\\)?"
3638 (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) 3590 (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
3639 ;; 3591 ;;
3640 ;; Variable name plus optional keywords followed by a type name. Slow. 3592 ;; Variable name plus optional keywords followed by a type name. Slow.
@@ -3661,7 +3613,7 @@ This does fairly subdued highlighting.")
3661 font-lock-type-face) nil t)) 3613 font-lock-type-face) nil t))
3662 ;; 3614 ;;
3663 ;; Keywords followed by a (comma separated list of) reference. 3615 ;; Keywords followed by a (comma separated list of) reference.
3664 (list (concat "\\<\\(goto\\|raise\\|use\\|when\\|with\\)\\>" 3616 (list (concat "\\<\\(goto\\|raise\\|use\\|with\\)\\>" ; "when" removed
3665 ; "[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?") ; RE 3617 ; "[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?") ; RE
3666 "[ \t]*\\([a-zA-Z0-9_\\.\\|, ]+\\)\\W") 3618 "[ \t]*\\([a-zA-Z0-9_\\.\\|, ]+\\)\\W")
3667 '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t)) 3619 '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t))
@@ -3690,87 +3642,103 @@ This does a lot more highlighting.")
3690 (error "No more functions/procedures"))) 3642 (error "No more functions/procedures")))
3691 3643
3692 3644
3693(defun ada-gen-treat-proc nil 3645(defun ada-gen-treat-proc (match)
3694 ;; make dummy body of a procedure/function specification. 3646 ;; make dummy body of a procedure/function specification.
3695 (goto-char (match-end 0)) 3647 ;; MATCH is a cons cell containing the start and end location of the
3696 (let ((wend (point)) 3648 ;; last search for ada-procedure-start-regexp.
3697 (wstart (progn (re-search-backward "[ ][a-zA-Z0-9_\"]+" nil t) 3649 (goto-char (car match))
3698 (+ (match-beginning 0) 1)))) ; delete leading WS 3650 (let (proc-found func-found)
3699 (copy-region-as-kill wstart wend) ; store proc name in kill-buffer 3651 (cond
3700 3652 ((or (setq proc-found (looking-at "^[ \t]*procedure"))
3701 3653 (setq func-found (looking-at "^[ \t]*function")))
3702 ;; if the next notWS char is '(' ==> parameterlist follows 3654 ;; treat it as a proc/func
3703 ;; if the next notWS char is ';' ==> no paramterlist 3655 (forward-word 2)
3704 ;; if the next notWS char is 'r' ==> paramterless function, search ';' 3656 (forward-word -1)
3705 3657 (setq procname (buffer-substring (point) (cdr match))) ; store proc name
3706 ;; goto end of regex before last (= end of procname) 3658
3707 (goto-char (match-end 0)) 3659 ;; goto end of procname
3660 (goto-char (cdr match))
3661
3662 ;; skip over parameterlist
3663 (forward-sexp)
3664 ;; if function, skip over 'return' and result type.
3665 (if func-found
3666 (progn
3667 (forward-word 1)
3668 (skip-chars-forward " \t\n")
3669 (setq functype (buffer-substring (point)
3670 (progn
3671 (skip-chars-forward
3672 "a-zA-Z0-9_\.")
3673 (point))))))
3708 ;; look for next non WS 3674 ;; look for next non WS
3709 (backward-char) 3675 (cond
3710 (re-search-forward "[ ]*.") 3676 ((looking-at "[ \t]*;")
3711 (if (char-equal (char-after (match-end 0)) ?\;) 3677 (delete-region (match-beginning 0) (match-end 0)) ;; delete the ';'
3712 (delete-char 1) ;; delete the ';' 3678 (ada-indent-newline-indent)
3679 (insert " is")
3680 (ada-indent-newline-indent)
3681 (if func-found
3682 (progn
3683 (insert "Result : ")
3684 (insert functype)
3685 (insert ";")
3686 (ada-indent-newline-indent)))
3687 (insert "begin -- ")
3688 (insert procname)
3689 (ada-indent-newline-indent)
3690 (insert "null;")
3691 (ada-indent-newline-indent)
3692 (if func-found
3693 (progn
3694 (insert "return Result;")
3695 (ada-indent-newline-indent)))
3696 (insert "end ")
3697 (insert procname)
3698 (insert ";")
3699 (ada-indent-newline-indent)
3700 )
3713 ;; else 3701 ;; else
3714 ;; find ');' or 'return <id> ;' 3702 ((looking-at "[ \t\n]*is")
3715 (re-search-forward 3703 ;; do nothing
3716 "\\()[ \t]*;\\)\\|\\(return[ \t]+[a-zA-Z0-9_]+[ \t]*;\\)" nil t)
3717 (goto-char (match-end 0))
3718 (delete-backward-char 1) ;; delete the ';'
3719 ) 3704 )
3720 3705 ((looking-at "[ \t\n]*rename")
3721 (insert " is") 3706 ;; do nothing
3722 ;; if it is a function, we should generate a return variable and a
3723 ;; return statement. Sth. like "Result : <return-type>;" and a
3724 ;; "return Result;".
3725 (ada-indent-newline-indent)
3726 (insert "begin -- ")
3727 (yank)
3728 (newline)
3729 (insert "null;")
3730 (newline)
3731 (insert "end ")
3732 (yank)
3733 (insert ";")
3734 (ada-indent-newline-indent))
3735
3736
3737(defun ada-gen-make-bodyfile (spec-filename)
3738 "Create a new buffer containing the correspondig Ada body
3739to the current specs."
3740 (interactive "b")
3741;;; (let* (
3742;;; (file-name (ada-body-filename spec-filename))
3743;;; (buf (get-buffer-create file-name)))
3744;;; (switch-to-buffer buf)
3745;;; (ada-mode)
3746 (ff-find-other-file t t)
3747;;; (if (= (buffer-size) 0)
3748;;; (make-header)
3749;;; ;; make nothing, autoinsert.el had put something in already
3750;;; )
3751 (end-of-buffer)
3752 (let ((hlen (count-lines (point-min) (point-max))))
3753 (insert-buffer spec-filename)
3754 ;; hlen lines have already been inserted automatically
3755 ) 3707 )
3708 (t
3709 (message "unknown syntax")))
3710 ))))
3711
3712
3713(defun ada-make-body ()
3714 "Create an Ada package body in the current buffer.
3715The potential old buffer contents is deleted first, then we copy the
3716spec buffer in here and modify it to make it a body.
3756 3717
3757 (if (re-search-forward ada-package-start-regexp nil t) 3718This function typically is to be hooked into `ff-file-created-hooks'."
3758 (progn (goto-char (match-end 1)) 3719 (interactive)
3759 (insert " body")) 3720 (delete-region (point-min) (point-max))
3721 (insert-buffer (car (cdr (buffer-list))))
3722 (ada-mode)
3723
3724 (let (found)
3725 (if (setq found
3726 (ada-search-ignore-string-comment ada-package-start-regexp))
3727 (progn (goto-char (cdr found))
3728 (insert " body")
3729 ;; (forward-line -1)
3730 ;;(comment-region (point-min) (point))
3731 )
3760 (error "No package")) 3732 (error "No package"))
3761 ; (comment-until-proc) 3733
3762 ; does not work correctly 3734 ;; (comment-until-proc)
3763 ; must be done by hand 3735 ;; does not work correctly
3764 3736 ;; must be done by hand
3765 (while (re-search-forward ada-procedure-start-regexp nil t) 3737
3766 (ada-gen-treat-proc)) 3738 (while (setq found
3767 3739 (ada-search-ignore-string-comment ada-procedure-start-regexp))
3768 ; don't overwrite an eventually 3740 (ada-gen-treat-proc found))))
3769 ; existing file 3741
3770; (if (file-exists-p file-name)
3771; (error "File with this name already exists!")
3772; (write-file file-name))
3773 ))
3774 3742
3775;;; provide ourself 3743;;; provide ourself
3776 3744