changeset 12039:a75524689022

(initial comments): Copyright 1995; don't speak about setup; correct history for a file that actually IS in Emacs 19.29; update list of known bugs. (all functions): inititialize all local variables explicitely to 'nil'. (ada-font-lock-keywords): initialized according to new user option `font-lock-maximum-decoration'. (ada-ident-re): new regexp for Ada identifiers. (ada-block-start-re): "record" may be preceded by one or more occurencies of "limited", "abstract", or "tagged". (ada-end-stmt-re): added "separate" body parts, "else", and "package <Id> is". (ada-subprogram-start-re): added "entry", "protected" and "package body" (ada-indent-function): handle "elsif" the same way as "if", added "separate" for no indent. (ada-get-indent-type): if "type ... is .." is followed by code on the same line, it is a broken statement. Test it. (ada-check-defun-name): check for "protected" records. (ada-goto-matching-decl-start): use of ada-ident-re. (ada-goto-matching-start): extend regexp for "protected" record. (ada-in-limit-line): renamed from in-limit-line. Don't use count-lines, but test if beginning-of-line/end-of-line puts us to bob/eob. (ada-goto-previous-nonblank-line): save a beginning-of-line statement, as we already are there. (ada-complete-type): removed. (ada-tabsize): removed. (keymap): use C-M-a and C-M-e for proc/func movement. No keybinding anymore for next/prev-package. (ada-font-lock-keywords-[1|2]): add protected records. "when" removed from 'reference'-face. (initial comments): updated CREDITS list. (ada-add-ada-menu): capitalized menu entries. Added menu statement needed for XEmacs. changed all Ada94 to Ada95. (ada-xemacs): new function, detect if we are running on XEmacs. Ada keymap definition and menus use it. (ada-create-syntax-table): corrected comments explaining use of 2nd syntax table. Added creation of ada-mode-symbol-syntax-table with '_' as word constituent. (ada-adjust-case): add test, if symbol is preceeded by a "'". If true, change case according to ada-case-attribute. (ada-which-function-are-we-in): new routine. Save name of the current function in the old buffer; we can place cursor now at the same function in the new buffer using find-file. (ada-make-body): new function. Generates body stubs if the body did not exist yet and you switch to it by find-file. (ada-gen-treat-proc): complete rewrite for ada-make-body. (ada-mode): two doc lines about the above extension. (keymap definition): remove 4th parameter in call to `substitute-key-definition' to make XEmacs happy. (ada-adjust-case-region, ada-move-to-start, ada-move-to-end, ada-indent-newline-indent, ada-format-paramlist): switch syntax tables, protect switching of syntax tables with unwind-protect. (ada-in-open-paren-p): replace user option `ada-search-paren-line-count-limit' by `ada-search-paren-char-count-limit'. (ada-case-attribute): new user option, but not yet the functionality. (ada-krunch-args): initialized to 0 exploiting the new capability of 'gnatk8' as of gnat-2.0. (ada-make-filename-from-adaname): remove downcasing and replacement of dots. This is done in external program gnatk8 (gnat-2.0). (ada-in-open-paren-p): complete rewrite for speed-up. (ada-search-ignore-string-comment): ignore # as a string terminator in all searches. (ada-add-ada-menu): use real variables instead of t for invoking 'easymenu' (require 'easymenu). (imenu-create-ada-index): we accept forward definitions again. (ada-indent-region): catch errors, simplified code.
author Karl Heuer <kwzh@gnu.org>
date Wed, 31 May 1995 19:30:32 +0000
parents 20f5e203dfe6
children e293764039a5
files lisp/progmodes/ada-mode.el
diffstat 1 files changed, 658 insertions(+), 690 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/progmodes/ada-mode.el	Tue May 30 23:32:09 1995 +0000
+++ b/lisp/progmodes/ada-mode.el	Wed May 31 19:30:32 1995 +0000
@@ -21,13 +21,13 @@
 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
 ;;; This mode is a complete rewrite of a major mode for editing Ada 83
-;;; and Ada 94 source code under Emacs-19.  It contains completely new
+;;; and Ada 95 source code under Emacs-19.  It contains completely new
 ;;; indenting code and support for code browsing (see ada-xref).
 
 
 ;;; USAGE
 ;;; =====
-;;; Emacs should enter ada-mode when you load an ada source (*.ada).
+;;; Emacs should enter ada-mode when you load an ada source (*.ad[abs]).
 ;;;
 ;;; When you have entered ada-mode, you may get more info by pressing
 ;;; C-h m. You may also get online help describing various functions by:
@@ -57,66 +57,77 @@
 ;;; to his version.
 
 
-;;; KNOWN BUGS / BUGREPORTS
-;;; =======================
+;;; KNOWN BUGS
+;;; ==========
 ;;;
 ;;; In the presence of comments and/or incorrect syntax
 ;;; ada-format-paramlist produces weird results.
 ;;;
-;;; Indentation is sometimes wrong at the very beginning of the buffer.
-;;; So please try it on different locations. If it's still wrong then
-;;; report the bug.
-;;;
-;;; At the moment the browsing functions are limited to the use of the
-;;; separate packages "find-file.el" and "ada-xref.el" (ada-xref.el is
-;;; only for GNAT users).
-;;;
-;;; indenting of some tasking constructs is not yet supported.
-;;;
-;;; `reformat-region' sometimes generates some weird indentation.
+;;; Indenting of some tasking constructs is still buggy.
+;;; -------------------
+;;;   For tagged types the problem comes from the keyword abstract:
+
+;;;   type T2 is abstract tagged record
+;;;   X : Integer;
+;;;   Y : Float;
+;;;   end record;
+;;; -------------------	
+;;; In Emacs FSF 19.28, ada-mode will correctly indent comments at the
+;;; very beginning of the buffer (_before_ any code) when I go M-; but
+;;; when I press TAB I'd expect the comments to be placed at the beginning
+;;; of the line, just as the first line of _code_ would be indented.
+
+;;; This does not happen but the comment stays put :-( I end up going 
+;;; M-; C-a M-\
+;;; -------------------
+;;; package Test is
+;;;    -- If I hit return on the "type" line it will indent the next line
+;;;    -- in another 3 space instead of heading out to the "(". If I hit
+;;;    -- tab or return it reindents the line correctly but does not initially.
+;;;    type Wait_Return is (Read_Success, Read_Timeout, Wait_Timeout,
+;;;       Nothing_To_Wait_For_In_Wait_List);
 ;;;
-;;;> I have the following suggestions for the function template: 1) I
-;;;> don't want it automatically assigning it a name for the return variable. I
-;;;> never want it to be called "Result" because that is nondescriptive. If you
-;;;> must define a variable, give me the ability to specify its name.
-;;;>
-;;;> 2) You do not provide a type for variable 'Result'. Its type is the same
-;;;> as the function's return type, which the template knows, so why force me
-;;;> to type it in?
-;;;>
-
-;;;As always, different users have different tastes.
-;;;It would be nice if one could configure such layout details separately
-;;;without patching the LISP code. Maybe the metalanguage used in ada-stmt.el
-;;;could be taken even further, providing the user with some nice syntax
-;;;for describing layout. Then my own hacks would survive the next
-;;;update of the package :-)
-
-;;;By the way, there are some more quirks:
-
-;;;1) text entered in prompt mode (*) is not converted to upper case (I have
-;;;   choosen upper case for indentifiers).
-;;;   (*) I would like to suggest the term "template code" instead of
-;;;   "pseudo code".
-
-;;; There are quite a few problems in the crossreferencing part. These
-;;; are partly due to errors in gnatf.  One of the major bugs in
-;;; ada-xref is, that we do not wait for gnatf to rebuild the xref file.
-;;; We start the job, but do not wait for finishing.
-
+;;;    -- The following line will be wrongly reindented after typing it in after
+;;;    -- the initial indent for the line was correct after type return after
+;;;    -- this line. Subsequent lines will show the same problem.
+;;; Unused:    constant Queue_ID := 0;
+;;; -------------------
+;;; -- If I do the following I get 
+;;; -- "no matching procedure/function/task/declare/package"
+;;; -- when I do return (I reverse the mappings of ^j and ^m) after "private".
+;;; package Package1 is
+;;;    package Package1_1 is
+;;;       type The_Type is private;
+;;;       private
+;;; -------------------
+;;; -- But what about this:
+;;; package G is
+;;;    type T1 is new Integer;
+;;;    type T2 is new Integer;  --< incorrect, correct if subtype
+;;;    package H is
+;;;       type T3 is new Integer;
+;;;    type                     --< Indentation is incorrect
+;;; -------------------
+
+
+
+;;; CREDITS
+;;; =======
+;;;
+;;; Many thanks to
+;;;    Philippe Warroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular,
+;;;    woodruff@stc.llnl.gov (John Woodruff)
+;;;    jj@ddci.dk (Jesper Joergensen)
+;;;    gse@ocsystems.com (Scott Evans)
+;;;    comar@LANG8.CS.NYU.EDU (Cyrille Comar)
+;;;    and others for their valuable hints.
 
 ;;; LCD Archive Entry:
 ;;; ada-mode|Rolf Ebert|<ebert@inf.enst.fr>
 ;;; |Major-mode for Ada
-;;; |$Date: 1995/04/07 00:14:59 $|$Revision: 1.5 $|
+;;; |$Date: 1995/05/24 17:02:23 $|$Revision: 2.17 $|
 
 
-(defconst ada-mode-version (substring "$Revision: 1.5 $" 11 -2)
-  "$Id: ada-mode.el,v 1.5 1995/04/07 00:14:59 kwzh Exp kwzh $
-
-Report bugs to: Rolf Ebert <ebert@inf.enst.fr>")
-
-
 ;;;--------------------
 ;;;    USER OPTIONS
 ;;;--------------------
@@ -153,9 +164,8 @@
   "*If non-nil, following lines get indented according to the innermost
 open parenthesis.")
 
-(defvar ada-search-paren-line-count-limit 5
-  "*Search that many non-blank non-comment lines for an open parenthesis.
-Values higher than about 5 horribly slow down the indenting.")
+(defvar ada-search-paren-char-count-limit 3000
+  "*Search that many characters for an open parenthesis.")
 
 
 ;; ---- other user options
@@ -166,7 +176,7 @@
 
 'indent-rigidly : always adds ada-indent blanks at the beginning of the line.
 'indent-auto    : use indentation functions in this file.
-'gei            : use David K}gedal's Generic Indentation Engine.
+'gei            : use David Kågedal's Generic Indentation Engine.
 'indent-af      : use Gary E. Barnes' ada-format.el
 'always-tab     : do indent-relative.")
 
@@ -180,8 +190,8 @@
 (defvar ada-body-suffix ".adb"
   "*Suffix of Ada body files.")
 
-(defvar ada-language-version 'ada94
-  "*Do we program in 'ada83 or 'ada94?")
+(defvar ada-language-version 'ada95
+  "*Do we program in 'ada83 or 'ada95?")
 
 (defvar ada-case-keyword 'downcase-word
   "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word
@@ -191,6 +201,10 @@
   "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word
 to adjust ada identifier case.")
 
+(defvar ada-case-attribute 'capitalize-word
+  "*downcase-word, upcase-word, ada-loose-case-word or capitalize-word
+to adjust ada identifier case.")
+
 (defvar ada-auto-case t
   "*Non-nil automatically changes casing of preceeding word while typing.
 Casing is done according to ada-case-keyword and ada-case-identifier.")
@@ -215,9 +229,9 @@
   "*This is inserted at the end of each line when filling a comment paragraph
 with ada-fill-comment-paragraph postfix.")
 
-(defvar ada-krunch-args "250"
+(defvar ada-krunch-args "0"
   "*Argument of gnatk8, a string containing the max number of characters.
-Set to a big number, if you dont use crunched filenames.")
+Set to 0, if you dont use crunched filenames.")
 
 ;;; ---- end of user configurable variables
 
@@ -232,6 +246,9 @@
 (defvar ada-mode-syntax-table nil
   "Syntax table to be used for editing Ada source code.")
 
+(defvar ada-mode-symbol-syntax-table nil
+  "Syntax table for Ada, where `_' is a word constituent.")
+
 (defconst ada-83-keywords
   "\\<\\(abort\\|abs\\|accept\\|access\\|all\\|and\\|array\\|\
 at\\|begin\\|body\\|case\\|constant\\|declare\\|delay\\|delta\\|\
@@ -243,7 +260,7 @@
 then\\|type\\|use\\|when\\|while\\|with\\|xor\\)\\>"
   "regular expression for looking at Ada83 keywords.")
 
-(defconst ada-94-keywords
+(defconst ada-95-keywords
   "\\<\\(abort\\|abs\\|abstract\\|accept\\|access\\|aliased\\|\
 all\\|and\\|array\\|at\\|begin\\|body\\|case\\|constant\\|declare\\|\
 delay\\|delta\\|digits\\|do\\|else\\|elsif\\|end\\|entry\\|\
@@ -253,9 +270,9 @@
 range\\|record\\|rem\\|renames\\|requeue\\|return\\|reverse\\|\
 select\\|separate\\|subtype\\|tagged\\|task\\|terminate\\|then\\|\
 type\\|until\\|use\\|when\\|while\\|with\\|xor\\)\\>"
-  "regular expression for looking at Ad94 keywords.")
-
-(defvar ada-keywords ada-94-keywords
+  "regular expression for looking at Ada95 keywords.")
+
+(defvar ada-keywords ada-95-keywords
   "regular expression for looking at Ada keywords.")
 
 (defvar ada-ret-binding nil
@@ -266,6 +283,10 @@
 
 ;;; ---- Regexps to find procedures/functions/packages
 
+(defconst ada-ident-re 
+  "[a-zA-Z0-9_\\.]+"
+  "Regexp matching Ada identifiers.")
+
 (defvar ada-procedure-start-regexp
   "^[ \t]*\\(procedure\\|function\\|task\\)[ \t\n]+\\([a-zA-Z0-9_\\.]+\\)"
   "Regexp used to find Ada procedures/functions.")
@@ -279,12 +300,15 @@
 
 (defvar ada-block-start-re
   "\\<\\(begin\\|select\\|declare\\|private\\|or\\|generic\\|\
-exception\\|loop\\|record\\|else\\)\\>"
+exception\\|loop\\|else\\|\
+\\(\\(limited\\|abstract\\|tagged\\)[ \t]+\\)*record\\)\\>"
   "Regexp for keywords starting ada-blocks.")
 
 (defvar ada-end-stmt-re
-  "\\(;\\|=>\\|\\<\\(begin\\|record\\|loop\\|select\\|do\\|\
-exception\\|declare\\|generic\\|private\\)\\>\\)"
+  "\\(;\\|=>\\|^[ \t]*separate[ \t]+([a-zA-Z0-9_\\.]+)\\|\
+\\<\\(begin\\|else\\|record\\|loop\\|select\\|do\\|\
+^[ \t]*package[ \ta-zA-Z0-9_\\.]+is\\|\
+^[ \t]*exception\\|declare\\|generic\\|private\\)\\>\\)"
   "Regexp of possible ends for a non-broken statement.
 'end' means that there has to start a new statement after these.")
 
@@ -293,7 +317,8 @@
   "Regexp for the start of a loop.")
 
 (defvar ada-subprog-start-re
-  "\\<\\(procedure\\|function\\|task\\|accept\\)\\>"
+  "\\<\\(procedure\\|protected\\|package[ \t]+body\\|function\\|\
+task\\|accept\\|entry\\)\\>"
   "Regexp for the start of a subprogram.")
 
 
@@ -301,17 +326,16 @@
 ;;;  functions
 ;;;-------------
 
+(defun ada-xemacs ()
+  (or (string-match "Lucid"  emacs-version)
+      (string-match "XEmacs" emacs-version)))
+
 (defun ada-create-syntax-table ()
   "Create the syntax table for ada-mode."
-  ;; This syntax table is a merge of two syntax tables I found
-  ;; in the two ada modes in the old ada.el and the old
-  ;; electric-ada.el. (jsl)
-  ;; There still remains the problem, if the underscore '_' is a word
-  ;; constituent or not. (re)
-  ;; The Emacs doc clearly states that it is a symbol, and that is what most
-  ;; on the ada-mode list prefer. (re)
-  ;; For some functions, the syntactical meaning of '_' is temporaryly
-  ;; changed to 'w'. (mh)
+  ;; There are two different syntax-tables.  The standard one declares
+  ;; `_' a symbol constituent, in the second one, it is a word
+  ;; constituent.  For some search and replacing routines we
+  ;; temporarily switch between the two.
   (setq ada-mode-syntax-table (make-syntax-table))
   (set-syntax-table  ada-mode-syntax-table)
 
@@ -353,6 +377,9 @@
   ;; define parentheses to match
   (modify-syntax-entry ?\( "()" ada-mode-syntax-table)
   (modify-syntax-entry ?\) ")(" ada-mode-syntax-table)
+
+  (setq ada-mode-symbol-syntax-table (copy-syntax-table ada-mode-syntax-table))
+  (modify-syntax-entry ?_ "w" ada-mode-symbol-syntax-table)
   )
 
 
@@ -378,8 +405,8 @@
  Fill comment paragraph and justify each line         '\\[ada-fill-comment-paragraph-justify]'
  Fill comment paragraph, justify and append postfix   '\\[ada-fill-comment-paragraph-postfix]'
 
- Next func/proc/task  '\\[ada-next-procedure]'    Previous func/proc/task '\\[ada-previous-procedure]'
- Next package         '\\[ada-next-package]'  Previous package        '\\[ada-previous-package]'
+ Next func/proc/task '\\[ada-next-procedure]'    Previous func/proc/task '\\[ada-previous-procedure]'
+ Next package        '\\[ada-next-package]'  Previous package        '\\[ada-previous-package]'
 
  Goto matching start of current 'end ...;'            '\\[ada-move-to-start]'
  Goto end of current block                            '\\[ada-move-to-end]'
@@ -398,6 +425,8 @@
                                                    or '\\[ff-mouse-find-other-file]
  Switch to other file in other window                 '\\[ada-ff-other-window]'
                                                    or '\\[ff-mouse-find-other-file-other-window]
+ If you use this function in a spec and no body is available, it gets created
+ with body stubs.
 
 If you use ada-xref.el:
  Goto declaration:          '\\[ada-point-and-xref]' on the identifier
@@ -473,8 +502,8 @@
 
   (cond ((eq ada-language-version 'ada83)
          (setq ada-keywords ada-83-keywords))
-        ((eq ada-language-version 'ada94)
-         (setq ada-keywords ada-94-keywords)))
+        ((eq ada-language-version 'ada95)
+         (setq ada-keywords ada-95-keywords)))
 
   (if ada-auto-case
       (ada-activate-keys-for-case)))
@@ -719,7 +748,8 @@
          (looking-at (concat ada-keywords "[^_]")))))
 
 (defun ada-after-char-p ()
-  ;; returns t if after ada character "'".
+  ;; returns t if after ada character "'". This is interpreted as being
+  ;; in a character constant.
   (save-excursion
     (if (> (point) 2)
         (progn
@@ -738,11 +768,17 @@
                                   (ada-in-comment-p)
                                   (ada-after-char-p))))
       (if (eq (char-syntax (char-after (1- (point)))) ?w)
-          (if (and
-               (not force-identifier) ; (MH)
-               (ada-after-keyword-p))
-              (funcall ada-case-keyword -1)
-            (funcall ada-case-identifier -1))))
+	  (if (save-excursion
+		(forward-word -1)
+		(or (= (point) (point-min))
+		    (backward-char 1))
+		(looking-at "'"))
+	      (funcall ada-case-attribute -1)
+	    (if (and
+		 (not force-identifier) ; (MH)
+		 (ada-after-keyword-p))
+		(funcall ada-case-keyword -1)
+	      (funcall ada-case-identifier -1)))))
   (forward-char 1))
 
 
@@ -818,40 +854,43 @@
         (end nil)
         (keywordp nil)
         (reldiff nil))
-    (save-excursion
-      (goto-char to)
-      ;;
-      ;; loop: look for all identifiers and keywords
-      ;;
-      (while (re-search-backward
-              "[^a-zA-Z0-9_]\\([a-zA-Z0-9_]+\\)[^a-zA-Z0-9_]"
-              from
-              t)
-        ;;
-        ;; print status message
-        ;;
-        (setq reldiff (- (point) from))
-        (message (format "adjusting case ... %5d characters left"
-                         (- (point) from)))
-        (forward-char 1)
-        (or
-         ;; do nothing if it is a string or comment
-         (ada-in-string-or-comment-p)
-         (progn
-             ;;
-             ;; get the identifier or keyword
-             ;;
-             (setq begin (point))
-             (setq keywordp (looking-at (concat ada-keywords "[^_]")))
-             (skip-chars-forward "a-zA-Z0-9_")
-           ;;
-           ;; casing according to user-option
-           ;;
-           (if keywordp
-               (funcall ada-case-keyword -1)
-             (funcall ada-case-identifier -1))
-           (goto-char begin))))
-      (message "adjusting case ... done"))))
+    (unwind-protect
+	(save-excursion
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+	  (goto-char to)
+	  ;;
+	  ;; loop: look for all identifiers and keywords
+	  ;;
+	  (while (re-search-backward
+		  "[^a-zA-Z0-9_]\\([a-zA-Z0-9_]+\\)[^a-zA-Z0-9_]"
+		  from
+		  t)
+	    ;;
+	    ;; print status message
+	    ;;
+	    (setq reldiff (- (point) from))
+	    (message (format "adjusting case ... %5d characters left"
+			     (- (point) from)))
+	    (forward-char 1)
+	    (or
+	     ;; do nothing if it is a string or comment
+	     (ada-in-string-or-comment-p)
+	     (progn
+	       ;;
+	       ;; get the identifier or keyword
+	       ;;
+	       (setq begin (point))
+	       (setq keywordp (looking-at (concat ada-keywords "[^_]")))
+	       (skip-chars-forward "a-zA-Z0-9_")
+	       ;;
+	       ;; casing according to user-option
+	       ;;
+	       (if keywordp
+		   (funcall ada-case-keyword -1)
+		 (funcall ada-case-identifier -1))
+	       (goto-char begin))))
+	  (message "adjusting case ... done"))
+      (set-syntax-table ada-mode-syntax-table))))
 
 
 ;;
@@ -860,7 +899,7 @@
 (defun ada-adjust-case-buffer ()
   "Adjusts the case of all identifiers and keywords in the whole buffer.
 ATTENTION: This function might take very long for big buffers !"
-  (interactive)
+  (interactive "*")
   (ada-adjust-case-region (point-min) (point-max)))
 
 
@@ -880,59 +919,59 @@
         (end nil)
         (delend nil)
         (paramlist nil))
-    ;;
-    ;; ATTENTION: modify sntax-table temporary !
-    ;;
-    (modify-syntax-entry ?_ "w")
-
-    ;; check if really inside parameter list
-    (or (ada-in-paramlist-p)
-        (error "not in parameter list"))
-    ;;
-    ;; find start of current parameter-list
-    ;;
-    (ada-search-ignore-string-comment
-     (concat "\\<\\("
-             "procedure\\|function\\|body\\|package\\|task\\|entry\\|accept"
-             "\\)\\>") t nil)
-    (ada-search-ignore-string-comment "(" nil nil t)
-    (backward-char 1)
-    (setq begin (point))
-
-    ;;
-    ;; find end of parameter-list
-    ;;
-    (forward-sexp 1)
-    (setq delend (point))
-    (delete-char -1)
-
-    ;;
-    ;; find end of last parameter-declaration
-    ;;
-    (ada-search-ignore-string-comment "[^ \t\n]" t nil t)
-    (forward-char 1)
-    (setq end (point))
-
-    ;;
-    ;; build a list of all elements of the parameter-list
-    ;;
-    (setq paramlist (ada-scan-paramlist (1+ begin) end))
-
-    ;;
-    ;; delete the original parameter-list
-    ;;
-    (delete-region begin (1- delend))
-
-    ;;
-    ;; insert the new parameter-list
-    ;;
-    (goto-char begin)
-    (ada-insert-paramlist paramlist)
-
-    ;;
-    ;; restore syntax-table
-    ;;
-    (modify-syntax-entry ?_ "_")))
+    (unwind-protect
+	(progn 
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+
+	  ;; check if really inside parameter list
+	  (or (ada-in-paramlist-p)
+	      (error "not in parameter list"))
+	  ;;
+	  ;; find start of current parameter-list
+	  ;;
+	  (ada-search-ignore-string-comment
+	   (concat "\\<\\("
+		   "procedure\\|function\\|body\\|package\\|task\\|entry\\|accept"
+		   "\\)\\>") t nil)
+	  (ada-search-ignore-string-comment "(" nil nil t)
+	  (backward-char 1)
+	  (setq begin (point))
+
+	  ;;
+	  ;; find end of parameter-list
+	  ;;
+	  (forward-sexp 1)
+	  (setq delend (point))
+	  (delete-char -1)
+
+	  ;;
+	  ;; find end of last parameter-declaration
+	  ;;
+	  (ada-search-ignore-string-comment "[^ \t\n]" t nil t)
+	  (forward-char 1)
+	  (setq end (point))
+
+	  ;;
+	  ;; build a list of all elements of the parameter-list
+	  ;;
+	  (setq paramlist (ada-scan-paramlist (1+ begin) end))
+
+	  ;;
+	  ;; delete the original parameter-list
+	  ;;
+	  (delete-region begin (1- delend))
+
+	  ;;
+	  ;; insert the new parameter-list
+	  ;;
+	  (goto-char begin)
+	  (ada-insert-paramlist paramlist))
+
+      ;;
+      ;; restore syntax-table
+      ;;
+      (set-syntax-table ada-mode-syntax-table)
+      )))
 
 
 (defun ada-scan-paramlist (begin end)
@@ -1246,47 +1285,46 @@
   "Moves point to the matching start of the current end ... around point."
   (interactive)
   (let ((pos (point)))
-    ;;
-    ;; ATTENTION: modify sntax-table temporary !
-    ;;
-    (modify-syntax-entry ?_ "w")
-
-    (message "searching for block start ...")
-    (save-excursion
-      ;;
-      ;; do nothing if in string or comment or not on 'end ...;'
-      ;;            or if an error occurs during processing
+    (unwind-protect
+	(progn
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+
+	  (message "searching for block start ...")
+	  (save-excursion
+	    ;;
+	    ;; do nothing if in string or comment or not on 'end ...;'
+	    ;;            or if an error occurs during processing
+	    ;;
+	    (or
+	     (ada-in-string-or-comment-p)
+	     (and (progn
+		    (or (looking-at "[ \t]*\\<end\\>")
+			(backward-word 1))
+		    (or (looking-at "[ \t]*\\<end\\>")
+			(backward-word 1))
+		    (or (looking-at "[ \t]*\\<end\\>")
+			(error "not on end ...;")))
+		  (ada-goto-matching-start 1)
+		  (setq pos (point))
+
+		  ;;
+		  ;; on 'begin' => go on, according to user option
+		  ;;
+		  ada-move-to-declaration
+		  (looking-at "\\<begin\\>")
+		  (ada-goto-matching-decl-start)
+		  (setq pos (point))))
+
+	    ) ; end of save-excursion
+
+	  ;; now really move to the found position
+	  (goto-char pos)
+	  (message "searching for block start ... done"))
+
       ;;
-      (or
-       (ada-in-string-or-comment-p)
-       (and (progn
-              (or (looking-at "[ \t]*\\<end\\>")
-                  (backward-word 1))
-              (or (looking-at "[ \t]*\\<end\\>")
-                  (backward-word 1))
-              (or (looking-at "[ \t]*\\<end\\>")
-                  (error "not on end ...;")))
-            (ada-goto-matching-start 1)
-            (setq pos (point))
-
-            ;;
-            ;; on 'begin' => go on, according to user option
-            ;;
-            ada-move-to-declaration
-            (looking-at "\\<begin\\>")
-            (ada-goto-matching-decl-start)
-            (setq pos (point))))
-
-      ) ; end of save-excursion
-
-    ;; now really move to the found position
-    (goto-char pos)
-    (message "searching for block start ... done")
-
-    ;;
-    ;; restore syntax-table
-    ;;
-    (modify-syntax-entry ?_ "_")))
+      ;; restore syntax-table
+      ;;
+      (set-syntax-table ada-mode-syntax-table))))
 
 
 (defun ada-move-to-end ()
@@ -1296,64 +1334,63 @@
   (let ((pos (point))
         (decstart nil)
         (packdecl nil))
-    ;;
-    ;; ATTENTION: modify sntax-table temporary !
-    ;;
-    (modify-syntax-entry ?_ "w")
-
-    (message "searching for block end ...")
-    (save-excursion
-
-      (forward-char 1)
-      (cond
-       ;; directly on 'begin'
-       ((save-excursion
-          (ada-goto-previous-word)
-          (looking-at "\\<begin\\>"))
-        (ada-goto-matching-end 1))
-       ;; on first line of defun declaration
-       ((save-excursion
-          (and (ada-goto-stmt-start)
-               (looking-at "\\<function\\>\\|\\<procedure\\>" )))
-        (ada-search-ignore-string-comment "\\<begin\\>"))
-       ;; on first line of task declaration
-       ((save-excursion
-          (and (ada-goto-stmt-start)
-               (looking-at "\\<task\\>" )
-               (forward-word 1)
-               (ada-search-ignore-string-comment "[^ \n\t]")
-               (not (backward-char 1))
-               (looking-at "\\<body\\>")))
-        (ada-search-ignore-string-comment "\\<begin\\>"))
-       ;; accept block start
-       ((save-excursion
-          (and (ada-goto-stmt-start)
-               (looking-at "\\<accept\\>" )))
-        (ada-goto-matching-end 0))
-       ;; package start
-       ((save-excursion
-          (and (ada-goto-matching-decl-start t)
-               (looking-at "\\<package\\>")))
-        (ada-goto-matching-end 1))
-       ;; inside a 'begin' ... 'end' block
-       ((save-excursion
-          (ada-goto-matching-decl-start t))
-        (ada-search-ignore-string-comment "\\<begin\\>"))
-       ;; (hopefully ;-) everything else
-       (t
-        (ada-goto-matching-end 1)))
-      (setq pos (point))
-
-      ) ; end of save-excursion
-
-    ;; now really move to the found position
-    (goto-char pos)
-    (message "searching for block end ... done")
-
-    ;;
-    ;; restore syntax-table
-    ;;
-    (modify-syntax-entry ?_ "_")))
+    (unwind-protect
+	(progn
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+
+	  (message "searching for block end ...")
+	  (save-excursion
+
+	    (forward-char 1)
+	    (cond
+	     ;; directly on 'begin'
+	     ((save-excursion
+		(ada-goto-previous-word)
+		(looking-at "\\<begin\\>"))
+	      (ada-goto-matching-end 1))
+	     ;; on first line of defun declaration
+	     ((save-excursion
+		(and (ada-goto-stmt-start)
+		     (looking-at "\\<function\\>\\|\\<procedure\\>" )))
+	      (ada-search-ignore-string-comment "\\<begin\\>"))
+	     ;; on first line of task declaration
+	     ((save-excursion
+		(and (ada-goto-stmt-start)
+		     (looking-at "\\<task\\>" )
+		     (forward-word 1)
+		     (ada-search-ignore-string-comment "[^ \n\t]")
+		     (not (backward-char 1))
+		     (looking-at "\\<body\\>")))
+	      (ada-search-ignore-string-comment "\\<begin\\>"))
+	     ;; accept block start
+	     ((save-excursion
+		(and (ada-goto-stmt-start)
+		     (looking-at "\\<accept\\>" )))
+	      (ada-goto-matching-end 0))
+	     ;; package start
+	     ((save-excursion
+		(and (ada-goto-matching-decl-start t)
+		     (looking-at "\\<package\\>")))
+	      (ada-goto-matching-end 1))
+	     ;; inside a 'begin' ... 'end' block
+	     ((save-excursion
+		(ada-goto-matching-decl-start t))
+	      (ada-search-ignore-string-comment "\\<begin\\>"))
+	     ;; (hopefully ;-) everything else
+	     (t
+	      (ada-goto-matching-end 1)))
+	    (setq pos (point))
+
+	    ) ; end of save-excursion
+
+	  ;; now really move to the found position
+	  (goto-char pos)
+	  (message "searching for block end ... done"))
+      
+      ;;
+      ;; restore syntax-table
+      ;;
+      (set-syntax-table ada-mode-syntax-table))))
 
 
 ;;;-----------------------------;;;
@@ -1366,19 +1403,28 @@
   "Indents the region using ada-indent-current on each line."
   (interactive "*r")
   (goto-char beg)
-  ;; catch errors while indenting
-  (condition-case err
-      (while (< (point) end)
-        (message (format "indenting ... %4d lines left"
-                         (count-lines (point) end)))
-        (ada-indent-current)
-        (forward-line 1))
-    ;; show line number where the error occured
-    (error
-     (error (format "line %d: %s"
-                    (1+ (count-lines (point-min) (point)))
-                    err) nil)))
-  (message "indenting ... done"))
+  (let ((block-done 0)
+	(lines-remaining (count-lines beg end))
+	(msg (format "indenting %4d lines %%4d lines remaining ..."
+		     (count-lines beg end)))
+        (endmark (copy-marker end)))
+    ;; catch errors while indenting
+    (condition-case err
+        (while (< (point) endmark)
+          (if (> block-done 9)
+              (progn (message (format msg lines-remaining))
+                     (setq block-done 0)))
+	  (if (looking-at "^$") nil
+	    (ada-indent-current))
+          (forward-line 1)
+	  (setq block-done (1+ block-done))
+	  (setq lines-remaining (1- lines-remaining)))
+      ;; show line number where the error occured
+      (error
+       (error (format "line %d: %s"
+                      (1+ (count-lines (point-min) (point)))
+                      err) nil)))
+    (message "indenting ... done")))
 
 
 (defun ada-indent-newline-indent ()
@@ -1392,18 +1438,17 @@
     (delete-horizontal-space)
     (setq orgpoint (point))
 
-    ;;
-    ;; ATTENTION: modify syntax-table temporary !
-    ;;
-    (modify-syntax-entry ?_ "w")
-
-    (setq column (save-excursion
-                   (funcall (ada-indent-function) orgpoint)))
-
-    ;;
-    ;; restore syntax-table
-    ;;
-    (modify-syntax-entry ?_ "_")
+    (unwind-protect
+	(progn
+	  (set-syntax-table ada-mode-symbol-syntax-table)
+
+	  (setq column (save-excursion
+			 (funcall (ada-indent-function) orgpoint))))
+
+      ;;
+      ;; restore syntax-table
+      ;;
+      (set-syntax-table ada-mode-syntax-table))
 
     (indent-to column)
 
@@ -1438,57 +1483,59 @@
 
   (interactive)
 
-  ;;
-  ;; ATTENTION: modify sntax-table temporary !
-  ;;
-  (modify-syntax-entry ?_ "w")
-
-  (let ((line-end)
-        (orgpoint (point-marker))
-        (cur-indent)
-        (prev-indent)
-        (prevline t))
+  (unwind-protect
+      (progn
+	(set-syntax-table ada-mode-symbol-syntax-table)
+
+	(let ((line-end)
+	      (orgpoint (point-marker))
+	      (cur-indent)
+	      (prev-indent)
+	      (prevline t))
+
+	  ;;
+	  ;; first step
+	  ;;
+	  (save-excursion
+	    (if (ada-goto-prev-nonblank-line t)
+		;;
+		;; we are not in the first accessible line in the buffer
+		;;
+		(progn
+		  ;;(end-of-line)
+		  ;;(forward-char 1)
+		  ;; we are already at the BOL
+		  (forward-line 1)
+		  (setq line-end (point))
+		  (setq prev-indent
+			(save-excursion
+			  (funcall (ada-indent-function) line-end))))
+	      (setq prevline nil)))
+
+	  (if prevline
+	      ;;
+	      ;; we are not in the first accessible line in the buffer
+	      ;;
+	      (progn
+		;;
+		;; second step
+		;;
+		(back-to-indentation)
+		(setq cur-indent (ada-get-current-indent prev-indent))
+		(delete-horizontal-space)
+		(indent-to cur-indent)
+
+		;;
+		;; restore position of point
+		;;
+		(goto-char orgpoint)
+		(if (< (current-column) (current-indentation))
+              (back-to-indentation))))))
 
     ;;
-    ;; first step
+    ;; restore syntax-table
     ;;
-    (save-excursion
-      (if (ada-goto-prev-nonblank-line t)
-          ;;
-          ;; we are not in the first accessible line in the buffer
-          ;;
-          (progn
-            (end-of-line)
-            (forward-char 1)
-            (setq line-end (point))
-            (setq prev-indent (save-excursion
-                                (funcall (ada-indent-function) line-end))))
-        (setq prevline nil)))
-
-    (if prevline
-        ;;
-        ;; we are not in the first accessible line in the buffer
-        ;;
-        (progn
-          ;;
-          ;; second step
-          ;;
-          (back-to-indentation)
-          (setq cur-indent (ada-get-current-indent prev-indent))
-          (delete-horizontal-space)
-          (indent-to cur-indent)
-
-          ;;
-          ;; restore position of point
-          ;;
-          (goto-char orgpoint)
-          (if (< (current-column) (current-indentation))
-              (back-to-indentation)))))
-
-  ;;
-  ;; restore syntax-table
-  ;;
-  (modify-syntax-entry ?_ "_"))
+    (set-syntax-table ada-mode-syntax-table)))
 
 
 (defun ada-get-current-indent (prev-indent)
@@ -1785,13 +1832,9 @@
            ((looking-at "\\<type\\>")
             (setq func 'ada-get-indent-type))
            ;;
-           ((looking-at "\\<if\\>")
+           ((looking-at "\\<\\(els\\)?if\\>")
             (setq func 'ada-get-indent-if))
            ;;
-           ((looking-at "\\<elsif\\>")
-            (setq func 'ada-get-indent-if)) ; maybe it needs a special
-                                            ; function sometimes ?
-           ;;
            ((looking-at "\\<case\\>")
             (setq func 'ada-get-indent-case))
            ;;
@@ -1804,6 +1847,8 @@
            ((looking-at "[a-zA-Z0-9_]+[ \t\n]*:[^=]")
             (setq func 'ada-get-indent-label))
            ;;
+	   ((looking-at "\\<separate\\>")
+	    (setq func 'ada-get-indent-nochange))
            (t
             (setq func 'ada-get-indent-noindent))))))
 
@@ -1904,7 +1949,7 @@
            ;;
            ;; a named block end
            ;;
-           ((looking-at "[a-zA-Z0-9_]+")
+           ((looking-at ada-ident-re)
             (setq defun-name (buffer-substring (match-beginning 0)
                                                (match-end 0)))
             (save-excursion
@@ -2307,10 +2352,12 @@
         (ada-search-ignore-string-comment ";" nil orgpoint))
       (current-indentation))
      ;;
-     ;; type ... is
+     ;; "type ... is", but not "type ... is ...", which is broken
      ;;
      ((save-excursion
-        (ada-search-ignore-string-comment "\\<is\\>" nil orgpoint))
+	(and
+	 (ada-search-ignore-string-comment "\\<is\\>" nil orgpoint)
+	 (not (ada-search-ignore-string-comment "[^ \t\n]" nil orgpoint))))
       (+ (current-indentation) ada-indent))
      ;;
      ;; broken statement
@@ -2475,7 +2522,7 @@
   ;;
   ;; 'accept' or 'package' ?
   ;;
-  (if (not (looking-at "\\<\\(accept\\|package\\|task\\)\\>"))
+  (if (not (looking-at "\\<\\(accept\\|package\\|task\\|protected\\)\\>"))
       (ada-goto-matching-decl-start))
   ;;
   ;; 'begin' of 'procedure'/'function'/'task' or 'declare'
@@ -2487,13 +2534,13 @@
     (if (looking-at "\\<declare\\>")
         (ada-goto-stmt-start)
       ;;
-      ;; no, => 'procedure'/'function'/'task'
+      ;; no, => 'procedure'/'function'/'task'/'protected'
       ;;
       (progn
         (forward-word 2)
         (backward-word 1)
         ;;
-        ;; skip 'body' or 'type'
+        ;; skip 'body' 'protected' 'type'
         ;;
         (if (looking-at "\\<\\(body\\|type\\)\\>")
             (forward-word 1))
@@ -2536,8 +2583,7 @@
        ;;
        ((looking-at "end")
         (ada-goto-matching-start 1 noerror)
-        (if (progn
-              (looking-at "begin"))
+        (if (looking-at "begin")
             (setq nest-count (1+ nest-count))))
        ;;
        ((looking-at "declare\\|generic")
@@ -2590,7 +2636,7 @@
           (progn
             (if (looking-at "is")
                   (ada-search-ignore-string-comment
-                   "\\<\\(procedure\\|function\\|task\\|package\\)\\>" t)
+                   ada-subprog-start-re t)
               (looking-at "declare\\|generic")))))
         (if noerror nil
           (error "no matching procedure/function/task/declare/package"))
@@ -2614,8 +2660,8 @@
             (not found)
             (ada-search-ignore-string-comment
              (concat "\\<\\("
-                     "end\\|loop\\|select\\|begin\\|case\\|"
-                     "if\\|task\\|package\\|record\\|do\\)\\>")
+                     "end\\|loop\\|select\\|begin\\|case\\|do\\|"
+                     "if\\|task\\|package\\|record\\|protected\\)\\>")
              t))
 
       ;;
@@ -2798,9 +2844,9 @@
        ((ada-in-string-p)
         (if backward
             (progn
-              (re-search-backward "\"\\|#" nil 1)
+              (re-search-backward "\"" nil 1) ; "\"\\|#" don't treat #
               (goto-char (match-beginning 0))))
-        (re-search-forward "\"\\|#" nil 1))
+        (re-search-forward "\"" nil 1))
        ;;
        ;; found character constant => ignore it
        ;;
@@ -2905,7 +2951,7 @@
 
 
 (defun ada-goto-prev-nonblank-line ( &optional ignore-comment)
-  ;; Moves point to previous non-blank line,
+  ;; Moves point to the beginning of previous non-blank line,
   ;; ignoring comments if IGNORE-COMMENT is non-nil.
   ;; It returns t if a matching line was found.
   (let ((notfound t)
@@ -2930,9 +2976,9 @@
                               (or (looking-at "[ \t]*$")
                                   (and (looking-at "[ \t]*--")
                                        ignore-comment)))
-                        (not (in-limit-line-p)))
+                        (not (ada-in-limit-line-p)))
               (forward-line -1)
-              (beginning-of-line)
+              ;;(beginning-of-line)
               (setq newpoint (point))) ; end of loop
 
             )) ; end of if
@@ -2971,7 +3017,7 @@
                               (or (looking-at "[ \t]*$")
                                   (and (looking-at "[ \t]*--")
                                        ignore-comment)))
-                        (not (in-limit-line-p)))
+                        (not (ada-in-limit-line-p)))
               (forward-line 1)
               (beginning-of-line)
               (setq newpoint (point))) ; end of loop
@@ -3017,11 +3063,11 @@
            (looking-at "\\<private\\>")))))
 
 
-(defun in-limit-line-p ()
-  ;; Returns t if point is in first or last accessible line.
-  (or
-   (>= 1 (count-lines (point-min) (point)))
-   (>= 1 (count-lines (point) (point-max)))))
+;;; make a faster??? ada-in-limit-line-p not using count-lines
+(defun ada-in-limit-line-p ()
+  ;; return t if point is in first or last accessible line.
+  (or (save-excursion (beginning-of-line) (= (point-min) (point)))
+      (save-excursion (end-of-line) (= (point-max) (point)))))
 
 
 (defun ada-in-comment-p ()
@@ -3041,7 +3087,7 @@
                (point)) (point)))
      ;; check if 'string quote' is only a character constant
      (progn
-       (re-search-backward "\"\\|#" nil t)
+       (re-search-backward "\"" nil t) ; # not a string delimiter anymore
        (not (= (char-after (1- (point))) ?'))))))
 
 
@@ -3075,168 +3121,26 @@
   ;; If point is somewhere behind an open parenthesis not yet closed,
   ;; it returns the column # of the first non-ws behind this open
   ;; parenthesis, otherwise nil."
-  (let ((nest-count 1)
-        (limit nil)
-        (found nil)
-        (pos nil)
-        (col nil)
-        (counter ada-search-paren-line-count-limit))
-
-    ;;
-    ;; get search-limit
-    ;;
-    (if ada-search-paren-line-count-limit
-        (setq limit
-              (save-excursion
-                (while (not (zerop counter))
-                  (ada-goto-prev-nonblank-line)
-                  (setq counter (1- counter)))
-                (beginning-of-line)
-                (point))))
-
-    (save-excursion
-
-      ;;
-      ;; loop until found or limit
-      ;;
-      (while (and
-              (not found)
-              (ada-search-ignore-string-comment "(\\|)" t limit t))
-        (setq nest-count
-              (if (looking-at ")")
-                  (1+ nest-count)
-                (1- nest-count)))
-        (setq found (zerop nest-count))) ; end of loop
-
-      (if found
-          ;; if found => return column of first non-ws after the parenthesis
-          (progn
-            (forward-char 1)
-            (if (save-excursion
-                  (re-search-forward "[^ \t]" nil 1)
-                  (backward-char 1)
-                  (and
-                   (not (looking-at "\n"))
-                   (setq col (current-column))))
-                col
-              (current-column)))
-        nil))))
-
-
-;;;-----------------------------;;;
-;;; Simple Completion Functions ;;;
-;;;-----------------------------;;;
-
-;; These are my first steps in Emacs-Lisp ... :-) They can be replaced
-;; by functions based on the output of the Gnatf Tool that comes with
-;; the GNAT Ada compiler. See the file ada-xref.el (MH) But you might
-;; use these functions if you don't use GNAT
-
-(defun ada-use-last-with ()
-  "Inserts the package name of the last 'with' statement after use."
-  (interactive)
-  (let ((pakname nil))
-    (save-excursion
-      (forward-word -1)
-      (if (looking-at "use")
-          ;;
-          ;; find last 'with'
-          ;;
-          (progn (re-search-backward
-                  "\\(\\<with\\s-+\\)\\([a-zA-Z0-9_.]+\\)\\(\\s-*;\\)")
-                 ;;
-                 ;; get the name of the package
-                 ;;
-                 (setq pakname (concat
-                                (buffer-substring (match-beginning 2)
-                                                  (match-end 2))
-                                ";")))
-        (setq pakname "")))
-    (insert pakname)))
-
-
-(defun ada-complete-symbol (symboldef position symalist)
-  ;; Tries to complete a symbol in the buffer.
-  ;; SYMBOLDEF is the regexp to find the definition of the desired symbol.
-  ;; POSITION is the position of the subexpression in SYMBOLDEF to match
-  ;; the symbol itself.
-  ;; SYMALIST is an alist with possibly predefined completions."
-  (let ((sofar nil)
-        (completed nil)
-        (insertpos nil))
-    (save-excursion
-      ;;
-      ;; get the part of the symbol already typed
-      ;;
-      (re-search-backward "\\([^a-zA-Z0-9_\\.]\\)\\([a-zA-Z0-9_\\.]+\\)")
-      (setq sofar (buffer-substring (match-beginning 2)
-                                    (match-end 2)))
-      ;;
-      ;; delete it
-      ;;
-      (delete-region (setq insertpos (match-beginning 2))
-                     (match-end 2))
-      ;;
-      ;; find all possible completions by searching for definitions of
-      ;; this kind of symbol
-      ;;
-      (while (re-search-backward symboldef nil t)
-        ;;
-        ;; build an alist of these possible completions
-        ;;
-        (setq symalist (cons (cons (buffer-substring (match-beginning position)
-                                                     (match-end position))
-                                   nil)
-                             symalist)))
-
-      (or
-       ;;
-       ;; symbol gets completed as far as possible
-       ;;
-       (stringp (setq completed (try-completion sofar symalist)))
-       ;;
-       ;; or is already complete
-       ;;
-       (setq completed sofar)))
-    ;;
-    ;; insert the completed symbol
-    ;;
-    (goto-char insertpos)
-    (insert completed)))
-
-
-(defun ada-complete-use ()
-  "Tries to complete the package name in an 'use' statement in the buffer.
-Searches through former 'with' statements for possible completions."
-  (interactive)
-  (ada-complete-symbol
-   "\\(\\<with\\s-+\\)\\([a-zA-Z0-9_.]+\\)\\(\\s-*;\\)" 2 nil)
-  (insert ";"))
-
-
-(defun ada-complete-procedure ()
-  "Tries to complete a procedure/function name in the buffer."
-  (interactive)
-  (ada-complete-symbol ada-procedure-start-regexp 2 nil))
-
-
-(defun ada-complete-variable ()
-  "Tries to complete a variable name in the buffer."
-  (interactive)
-  (ada-complete-symbol
-   "\\([^a-zA-Z0-9_]\\)\\([a-zA-Z0-9_]+\\)[ \t\n]+\\(:\\)" 2 nil))
-
-
-(defun ada-complete-type ()
-  "Tries to complete a type name in the buffer."
-  (interactive)
-  (ada-complete-symbol "\\(type\\)[ \t\n]+\\([a-zA-Z0-9_\\.]+\\)"
-                       2
-                       '(("Integer" nil)
-                         ("Long_Integer" nil)
-                         ("Natural" nil)
-                         ("Positive" nil)
-                         ("Short_Integer" nil))))
+
+  (let ((start (if (< (point) ada-search-paren-char-count-limit)
+                   1
+                 (- (point) ada-search-paren-char-count-limit)))
+        parse-result
+        (col nil))
+    (setq parse-result (parse-partial-sexp start (point)))
+    (if (nth 1 parse-result)
+        (save-excursion
+          (goto-char (1+ (nth 1 parse-result)))
+          (if (save-excursion
+                (re-search-forward "[^ \t]" nil 1)
+                (backward-char 1)
+                (and
+                 (not (looking-at "\n"))
+                 (setq col (current-column))))
+              col
+            (current-column)))
+      nil)))
+
 
 
 ;;;----------------------;;;
@@ -3269,7 +3173,7 @@
 
 
 (defun ada-indent-current-function ()
-  "ada-mode version of the indent-line-function."
+  "Ada Mode version of the indent-line-function."
   (interactive "*")
   (let ((starting-point (point-marker)))
     (ada-beginning-of-line)
@@ -3280,8 +3184,6 @@
     ))
 
 
-
-
 (defun ada-tab-hard ()
   "Indent current line to next tab stop."
   (interactive)
@@ -3300,11 +3202,6 @@
     (indent-rigidly bol eol  (- 0 ada-indent))))
 
 
-(defun ada-tabsize (s)
-  "changes spacing used for indentation. Reads spacing from minibuffer."
-  (interactive "nnew indentation spacing: ")
-  (setq ada-indent s))
-
 
 ;;;---------------;;;
 ;;; Miscellaneous ;;;
@@ -3389,8 +3286,9 @@
       (define-key ada-mode-map "\C-j"     'ada-indent-newline-indent)
       (define-key ada-mode-map "\t"       'ada-tab)
       (define-key ada-mode-map "\C-c\C-l" 'ada-indent-region)
-      ;; How do I write this for working with Lucid Emacs?
-      (define-key ada-mode-map [S-tab]    'ada-untab)
+      (if (ada-xemacs)
+	  (define-key ada-mode-map '(shift tab)    'ada-untab)
+	(define-key ada-mode-map [S-tab]    'ada-untab))
       (define-key ada-mode-map "\C-c\C-f" 'ada-format-paramlist)
       (define-key ada-mode-map "\C-c\C-p" 'ada-call-pretty-printer)
 ;;; We don't want to make meta-characters case-specific.
@@ -3399,10 +3297,10 @@
 
       ;; Movement
 ;;; It isn't good to redefine these.  What should be done instead?  -- rms.
-;;;   (define-key ada-mode-map "\M-e"     'ada-next-procedure)
-;;;   (define-key ada-mode-map "\M-a"     'ada-previous-procedure)
-      (define-key ada-mode-map "\M-\C-e"  'ada-next-package)
-      (define-key ada-mode-map "\M-\C-a"  'ada-previous-package)
+;;;   (define-key ada-mode-map "\M-e"     'ada-next-package)
+;;;   (define-key ada-mode-map "\M-a"     'ada-previous-package)
+      (define-key ada-mode-map "\M-\C-e"  'ada-next-procedure)
+      (define-key ada-mode-map "\M-\C-a"  'ada-previous-procedure)
       (define-key ada-mode-map "\C-c\C-a" 'ada-move-to-start)
       (define-key ada-mode-map "\C-c\C-e" 'ada-move-to-end)
 
@@ -3420,13 +3318,24 @@
       (define-key ada-mode-map "\C-c:"    'ada-uncomment-region)
 
       ;; Change basic functionality
-      (mapcar (lambda (pair)
-                (substitute-key-definition (car pair) (cdr pair)
-                                           ada-mode-map global-map))
-              '((beginning-of-line      . ada-beginning-of-line)
-                (end-of-line            . ada-end-of-line)
-                (forward-to-indentation . ada-forward-to-indentation)
-                ))
+
+      ;; substitute-key-definition is not defined equally in GNU Emacs
+      ;; and XEmacs, you cannot put in an optional 4th parameter in
+      ;; XEmacs.  I don't think it's necessary, so I leave it out for
+      ;; GNU Emacs as well.  If you encounter any problems with the
+      ;; following three functions, please tell me. RE
+      (mapcar (function (lambda (pair)
+			  (substitute-key-definition (car pair) (cdr pair)
+						     ada-mode-map)))
+	      '((beginning-of-line      . ada-beginning-of-line)
+		(end-of-line            . ada-end-of-line)
+		(forward-to-indentation . ada-forward-to-indentation)
+		))
+      ;; else GNU Emacs
+      ;;(mapcar (lambda (pair)
+      ;;             (substitute-key-definition (car pair) (cdr pair)
+      ;;				   ada-mode-map global-map))
+
       ))
 
 
@@ -3434,45 +3343,51 @@
 ;;; define menu 'Ada'
 ;;;-------------------
 
+(require 'easymenu)
+
 (defun ada-add-ada-menu ()
   "Adds the menu 'Ada' to the menu-bar in Ada Mode."
   (easy-menu-define ada-mode-menu ada-mode-map "Menu keymap for Ada mode."
                     '("Ada"
-                      ["next package" ada-next-package t]
-                      ["previous package" ada-previous-package t]
-                      ["next procedure" ada-next-procedure t]
-                      ["previous procedure" ada-previous-procedure t]
-                      ["goto start" ada-move-to-start t]
-                      ["goto end" ada-move-to-end t]
+                      ["Next Package" ada-next-package t]
+                      ["Previous Package" ada-previous-package t]
+                      ["Next Procedure" ada-next-procedure t]
+                      ["Previous Procedure" ada-previous-procedure t]
+                      ["Goto Start" ada-move-to-start t]
+                      ["Goto End" ada-move-to-end t]
                       ["------------------" nil nil]
-                      ["indent current line (TAB)"
+                      ["Indent Current Line (TAB)"
                        ada-indent-current-function t]
-                      ["indent lines in region" ada-indent-region t]
-                      ["format parameter list" ada-format-paramlist t]
-                      ["pretty print buffer" ada-call-pretty-printer t]
+                      ["Indent Lines in Region" ada-indent-region t]
+                      ["Format Parameter List" ada-format-paramlist t]
+                      ["Pretty Print Buffer" ada-call-pretty-printer t]
                       ["------------" nil nil]
-                      ["fill comment paragraph"
+                      ["Fill Comment Paragraph"
                        ada-fill-comment-paragraph t]
-                      ["justify comment paragraph"
+                      ["Justify Comment Paragraph"
                        ada-fill-comment-paragraph-justify t]
-                      ["postfix comment paragraph"
+                      ["Postfix Comment Paragraph"
                        ada-fill-comment-paragraph-postfix t]
                       ["------------" nil nil]
-                      ["adjust case region" ada-adjust-case-region t]
-                      ["adjust case buffer" ada-adjust-case-buffer t]
+                      ["Adjust Case Region" ada-adjust-case-region t]
+                      ["Adjust Case Buffer" ada-adjust-case-buffer t]
                       ["----------" nil nil]
-                      ["comment   region" comment-region t]
-                      ["uncomment region" ada-uncomment-region t]
+                      ["Comment   Region" comment-region t]
+                      ["Uncomment Region" ada-uncomment-region t]
                       ["----------------" nil nil]
-                      ["compile" compile (fboundp 'compile)]
-                      ["next error" next-error (fboundp 'next-error)]
+                      ["Compile" compile (fboundp 'compile)]
+                      ["Next Error" next-error (fboundp 'next-error)]
                       ["---------------" nil nil]
                       ["Index" imenu (fboundp 'imenu)]
                       ["--------------" nil nil]
-                      ["other file other window" ada-ff-other-window
+                      ["Other File Other Window" ada-ff-other-window
                        (fboundp 'ff-find-other-file)]
-                      ["other file" ff-find-other-file
-                       (fboundp 'ff-find-other-file)])))
+                      ["Other File" ff-find-other-file
+                       (fboundp 'ff-find-other-file)]))
+  (if (ada-xemacs) (progn
+                     (easy-menu-add ada-mode-menu)
+                     (setq mode-popup-menu (cons "Ada Mode" ada-mode-menu)))))
+
 
 
 ;;;-------------------------------
@@ -3510,10 +3425,8 @@
 ;;; support for find-file
 ;;;---------------------------------------------------
 
-(defvar ada-krunch-args "8"
-  "*Argument of gnatk8, a string containing the max number of characters.
-Set to a big number, if you dont use crunched filenames.")
-
+
+;;;###autoload
 (defun ada-make-filename-from-adaname (adaname)
   "determine the filename of a package/procedure from its own Ada name."
   ;; this is done simply by calling gkrunch, when we work with GNAT. It
@@ -3521,21 +3434,23 @@
   (interactive "s")
 
   ;; things that should really be done by the external process
+  ;; since gnat-2.0, gnatk8 can do these things. If you still use a
+  ;; previous version, just uncomment the following lines.
   (let (krunch-buf)
     (setq krunch-buf (generate-new-buffer "*gkrunch*"))
     (save-excursion
       (set-buffer krunch-buf)
-      (insert (downcase adaname))
-      (goto-char (point-min))
-      (while (search-forward "." nil t)
-        (replace-match "-" nil t))
-      (setq adaname (buffer-substring (point-min)
-                                      (progn
-                                        (goto-char (point-min))
-                                        (end-of-line)
-                                        (point))))
-      ;; clean the buffer
-      (delete-region (point-min) (point-max))
+;      (insert (downcase adaname))
+;      (goto-char (point-min))
+;      (while (search-forward "." nil t)
+;        (replace-match "-" nil t))
+;      (setq adaname (buffer-substring (point-min)
+;                                      (progn
+;                                        (goto-char (point-min))
+;                                        (end-of-line)
+;                                        (point))))
+;      ;; clean the buffer
+;      (delete-region (point-min) (point-max))
       ;; send adaname to external process "gnatk8"
       (call-process "gnatk8" nil krunch-buf nil
                     adaname ada-krunch-args)
@@ -3550,6 +3465,25 @@
   (setq adaname adaname) ;; can I avoid this statement?
   )
 
+
+;;; functions for placing the cursor on the corresponding subprogram
+(defun ada-which-function-are-we-in ()
+  "Determine whether we are on a function definition/declaration and remember
+the name of that function."
+
+  (setq ff-function-name nil)
+
+  (save-excursion
+    (if (re-search-backward ada-procedure-start-regexp nil t)
+	(setq ff-function-name (buffer-substring (match-beginning 0)
+						 (match-end 0)))
+      ; we didn't find a procedure start, perhaps there is a package
+      (if (re-search-backward ada-package-start-regexp nil t)
+	  (setq ff-function-name (buffer-substring (match-beginning 0)
+						   (match-end 0)))
+	))))
+
+
 ;;;---------------------------------------------------
 ;;; support for imenu
 ;;;---------------------------------------------------
@@ -3566,21 +3500,23 @@
              (or regexp ada-procedure-start-regexp)
              nil t)
        ;(imenu-progress-message prev-pos)
-       ;;(backward-up-list 1) ;; needed in Ada ????
        ;; do not store forward definitions
+       ;; right now we store them. We want to avoid them only in
+       ;; package bodies, not in the specs!! ???RE???
        (save-match-data
-        (if (not (looking-at (concat
-                              "[ \t\n]*" ; WS
-                              "\([^)]+\)" ; parameterlist
-                              "\\([ \n\t]+return[ \n\t]+"; potential return
-                              "[a-zA-Z0-9_\\.]+\\)?"
-                              "[ \t]*" ; WS
-                              ";"  ;; THIS is what we really look for
-                              )))
-            ; (push (imenu-example--name-and-position) index-alist)
+;        (if (not (looking-at (concat
+;                              "[ \t\n]*" ; WS
+;                              "\([^)]+\)" ; parameterlist
+;                              "\\([ \n\t]+return[ \n\t]+"; potential return
+;                              "[a-zA-Z0-9_\\.]+\\)?"
+;                              "[ \t]*" ; WS
+;                              ";"  ;; THIS is what we really look for
+;                              )))
+;            ; (push (imenu-example--name-and-position) index-alist)
             (setq index-alist (cons (imenu-example--name-and-position)
                         index-alist))
-          ))
+;          )
+	)
        ;(imenu-progress-message 100)
        ))
     (nreverse index-alist)))
@@ -3598,13 +3534,28 @@
 (defconst ada-font-lock-keywords-1
   (list
    ;;
-   ;; Function, package (body), pragma, procedure, task (body) plus name.
-   (list (concat "\\<\\("
-                 "function\\|"
-                 "p\\(ackage\\(\\|[ \t]+body\\)\\|r\\(agma\\|ocedure\\)\\)\\|"
-                 "task\\(\\|[ \t]+body\\)"
-                 "\\)\\>[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?")
-         '(1 font-lock-keyword-face) '(6 font-lock-function-name-face nil t)))
+   ;; accept, entry, function, package (body), protected (body|type),
+   ;; pragma, procedure, task (body) plus name.
+   (list (concat
+	  "\\<\\("
+	  "accept\\|"
+	  "entry\\|"
+	  "function\\|"
+	  "package\\|"
+	  "package[ \t]+body\\|"
+	  "procedure\\|"
+	  "protected\\|"
+	  "protected[ \t]+body\\|"
+	  "protected[ \t]+type\\|"
+;;	  "p\\(\\(ackage\\|rotected\\)\\(\\|[ \t]+\\(body\\|type\\)\\)\
+;;\\|r\\(agma\\|ocedure\\)\\)\\|"
+	  "task\\|"
+	  "task[ \t]+body\\|"
+	  "task[ \t]+type"
+;;	  "task\\(\\|[ \t]+body\\)"
+	  "\\)\\>[ \t]*"
+	  "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
+    '(1 font-lock-keyword-face) '(2 font-lock-function-name-face nil t)))
   "For consideration as a value of `ada-font-lock-keywords'.
 This does fairly subdued highlighting.")
 
@@ -3630,11 +3581,12 @@
             "o\\(r\\|thers\\|ut\\)\\|pr\\(ivate\\|otected\\)\\|"
             "r\\(ange\\|e\\(cord\\|m\\|names\\|queue\\|turn\\|verse\\)\\)\\|"
             "se\\(lect\\|parate\\)\\|"
-            "t\\(a\\(gged\\|sk\\)\\|erminate\\|hen\\)\\|until\\|while\\|xor"
+            "t\\(agged\\|erminate\\|hen\\)\\|until\\|" ; task removed
+	    "wh\\(ile\\|en\\)\\|xor" ; "when" added
             "\\)\\>")
     ;;
     ;; Anything following end and not already fontified is a body name.
-    '("\\<\\(end\\)\\>[ \t]*\\(\\sw+\\)?"
+    '("\\<\\(end\\)\\>[ \t]+\\(\\sw+\\)?"
       (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
     ;;
     ;; Variable name plus optional keywords followed by a type name.  Slow.
@@ -3661,7 +3613,7 @@
                 font-lock-type-face) nil t))
     ;;
     ;; Keywords followed by a (comma separated list of) reference.
-    (list (concat "\\<\\(goto\\|raise\\|use\\|when\\|with\\)\\>"
+    (list (concat "\\<\\(goto\\|raise\\|use\\|with\\)\\>" ; "when" removed
                   ; "[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?") ; RE
                   "[ \t]*\\([a-zA-Z0-9_\\.\\|, ]+\\)\\W")
           '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t))
@@ -3690,87 +3642,103 @@
     (error "No more functions/procedures")))
 
 
-(defun ada-gen-treat-proc nil
+(defun ada-gen-treat-proc (match)
   ;; make dummy body of a procedure/function specification.
-  (goto-char (match-end 0))
-  (let ((wend (point))
-        (wstart (progn (re-search-backward "[   ][a-zA-Z0-9_\"]+" nil t)
-                       (+ (match-beginning 0) 1)))) ; delete leading WS
-    (copy-region-as-kill wstart wend) ; store  proc name in kill-buffer
-
-
-    ;; if the next notWS char is '(' ==> parameterlist follows
-    ;; if the next notWS char is ';' ==> no paramterlist
-    ;; if the next notWS char is 'r' ==> paramterless function, search ';'
-
-    ;; goto end of regex before last (= end of procname)
-    (goto-char (match-end 0))
+  ;; MATCH is a cons cell containing the start and end location of the
+  ;; last search for ada-procedure-start-regexp. 
+  (goto-char (car match))
+  (let (proc-found func-found)
+    (cond
+     ((or (setq proc-found (looking-at "^[ \t]*procedure"))
+	  (setq func-found (looking-at "^[ \t]*function")))
+      ;; treat it as a proc/func
+      (forward-word 2) 
+      (forward-word -1)
+      (setq procname (buffer-substring (point) (cdr match))) ; store  proc name
+
+    ;; goto end of procname
+    (goto-char (cdr match))
+
+    ;; skip over parameterlist
+    (forward-sexp)
+    ;; if function, skip over 'return' and result type.
+    (if func-found
+	(progn
+	  (forward-word 1)
+	  (skip-chars-forward " \t\n")
+	  (setq functype (buffer-substring (point)
+					   (progn 
+					     (skip-chars-forward
+					      "a-zA-Z0-9_\.")
+					     (point))))))
     ;; look for next non WS
-    (backward-char)
-    (re-search-forward "[       ]*.")
-    (if (char-equal (char-after (match-end 0)) ?\;)
-        (delete-char 1) ;; delete the ';'
-      ;; else
-      ;; find ');' or 'return <id> ;'
-      (re-search-forward
-       "\\()[ \t]*;\\)\\|\\(return[ \t]+[a-zA-Z0-9_]+[ \t]*;\\)" nil t)
-      (goto-char (match-end 0))
-      (delete-backward-char 1) ;; delete the ';'
+    (cond
+     ((looking-at "[ \t]*;")
+      (delete-region (match-beginning 0) (match-end 0)) ;; delete the ';'
+      (ada-indent-newline-indent)
+      (insert " is")
+      (ada-indent-newline-indent)
+      (if func-found
+	  (progn
+	    (insert "Result : ")
+	    (insert functype)
+	    (insert ";")
+	    (ada-indent-newline-indent)))
+      (insert "begin -- ")
+      (insert procname)
+      (ada-indent-newline-indent)
+      (insert "null;")
+      (ada-indent-newline-indent)
+      (if func-found
+	  (progn
+	    (insert "return Result;")
+	    (ada-indent-newline-indent)))
+      (insert "end ")
+      (insert procname)
+      (insert ";")
+      (ada-indent-newline-indent)	
       )
-
-    (insert " is")
-    ;; if it is a function, we should generate a return variable and a
-    ;; return statement. Sth. like "Result : <return-type>;" and a
-    ;; "return Result;".
-    (ada-indent-newline-indent)
-    (insert "begin -- ")
-    (yank)
-    (newline)
-    (insert "null;")
-    (newline)
-    (insert "end ")
-    (yank)
-    (insert ";")
-    (ada-indent-newline-indent))
-
-
-(defun ada-gen-make-bodyfile (spec-filename)
-  "Create a new buffer containing the correspondig Ada body
-to the current specs."
-  (interactive "b")
-;;;  (let* (
-;;;      (file-name (ada-body-filename spec-filename))
-;;;      (buf (get-buffer-create file-name)))
-;;;    (switch-to-buffer buf)
-;;;    (ada-mode)
-  (ff-find-other-file t t)
-;;;  (if (= (buffer-size) 0)
-;;;      (make-header)
-;;;    ;; make nothing, autoinsert.el had put something in already
-;;;    )
-    (end-of-buffer)
-    (let ((hlen (count-lines (point-min) (point-max))))
-      (insert-buffer spec-filename)
-      ;; hlen lines have already been inserted automatically
+      ;; else
+     ((looking-at "[ \t\n]*is")
+      ;; do nothing
+      )
+     ((looking-at "[ \t\n]*rename")
+      ;; do nothing
       )
-
-    (if (re-search-forward ada-package-start-regexp nil t)
-        (progn (goto-char (match-end 1))
-               (insert " body"))
+     (t
+      (message "unknown syntax")))
+    ))))
+
+
+(defun ada-make-body ()
+  "Create an Ada package body in the current buffer.
+The potential old buffer contents is deleted first, then we copy the
+spec buffer in here and modify it to make it a body.
+
+This function typically is to be hooked into `ff-file-created-hooks'."
+  (interactive)
+  (delete-region (point-min) (point-max))
+  (insert-buffer (car (cdr (buffer-list))))
+  (ada-mode)
+
+  (let (found)
+    (if (setq found 
+	      (ada-search-ignore-string-comment ada-package-start-regexp))
+	(progn (goto-char (cdr found))
+	       (insert " body")
+	       ;; (forward-line -1)
+	       ;;(comment-region (point-min) (point))
+	       )
       (error "No package"))
-                                        ; (comment-until-proc)
-                                        ; does not work correctly
-                                        ; must be done by hand
-
-    (while (re-search-forward ada-procedure-start-regexp nil t)
-      (ada-gen-treat-proc))
-
-                                        ; don't overwrite an eventually
-                                        ; existing file
-;    (if (file-exists-p file-name)
-;        (error "File with this name already exists!")
-;      (write-file file-name))
-    ))
+    
+    ;; (comment-until-proc)
+    ;;   does not work correctly
+    ;;   must be done by hand
+    
+    (while (setq found
+		 (ada-search-ignore-string-comment ada-procedure-start-regexp))
+      (ada-gen-treat-proc found))))
+
 
 ;;; provide ourself