]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/ada-mode.el
Merge multi-tty branch
[gnu-emacs] / lisp / progmodes / ada-mode.el
index 7015a24ac016a6aa6e3eb32976936165349cb3cd..478a07bc3b6bbf8ca666e69bdc217d9c4432f6f3 100644 (file)
@@ -1,7 +1,7 @@
 ;;; ada-mode.el --- major-mode for editing Ada sources
 
 ;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;               2005, 2006  Free Software Foundation, Inc.
+;;               2005, 2006, 2007  Free Software Foundation, Inc.
 
 ;; Author: Rolf Ebert      <ebert@inf.enst.fr>
 ;;      Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de>
@@ -13,7 +13,7 @@
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
-;;; This mode is a major mode for editing Ada83 and Ada95 source code.
-;;; This is a major rewrite of the file packaged with Emacs-20.  The
-;;; ada-mode is composed of four Lisp files, ada-mode.el, ada-xref.el,
-;;; ada-prj.el and ada-stmt.el. Only this file (ada-mode.el) is
-;;; completely independent from the GNU Ada compiler Gnat, distributed
-;;; by Ada Core Technologies. All the other files rely heavily on
-;;; features provided only by Gnat.
-;;;
-;;; Note: this mode will not work with Emacs 19. If you are on a VMS
-;;; system, where the latest version of Emacs is 19.28, you will need
-;;; another file, called ada-vms.el, that provides some required
-;;; functions.
+;; This mode is a major mode for editing Ada code.  This is a major
+;; rewrite of the file packaged with Emacs-20.  The Ada mode is
+;; composed of four Lisp files: ada-mode.el, ada-xref.el, ada-prj.el
+;; and ada-stmt.el.  Only this file (ada-mode.el) is completely
+;; independent from the GNU Ada compiler GNAT, distributed by Ada
+;; Core Technologies.  All the other files rely heavily on features
+;; provided only by GNAT.
+;;
+;; Note: this mode will not work with Emacs 19. If you are on a VMS
+;; system, where the latest version of Emacs is 19.28, you will need
+;; another file, called ada-vms.el, that provides some required
+;; functions.
 
 ;;; Usage:
-;;; Emacs should enter Ada mode automatically when you load an Ada file.
-;;; By default, the valid extensions for Ada files are .ads, .adb or .ada
-;;; If the ada-mode does not start automatically, then simply type the
-;;; following command :
-;;;     M-x ada-mode
-;;;
-;;; By default, ada-mode is configured to take full advantage of the GNAT
-;;; compiler (the menus will include the cross-referencing features,...).
-;;; If you are using another compiler, you might want to set the following
-;;; variable in your .emacs (Note: do not set this in the ada-mode-hook, it
-;;; won't work) :
-;;;    (setq ada-which-compiler 'generic)
-;;;
-;;; This mode requires find-file.el to be present on your system.
+;; Emacs should enter Ada mode automatically when you load an Ada file.
+;; By default, the valid extensions for Ada files are .ads, .adb or .ada
+;; If the ada-mode does not start automatically, then simply type the
+;; following command :
+;;     M-x ada-mode
+;;
+;; By default, ada-mode is configured to take full advantage of the GNAT
+;; compiler (the menus will include the cross-referencing features,...).
+;; If you are using another compiler, you might want to set the following
+;; variable in your .emacs (Note: do not set this in the ada-mode-hook, it
+;; won't work) :
+;;    (setq ada-which-compiler 'generic)
+;;
+;; This mode requires find-file.el to be present on your system.
 
 ;;; History:
-;;; The first Ada mode for GNU Emacs was written by V. Broman in
-;;; 1985. He based his work on the already existing Modula-2 mode.
-;;; This was distributed as ada.el in versions of Emacs prior to 19.29.
-;;;
-;;; Lynn Slater wrote an extensive Ada mode in 1989. It consisted of
-;;; several files with support for dired commands and other nice
-;;; things. It is currently available from the PAL
-;;; (wuarchive.wustl.edu:/languages/ada) as ada-mode-1.06a.tar.Z.
-;;;
-;;; The probably very first Ada mode (called electric-ada.el) was
-;;; written by Steven D. Litvintchouk and Steven M. Rosen for the
-;;; Gosling Emacs. L. Slater based his development on ada.el and
-;;; electric-ada.el.
-;;;
-;;; A complete rewrite by M. Heritsch and R. Ebert has been done.
-;;; Some ideas from the Ada mode mailing list have been
-;;; added.  Some of the functionality of L. Slater's mode has not
-;;; (yet) been recoded in this new mode.  Perhaps you prefer sticking
-;;; to his version.
-;;;
-;;; A complete rewrite for Emacs-20 / Gnat-3.11 has been done by Ada Core
-;;; Technologies.
+;; The first Ada mode for GNU Emacs was written by V. Broman in
+;; 1985. He based his work on the already existing Modula-2 mode.
+;; This was distributed as ada.el in versions of Emacs prior to 19.29.
+;;
+;; Lynn Slater wrote an extensive Ada mode in 1989. It consisted of
+;; several files with support for dired commands and other nice
+;; things. It is currently available from the PAL
+;; (wuarchive.wustl.edu:/languages/ada) as ada-mode-1.06a.tar.Z.
+;;
+;; The probably very first Ada mode (called electric-ada.el) was
+;; written by Steven D. Litvintchouk and Steven M. Rosen for the
+;; Gosling Emacs. L. Slater based his development on ada.el and
+;; electric-ada.el.
+;;
+;; A complete rewrite by M. Heritsch and R. Ebert has been done.
+;; Some ideas from the Ada mode mailing list have been
+;; added.  Some of the functionality of L. Slater's mode has not
+;; (yet) been recoded in this new mode.  Perhaps you prefer sticking
+;; to his version.
+;;
+;; A complete rewrite for Emacs-20 / GNAT-3.11 has been done by Ada Core
+;; Technologies.
 
 ;;; Credits:
-;;;   Many thanks to John McCabe <john@assen.demon.co.uk> for sending so
-;;;     many patches included in this package.
-;;;   Christian Egli <Christian.Egli@hcsd.hac.com>:
-;;;     ada-imenu-generic-expression
-;;;   Many thanks also to the following persons that have contributed
-;;;   to the ada-mode
-;;;     Philippe Waroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular,
-;;;     woodruff@stc.llnl.gov (John Woodruff)
-;;;     jj@ddci.dk (Jesper Joergensen)
-;;;     gse@ocsystems.com (Scott Evans)
-;;;     comar@gnat.com (Cyrille Comar)
-;;;     stephen.leake@gsfc.nasa.gov (Stephen Leake)
-;;;     robin-reply@reagans.org
-;;;    and others for their valuable hints.
+;;   Many thanks to John McCabe <john@assen.demon.co.uk> for sending so
+;;     many patches included in this package.
+;;   Christian Egli <Christian.Egli@hcsd.hac.com>:
+;;     ada-imenu-generic-expression
+;;   Many thanks also to the following persons that have contributed
+;;   to the ada-mode
+;;     Philippe Waroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular,
+;;     woodruff@stc.llnl.gov (John Woodruff)
+;;     jj@ddci.dk (Jesper Joergensen)
+;;     gse@ocsystems.com (Scott Evans)
+;;     comar@gnat.com (Cyrille Comar)
+;;     stephen.leake@gsfc.nasa.gov (Stephen Leake)
+;;     robin-reply@reagans.org
+;;    and others for their valuable hints.
 
 ;;; Code:
-;;; Note: Every function in this package is compiler-independent.
-;;; The names start with  ada-
-;;; The variables that the user can edit can all be modified through
-;;;   the customize mode. They are sorted in alphabetical order in this
-;;;   file.
-
-;;; Supported packages.
-;;; This package supports a number of other Emacs modes. These other modes
-;;; should be loaded before the ada-mode, which will then setup some variables
-;;; to improve the support for Ada code.
-;;; Here is the list of these modes:
-;;;   `which-function-mode': Display the name of the subprogram the cursor is
-;;;      in in the mode line.
-;;;   `outline-mode': Provides the capability to collapse or expand the code
-;;;      for specific language constructs, for instance if you want to hide the
-;;;      code corresponding to a subprogram
-;;;   `align': This mode is now provided with Emacs 21, but can also be
-;;;      installed manually for older versions of Emacs. It provides the
-;;;      capability to automatically realign the selected region (for instance
-;;;      all ':=', ':' and '--' will be aligned on top of each other.
-;;;   `imenu': Provides a menu with the list of entities defined in the current
-;;;      buffer, and an easy way to jump to any of them
-;;;   `speedbar': Provides a separate file browser, and the capability for each
-;;;      file to see the list of entities defined in it and to jump to them
-;;;      easily
-;;;   `abbrev-mode': Provides the capability to define abbreviations, which
-;;;      are automatically expanded when you type them. See the Emacs manual.
-
-(eval-when-compile
-  (require 'ispell nil t)
-  (require 'find-file nil t)
-  (require 'align nil t)
-  (require 'which-func nil t)
-  (require 'compile nil t))
+;; Note: Every function in this package is compiler-independent.
+;; The names start with  ada-
+;; The variables that the user can edit can all be modified through
+;;   the customize mode. They are sorted in alphabetical order in this
+;;   file.
+
+;; Supported packages.
+;; This package supports a number of other Emacs modes. These other modes
+;; should be loaded before the ada-mode, which will then setup some variables
+;; to improve the support for Ada code.
+;; Here is the list of these modes:
+;;   `which-function-mode': Display the name of the subprogram the cursor is
+;;      in in the mode line.
+;;   `outline-mode': Provides the capability to collapse or expand the code
+;;      for specific language constructs, for instance if you want to hide the
+;;      code corresponding to a subprogram
+;;   `align': This mode is now provided with Emacs 21, but can also be
+;;      installed manually for older versions of Emacs. It provides the
+;;      capability to automatically realign the selected region (for instance
+;;      all ':=', ':' and '--' will be aligned on top of each other.
+;;   `imenu': Provides a menu with the list of entities defined in the current
+;;      buffer, and an easy way to jump to any of them
+;;   `speedbar': Provides a separate file browser, and the capability for each
+;;      file to see the list of entities defined in it and to jump to them
+;;      easily
+;;   `abbrev-mode': Provides the capability to define abbreviations, which
+;;      are automatically expanded when you type them. See the Emacs manual.
+
+(require 'find-file nil t)
+(require 'align nil t)
+(require 'which-func nil t)
+(require 'compile nil t)
 
 (defvar compile-auto-highlight)
+(defvar ispell-check-comments)
 (defvar skeleton-further-elements)
 
-;; this function is needed at compile time
-(eval-and-compile
-  (defun ada-check-emacs-version (major minor &optional is-xemacs)
-    "Return t if Emacs's version is greater or equal to MAJOR.MINOR.
-If IS-XEMACS is non-nil, check for XEmacs instead of Emacs."
-    (let ((xemacs-running (or (string-match "Lucid"  emacs-version)
-                             (string-match "XEmacs" emacs-version))))
-      (and (or (and is-xemacs xemacs-running)
-              (not (or is-xemacs xemacs-running)))
-          (or (> emacs-major-version major)
-              (and (= emacs-major-version major)
-                   (>= emacs-minor-version minor)))))))
-
-
-;;  This call should not be made in the release that is done for the
-;;  official Emacs, since it does nothing useful for the latest version
-;;(if (not (ada-check-emacs-version 21 1))
-;;    (require 'ada-support))
-
 (defun ada-mode-version ()
   "Return Ada mode version."
   (interactive)
-  (let ((version-string "3.5"))
+  (let ((version-string "3.7"))
     (if (interactive-p)
        (message version-string)
       version-string)))
@@ -366,8 +346,8 @@ This is also used for <<..>> labels"
   :type 'integer :group 'ada)
 
 (defcustom ada-language-version 'ada95
-  "*Do we program in `ada83' or `ada95'?"
-  :type '(choice (const ada83) (const ada95)) :group 'ada)
+  "*Ada language version; one of `ada83', `ada95', `ada2005'."
+  :type '(choice (const ada83) (const ada95) (const ada2005)) :group 'ada)
 
 (defcustom ada-move-to-declaration nil
   "*Non-nil means `ada-move-to-start' moves to the subprogram declaration, not to 'begin'."
@@ -445,7 +425,7 @@ An example is:
   "*Name of the compiler to use.
 This will determine what features are made available through the Ada mode.
 The possible choices are:
-`gnat': Use Ada Core Technologies' Gnat compiler.  Add some cross-referencing
+`gnat': Use Ada Core Technologies' GNAT compiler.  Add some cross-referencing
     features.
 `generic': Use a generic compiler."
   :type '(choice (const gnat)
@@ -480,6 +460,7 @@ The extensions should include a `.' if needed.")
   "Syntax table for Ada, where `_' is a word constituent.")
 
 (eval-when-compile
+  ;; These values are used in eval-when-compile expressions.
   (defconst ada-83-string-keywords
     '("abort" "abs" "accept" "access" "all" "and" "array" "at" "begin"
       "body" "case" "constant" "declare" "delay" "delta" "digits" "do"
@@ -489,8 +470,18 @@ The extensions should include a `.' if needed.")
       "procedure" "raise" "range" "record" "rem" "renames" "return"
       "reverse" "select" "separate" "subtype" "task" "terminate" "then"
       "type" "use" "when" "while" "with" "xor")
-    "List of Ada keywords.
-This variable is used to define `ada-83-keywords' and `ada-95-keywords'."))
+    "List of Ada 83 keywords.
+Used to define `ada-*-keywords'.")
+
+  (defconst ada-95-string-keywords
+    '("abstract" "aliased" "protected" "requeue" "tagged" "until")
+    "List of keywords new in Ada 95.
+Used to define `ada-*-keywords'.")
+
+  (defconst ada-2005-string-keywords
+    '("interface" "overriding" "synchronized")
+    "List of keywords new in Ada 2005.
+Used to define `ada-*-keywords.'"))
 
 (defvar ada-ret-binding nil
   "Variable to save key binding of RET when casing is activated.")
@@ -541,24 +532,25 @@ See `align-mode-alist' for more information.")
 This variable defines several rules to use to align different lines.")
 
 (defconst ada-align-region-separate
-  (concat
-   "^\\s-*\\($\\|\\("
-   "begin\\|"
-   "declare\\|"
-   "else\\|"
-   "end\\|"
-   "exception\\|"
-   "for\\|"
-   "function\\|"
-   "generic\\|"
-   "if\\|"
-   "is\\|"
-   "procedure\\|"
-   "record\\|"
-   "return\\|"
-   "type\\|"
-   "when"
-   "\\)\\>\\)")
+  (eval-when-compile
+    (concat
+     "^\\s-*\\($\\|\\("
+     "begin\\|"
+     "declare\\|"
+     "else\\|"
+     "end\\|"
+     "exception\\|"
+     "for\\|"
+     "function\\|"
+     "generic\\|"
+     "if\\|"
+     "is\\|"
+     "procedure\\|"
+     "record\\|"
+     "return\\|"
+     "type\\|"
+     "when"
+     "\\)\\>\\)"))
   "See the variable `align-region-separate' for more information.")
 
 ;;; ---- Below are the regexp used in this package for parsing
@@ -566,29 +558,38 @@ This variable defines several rules to use to align different lines.")
 (defconst ada-83-keywords
   (eval-when-compile
     (concat "\\<" (regexp-opt ada-83-string-keywords t) "\\>"))
-  "Regular expression for looking at Ada83 keywords.")
+  "Regular expression matching Ada83 keywords.")
 
 (defconst ada-95-keywords
   (eval-when-compile
     (concat "\\<" (regexp-opt
                   (append
-                   '("abstract" "aliased" "protected" "requeue"
-                     "tagged" "until")
+                   ada-95-string-keywords
                    ada-83-string-keywords) t) "\\>"))
-  "Regular expression for looking at Ada95 keywords.")
+  "Regular expression matching Ada95 keywords.")
 
-(defvar ada-keywords ada-95-keywords
-  "Regular expression for looking at Ada keywords.")
+(defconst ada-2005-keywords
+  (eval-when-compile
+    (concat "\\<" (regexp-opt
+                  (append
+                   ada-2005-string-keywords
+                   ada-83-string-keywords
+                   ada-95-string-keywords) t) "\\>"))
+  "Regular expression matching Ada2005 keywords.")
+
+(defvar ada-keywords ada-2005-keywords
+  "Regular expression matching Ada keywords.")
+;; FIXME: make this customizable
 
 (defconst ada-ident-re
   "\\(\\sw\\|[_.]\\)+"
   "Regexp matching Ada (qualified) identifiers.")
 
-;;  "with" needs to be included in the regexp, so that we can insert new lines
-;;  after the declaration of the parameter for a generic.
+;;  "with" needs to be included in the regexp, to match generic subprogram parameters
+;;  Similarly, we put '[not] overriding' on the same line with 'procedure' etc.
 (defvar ada-procedure-start-regexp
   (concat
-   "^[ \t]*\\(with[ \t]+\\)?\\(procedure\\|function\\|task\\)[ \t\n]+"
+   "^[ \t]*\\(with[ \t]+\\)?\\(\\(not[ \t]+\\)?overriding[ \t]+\\)?\\(procedure\\|function\\|task\\)[ \t\n]+"
 
    ;;  subprogram name: operator ("[+/=*]")
    "\\("
@@ -598,11 +599,21 @@ This variable defines several rules to use to align different lines.")
    "\\|"
    "\\(\\(\\sw\\|[_.]\\)+\\)"
    "\\)")
-  "Regexp used to find Ada procedures/functions.")
+  "Regexp matching Ada subprogram start.
+The actual start is at (match-beginning 4).  The name is in (match-string 5).")
+
+(defconst ada-name-regexp
+  "\\([a-zA-Z][a-zA-Z0-9_.']*[a-zA-Z0-9]\\)"
+  "Regexp matching a fully qualified name (including attribute).")
+
+(defconst ada-package-start-regexp
+  (concat "^[ \t]*\\(private[ \t]+\\)?\\(package\\)[ \t\n]+\\(body[ \t]*\\)?" ada-name-regexp)
+  "Regexp matching start of package.
+The package name is in (match-string 4).")
 
-(defvar ada-package-start-regexp
-  "^[ \t]*\\(package\\)"
-  "Regexp used to find Ada packages.")
+(defconst ada-compile-goto-error-file-linenr-re
+  "\\([-_.a-zA-Z0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?"
+  "Regexp matching filename:linenr[:column].")
 
 
 ;;; ---- regexps for indentation functions
@@ -635,8 +646,8 @@ A new statement starts after these.")
   (eval-when-compile
     (concat "\\<"
            (regexp-opt
-            '("end" "loop" "select" "begin" "case" "do"
-              "if" "task" "package" "record" "protected") t)
+            '("end" "loop" "select" "begin" "case" "do" "declare"
+              "if" "task" "package" "procedure" "function" "record" "protected") t)
            "\\>"))
   "Regexp used in `ada-goto-matching-start'.")
 
@@ -753,40 +764,42 @@ the 4 file locations can be clicked on and jumped to."
   (skip-chars-backward "-a-zA-Z0-9_:./\\")
   (cond
    ;;  special case: looking at a filename:line not at the beginning of a line
+   ;;  or a simple line reference "at line ..."
    ((and (not (bolp))
-        (looking-at
-         "\\([-_.a-zA-Z0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?"))
-    (let ((line (match-string 2))
-         file
+        (or (looking-at ada-compile-goto-error-file-linenr-re)
+            (and
+             (save-excursion
+               (beginning-of-line)
+               (looking-at ada-compile-goto-error-file-linenr-re))
+             (save-excursion
+               (if (looking-at "\\([0-9]+\\)") (backward-word 1))
+               (looking-at "line \\([0-9]+\\)"))))
+            )
+    (let ((line (if (match-beginning 2) (match-string 2) (match-string 1)))
+         (file (if (match-beginning 2) (match-string 1)
+                 (save-excursion (beginning-of-line)
+                                 (looking-at ada-compile-goto-error-file-linenr-re)
+                                 (match-string 1))))
          (error-pos (point-marker))
          source)
+
+      ;; set source marker
       (save-excursion
-       (save-restriction
-         (widen)
-         ;;  Use funcall so as to prevent byte-compiler warnings
-         ;;  `ada-find-file' is not defined if ada-xref wasn't loaded. But
-         ;;  if we can find it, we should use it instead of
-         ;;  `compilation-find-file', since the latter doesn't know anything
-         ;;  about source path.
-
-         (if (functionp 'ada-find-file)
-             (setq file (funcall (symbol-function 'ada-find-file)
-                                 (match-string 1)))
-           (setq file (funcall (symbol-function 'compilation-find-file)
-                               (point-marker) (match-string 1)
-                               "./")))
-         (set-buffer file)
-
-         (if (stringp line)
-             (goto-line (string-to-number line)))
-         (setq source (point-marker))))
-      (funcall (symbol-function 'compilation-goto-locus)
-              (cons source error-pos))
+        (compilation-find-file (point-marker) (match-string 1) "./")
+        (set-buffer file)
+
+        (if (stringp line)
+            (goto-line (string-to-number line)))
+
+        (setq source (point-marker)))
+
+      (compilation-goto-locus error-pos source nil)
+
       ))
 
    ;; otherwise, default behavior
    (t
-    (funcall (symbol-function 'compile-goto-error)))
+    (compile-goto-error))
    )
   (recenter))
 
@@ -804,13 +817,12 @@ the 4 file locations can be clicked on and jumped to."
 ;; Thus their syntax property is changed automatically, and we can still use
 ;; the standard Emacs functions for sexp (see `ada-in-string-p')
 ;;
-;; On Emacs, this is done through the `syntax-table' text property. The
-;; modification is done automatically each time the user as typed a new
-;; character. This is already done in `font-lock-mode' (in
-;; `font-lock-syntactic-keywords', so we take advantage of the existing
-;; mechanism. If font-lock-mode is not activated, we do it by hand in
-;; `ada-after-change-function', thanks to `ada-deactivate-properties' and
-;; `ada-initialize-properties'.
+;; On Emacs, this is done through the `syntax-table' text property.  The
+;; corresponding action is applied automatically each time the buffer
+;; changes.  If `font-lock-mode' is enabled (the default) the action is
+;; set up by `font-lock-syntactic-keywords'.  Otherwise, we do it
+;; manually in `ada-after-change-function'.  The proper method is
+;; installed by `ada-handle-syntax-table-properties'.
 ;;
 ;; on XEmacs, the `syntax-table' property does not exist and we have to use a
 ;; slow advice to `parse-partial-sexp' to do the same thing.
@@ -827,7 +839,6 @@ The standard table declares `_' as a symbol constituent, the second one
 declares it as a word constituent."
   (interactive)
   (setq ada-mode-syntax-table (make-syntax-table))
-  (set-syntax-table  ada-mode-syntax-table)
 
   ;; define string brackets (`%' is alternative string bracket, but
   ;; almost never used as such and throws font-lock and indentation
@@ -911,50 +922,59 @@ declares it as a word constituent."
            (insert (caddar change))
            (setq change (cdr change)))))))
 
-(defun ada-deactivate-properties ()
-  "Deactivate Ada mode's properties handling.
-This would be a duplicate of font-lock if both are used at the same time."
-  (remove-hook 'after-change-functions 'ada-after-change-function t))
-
-(defun ada-initialize-properties ()
-  "Initialize some special text properties in the whole buffer.
-In particular, character constants are said to be strings, #...# are treated
-as numbers instead of gnatprep comments."
-  (save-excursion
-    (save-restriction
-      (widen)
-      (goto-char (point-min))
-      (while (re-search-forward "'.'" nil t)
-       (add-text-properties (match-beginning 0) (match-end 0)
-                            '(syntax-table ("'" . ?\"))))
-      (goto-char (point-min))
-      (while (re-search-forward "^[ \t]*#" nil t)
-       (add-text-properties (match-beginning 0) (match-end 0)
-                            '(syntax-table (11 . 10))))
-      (set-buffer-modified-p nil)
-
-      ;;  Setting this only if font-lock is not set won't work
-      ;;  if the user activates or deactivates font-lock-mode,
-      ;;  but will make things faster most of the time
-      (add-hook 'after-change-functions 'ada-after-change-function nil t)
-      )))
+(defun ada-set-syntax-table-properties ()
+  "Assign `syntax-table' properties in accessible part of buffer.
+In particular, character constants are said to be strings, #...#
+are treated as numbers instead of gnatprep comments."
+  (let ((modified (buffer-modified-p))
+       (buffer-undo-list t)
+       (inhibit-read-only t)
+       (inhibit-point-motion-hooks t)
+       (inhibit-modification-hooks t))
+    (remove-text-properties (point-min) (point-max) '(syntax-table nil))
+    (goto-char (point-min))
+    (while (re-search-forward
+           ;; The following regexp was adapted from
+           ;; `ada-font-lock-syntactic-keywords'.
+           "^[ \t]*\\(#\\(?:if\\|else\\|elsif\\|end\\)\\)\\|[^a-zA-Z0-9)]\\('\\)[^'\n]\\('\\)"
+           nil t)
+      (if (match-beginning 1)
+         (put-text-property
+              (match-beginning 1) (match-end 1) 'syntax-table '(11 . ?\n))
+       (put-text-property
+            (match-beginning 2) (match-end 2) 'syntax-table '(7 . ?'))
+       (put-text-property
+            (match-beginning 3) (match-end 3) 'syntax-table '(7 . ?'))))
+    (unless modified
+      (restore-buffer-modified-p nil))))
 
 (defun ada-after-change-function (beg end old-len)
   "Called when the region between BEG and END was changed in the buffer.
 OLD-LEN indicates what the length of the replaced text was."
-  (let ((inhibit-point-motion-hooks t)
-       (eol (point)))
+  (save-excursion
+    (save-restriction
+      (let ((from (progn (goto-char beg) (line-beginning-position)))
+           (to (progn (goto-char end) (line-end-position))))
+       (narrow-to-region from to)
+       (save-match-data
+         (ada-set-syntax-table-properties))))))
+
+(defun ada-initialize-syntax-table-properties ()
+  "Assign `syntax-table' properties in current buffer."
     (save-excursion
-      (save-match-data
-       (beginning-of-line)
-       (remove-text-properties (point) eol '(syntax-table nil))
-       (while (re-search-forward "'.'" eol t)
-         (add-text-properties (match-beginning 0) (match-end 0)
-                              '(syntax-table ("'" . ?\"))))
-       (beginning-of-line)
-       (if (looking-at "^[ \t]*#")
-           (add-text-properties (match-beginning 0) (match-end 0)
-                                '(syntax-table (11 . 10))))))))
+      (save-restriction
+       (widen)
+       (save-match-data
+         (ada-set-syntax-table-properties))))
+    (add-hook 'after-change-functions 'ada-after-change-function nil t))
+
+(defun ada-handle-syntax-table-properties ()
+  "Handle `syntax-table' properties."
+  (if font-lock-mode
+      ;; `font-lock-mode' will take care of `syntax-table' properties.
+      (remove-hook 'after-change-functions 'ada-after-change-function t)
+    ;; Take care of `syntax-table' properties manually.
+    (ada-initialize-syntax-table-properties)))
 
 ;;------------------------------------------------------------------
 ;;  Testing the grammatical context
@@ -1125,6 +1145,8 @@ If you use ada-xref.el:
 
   (interactive)
   (kill-all-local-variables)
+  
+  (set-syntax-table ada-mode-syntax-table)
 
   (set (make-local-variable 'require-final-newline) mode-require-final-newline)
 
@@ -1158,13 +1180,9 @@ If you use ada-xref.el:
   ;;  the comment and the text. We do not want any, this is already
   ;;  included in comment-start
   (unless (featurep 'xemacs)
-    (progn
-      (if (ada-check-emacs-version 20 3)
-         (progn
-           (set (make-local-variable 'parse-sexp-ignore-comments) t)
-           (set (make-local-variable 'comment-padding) 0)))
-      (set (make-local-variable 'parse-sexp-lookup-properties) t)
-      ))
+    (set (make-local-variable 'parse-sexp-ignore-comments) t)
+    (set (make-local-variable 'comment-padding) 0)
+    (set (make-local-variable 'parse-sexp-lookup-properties) t))
 
   (set 'case-fold-search t)
   (if (boundp 'imenu-case-fold-search)
@@ -1193,6 +1211,7 @@ If you use ada-xref.el:
   ;;  We need to set some properties for XEmacs, and define some variables
   ;;  for Emacs
 
+  ;; FIXME: The Emacs code should work just fine under XEmacs AFAIK.  --Stef
   (if (featurep 'xemacs)
       ;;  XEmacs
       (put 'ada-mode 'font-lock-defaults
@@ -1216,36 +1235,36 @@ If you use ada-xref.el:
        ff-file-created-hook 'ada-make-body)
   (add-hook 'ff-pre-load-hook 'ada-which-function-are-we-in)
 
-  ;; Some special constructs for find-file.el.
   (make-local-variable 'ff-special-constructs)
-  (mapc (lambda (pair)
-         (add-to-list 'ff-special-constructs pair))
-       `(
-         ;; Go to the parent package.
-         (,(eval-when-compile
-             (concat "^\\(private[ \t]\\)?[ \t]*package[ \t]+"
-                     "\\(body[ \t]+\\)?"
-                     "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is"))
-          . ,(lambda ()
-               (ff-get-file
-                ada-search-directories-internal
-                (ada-make-filename-from-adaname (match-string 3))
-                ada-spec-suffixes)))
-         ;; A "separate" clause.
-         ("^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))"
-          . ,(lambda ()
-               (ff-get-file
-                ada-search-directories-internal
-                (ada-make-filename-from-adaname (match-string 1))
-                ada-spec-suffixes)))
-         ;; A "with" clause.
-         ("^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)"
-          . ,(lambda ()
-               (ff-get-file
-                ada-search-directories-internal
-                (ada-make-filename-from-adaname (match-string 1))
-                ada-spec-suffixes)))
-         ))
+  (mapc (lambda (pair) (add-to-list 'ff-special-constructs pair))
+        (list
+         ;; Top level child package declaration; go to the parent package.
+         (cons (eval-when-compile
+                 (concat "^\\(private[ \t]\\)?[ \t]*package[ \t]+"
+                         "\\(body[ \t]+\\)?"
+                         "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is"))
+               (lambda ()
+                 (ff-get-file
+                  ada-search-directories-internal
+                  (ada-make-filename-from-adaname (match-string 3))
+                  ada-spec-suffixes)))
+
+         ;; A "separate" clause.
+         (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))"
+               (lambda ()
+                 (ff-get-file
+                  ada-search-directories-internal
+                  (ada-make-filename-from-adaname (match-string 1))
+                  ada-spec-suffixes)))
+
+         ;; A "with" clause.
+         (cons "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)"
+               (lambda ()
+                 (ff-get-file
+                  ada-search-directories-internal
+                  (ada-make-filename-from-adaname (match-string 1))
+                  ada-spec-suffixes)))
+         ))
 
   ;;  Support for outline-minor-mode
   (set (make-local-variable 'outline-regexp)
@@ -1258,59 +1277,49 @@ If you use ada-xref.el:
   ;;  Support for ispell : Check only comments
   (set (make-local-variable 'ispell-check-comments) 'exclusive)
 
-  ;;  Support for align.el <= 2.2, if present
-  ;;  align.el is distributed with Emacs 21, but not with earlier versions.
-  (if (boundp 'align-mode-alist)
-      (add-to-list 'align-mode-alist '(ada-mode . ada-align-list)))
-
-  ;;  Support for align.el >= 2.8, if present
-  (if (boundp 'align-dq-string-modes)
-      (progn
-       (add-to-list 'align-dq-string-modes 'ada-mode)
-       (add-to-list 'align-open-comment-modes 'ada-mode)
-       (set (make-local-variable 'align-region-separate)
-            ada-align-region-separate)
-
-       ;; Exclude comments alone on line from alignment.
-       (add-to-list 'align-exclude-rules-list
-                    '(ada-solo-comment
-                      (regexp  . "^\\(\\s-*\\)--")
-                      (modes   . '(ada-mode))))
-       (add-to-list 'align-exclude-rules-list
-                    '(ada-solo-use
-                      (regexp  . "^\\(\\s-*\\)\\<use\\>")
-                      (modes   . '(ada-mode))))
-
-       (setq ada-align-modes nil)
-
-       (add-to-list 'ada-align-modes
-                    '(ada-declaration-assign
-                      (regexp  . "[^:]\\(\\s-*\\):[^:]")
-                      (valid   . (lambda() (not (ada-in-comment-p))))
-                      (repeat . t)
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-associate
-                      (regexp  . "[^=]\\(\\s-*\\)=>")
-                      (valid   . (lambda() (not (ada-in-comment-p))))
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-comment
-                      (regexp  . "\\(\\s-*\\)--")
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-use
-                      (regexp  . "\\(\\s-*\\)\\<use\\s-")
-                      (valid   . (lambda() (not (ada-in-comment-p))))
-                      (modes   . '(ada-mode))))
-       (add-to-list 'ada-align-modes
-                    '(ada-at
-                      (regexp . "\\(\\s-+\\)at\\>")
-                      (modes . '(ada-mode))))
-
-
-       (setq align-mode-rules-list ada-align-modes)
-       ))
+  ;;  Support for align
+  (add-to-list 'align-dq-string-modes 'ada-mode)
+  (add-to-list 'align-open-comment-modes 'ada-mode)
+  (set (make-local-variable 'align-region-separate) ada-align-region-separate)
+
+  ;; Exclude comments alone on line from alignment.
+  (add-to-list 'align-exclude-rules-list
+               '(ada-solo-comment
+                 (regexp  . "^\\(\\s-*\\)--")
+                 (modes   . '(ada-mode))))
+  (add-to-list 'align-exclude-rules-list
+               '(ada-solo-use
+                 (regexp  . "^\\(\\s-*\\)\\<use\\>")
+                 (modes   . '(ada-mode))))
+
+  (setq ada-align-modes nil)
+
+  (add-to-list 'ada-align-modes
+               '(ada-declaration-assign
+                 (regexp  . "[^:]\\(\\s-*\\):[^:]")
+                 (valid   . (lambda() (not (ada-in-comment-p))))
+                 (repeat . t)
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-associate
+                 (regexp  . "[^=]\\(\\s-*\\)=>")
+                 (valid   . (lambda() (not (ada-in-comment-p))))
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-comment
+                 (regexp  . "\\(\\s-*\\)--")
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-use
+                 (regexp  . "\\(\\s-*\\)\\<use\\s-")
+                 (valid   . (lambda() (not (ada-in-comment-p))))
+                 (modes   . '(ada-mode))))
+  (add-to-list 'ada-align-modes
+               '(ada-at
+                 (regexp . "\\(\\s-+\\)at\\>")
+                 (modes . '(ada-mode))))
+
+  (setq align-mode-rules-list ada-align-modes)
 
   ;;  Set up the contextual menu
   (if ada-popup-key
@@ -1321,17 +1330,11 @@ If you use ada-xref.el:
   (setq local-abbrev-table ada-mode-abbrev-table)
 
   ;;  Support for which-function mode
-  ;; which-function-mode does not work with nested subprograms, since it is
-  ;; based only on the regexps generated by imenu, and thus can only detect the
-  ;; beginning of subprograms, not the end.
-  ;; Fix is: redefine a new function ada-which-function, and call it when the
-  ;; major-mode is ada-mode.
-
   (make-local-variable 'which-func-functions)
   (setq which-func-functions '(ada-which-function))
 
   ;;  Support for indent-new-comment-line (Especially for XEmacs)
-  (setq comment-multi-line nil)
+  (set (make-local-variable 'comment-multi-line) nil)
 
   (setq major-mode 'ada-mode
        mode-name "Ada")
@@ -1368,9 +1371,8 @@ If you use ada-xref.el:
   ;;  font-lock-mode
 
   (unless (featurep 'xemacs)
-    (progn
-      (ada-initialize-properties)
-      (add-hook 'font-lock-mode-hook 'ada-deactivate-properties nil t)))
+    (ada-initialize-syntax-table-properties)
+    (add-hook 'font-lock-mode-hook 'ada-handle-syntax-table-properties nil t))
 
   ;; the following has to be done after running the ada-mode-hook
   ;; because users might want to set the values of these variable
@@ -1379,7 +1381,9 @@ If you use ada-xref.el:
   (cond ((eq ada-language-version 'ada83)
         (setq ada-keywords ada-83-keywords))
        ((eq ada-language-version 'ada95)
-        (setq ada-keywords ada-95-keywords)))
+        (setq ada-keywords ada-95-keywords))
+       ((eq ada-language-version 'ada2005)
+        (setq ada-keywords ada-2005-keywords)))
 
   (if ada-auto-case
       (ada-activate-keys-for-case)))
@@ -1395,10 +1399,9 @@ If you use ada-xref.el:
 ;;  transient-mark-mode and mark-active are not defined in XEmacs
 (defun ada-region-selected ()
   "Return t if a region has been selected by the user and is still active."
-  (or (and (featurep 'xemacs) (funcall (symbol-function 'region-active-p)))
-      (and (not (featurep 'xemacs))
-          (symbol-value 'transient-mark-mode)
-          (symbol-value 'mark-active))))
+  (if (featurep 'xemacs)
+      (region-active-p)
+    (and transient-mark-mode mark-active)))
 
 \f
 ;;-----------------------------------------------------------------
@@ -3412,9 +3415,14 @@ is the end of the match."
                                       (concat "\\<"
                                               (regexp-opt
                                                '("separate" "access" "array"
-                                                 "abstract" "new") t)
+                                                 "private" "abstract" "new") t)
                                               "\\>\\|("))))))))
 
+        ((looking-at "private")
+         (save-excursion
+           (backward-word 1)
+           (setq found (not (looking-at "is")))))
+
         (t
          (setq found t))
        )))
@@ -3509,10 +3517,10 @@ Moves point to the beginning of the declaration."
     ;;
     (save-excursion
       ;;
-      ;; a named 'declare'-block ?
+      ;; a named 'declare'-block ? => jump to the label
       ;;
       (if (looking-at "\\<declare\\>")
-         (ada-goto-stmt-start)
+         (backward-word 1)
        ;;
        ;; no, => 'procedure'/'function'/'task'/'protected'
        ;;
@@ -3702,6 +3710,14 @@ If NOERROR is non-nil, it only returns nil if no matching start was found.
 If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
   (let ((nest-count (if nest-level nest-level 0))
        (found nil)
+
+       (last-was-begin '())
+       ;;  List all keywords encountered while traversing
+       ;;  something like '("end" "end" "begin")
+       ;;  This is removed from the list when "package", "procedure",...
+       ;;  are seen. The goal is to find whether a package has an elaboration
+       ;;  part
+
        (pos nil))
 
     ;; search backward for interesting keywords
@@ -3718,6 +3734,7 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
          (cond
           ;; found block end => increase nest depth
           ((looking-at "end")
+           (push nil last-was-begin)
            (setq nest-count (1+ nest-count)))
 
           ;; found loop/select/record/case/if => check if it starts or
@@ -3728,13 +3745,24 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
              ;; check if keyword follows 'end'
              (ada-goto-previous-word)
              (if (looking-at "\\<end\\>[ \t]*[^;]")
-                 ;; it ends a block => increase nest depth
-                 (setq nest-count (1+ nest-count)
-                       pos        (point))
+                 (progn
+                   ;; it ends a block => increase nest depth
+                   (setq nest-count (1+ nest-count)
+                         pos        (point))
+                   (push nil last-was-begin))
 
                ;; it starts a block => decrease nest depth
-               (setq nest-count (1- nest-count))))
-           (goto-char pos))
+               (setq nest-count (1- nest-count))
+
+               ;; Some nested  "begin .. end" blocks with no "declare"?
+               ;;  => remove those entries
+               (while (car last-was-begin)
+                 (setq last-was-begin (cdr (cdr last-was-begin))))
+
+               (setq last-was-begin (cdr last-was-begin))
+               ))
+           (goto-char pos)
+           )
 
           ;; found package start => check if it really is a block
           ((looking-at "package")
@@ -3758,8 +3786,12 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
                  ;;  or            package Foo is separate;
                  ;;  or            package Foo is begin null; end Foo
                  ;;                     for elaboration code (elaboration)
-                 (if (not (looking-at "\\<\\(new\\|separate\\|begin\\)\\>"))
-                     (setq nest-count (1- nest-count)))))))
+                 (if (and (not (looking-at "\\<\\(new\\|separate\\|begin\\)\\>"))
+                          (not (car last-was-begin)))
+                     (setq nest-count (1- nest-count))))))
+
+           (setq last-was-begin (cdr last-was-begin))
+           )
           ;; found task start => check if it has a body
           ((looking-at "task")
            (save-excursion
@@ -3791,10 +3823,53 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
                ;; it (i.e do nothing if we have just "task name;")
                (unless (progn (forward-word 1)
                               (looking-at "[ \t]*;"))
-                 (setq nest-count (1- nest-count)))))))
+                 (setq nest-count (1- nest-count))))))
+           (setq last-was-begin (cdr last-was-begin))
+           )
+
+          ((looking-at "declare")
+           ;;  remove entry for begin and end (include nested begin..end
+           ;;  groups)
+           (setq last-was-begin (cdr last-was-begin))
+           (let ((count 1))
+             (while (and (> count 0))
+               (if (equal (car last-was-begin) t)
+                   (setq count (1+ count))
+                 (setq count (1- count)))
+               (setq last-was-begin (cdr last-was-begin))
+               )))
+
+          ((looking-at "protected")
+           ;; Ignore if this is just a declaration
+           (save-excursion
+             (let ((pos (ada-search-ignore-string-comment
+                         "\\(\\<is\\>\\|\\<renames\\>\\|;\\)" nil)))
+               (if pos
+                   (goto-char (car pos)))
+               (if (looking-at "is")
+                   ;;  remove entry for end
+                   (setq last-was-begin (cdr last-was-begin)))))
+           (setq nest-count     (1- nest-count)))
+
+          ((or (looking-at "procedure")
+               (looking-at "function"))
+           ;; Ignore if this is just a declaration
+           (save-excursion
+             (let ((pos (ada-search-ignore-string-comment
+                         "\\(\\<is\\>\\|\\<renames\\>\\|)[ \t]*;\\)" nil)))
+               (if pos
+                   (goto-char (car pos)))
+               (if (looking-at "is")
+                   ;;  remove entry for begin and end
+                   (setq last-was-begin (cdr (cdr last-was-begin))))))
+           )
+
           ;; all the other block starts
           (t
-           (setq nest-count (1- nest-count)))) ; end of 'cond'
+           (push (looking-at "begin") last-was-begin)
+           (setq nest-count (1- nest-count)))
+
+          )
 
          ;; match is found, if nest-depth is zero
          (setq found (zerop nest-count))))) ; end of loop
@@ -3950,7 +4025,7 @@ Returns a cons cell of begin and end of match data or nil, if not found.
 If BACKWARD is non-nil, search backward; search forward otherwise.
 The search stops at pos LIMIT.
 If PARAMLISTS is nil, ignore parameter lists.
-The search is done using SEARCH-FUNC. SEARCH-FUNC can be optimized
+The search is done using SEARCH-FUNC.  SEARCH-FUNC can be optimized
 in case we are searching for a constant string.
 Point is moved at the beginning of the SEARCH-RE."
   (let (found
@@ -4430,7 +4505,7 @@ Moves to 'begin' if in a declarative part."
   (interactive)
   (end-of-line)
   (if (re-search-forward ada-procedure-start-regexp nil t)
-      (goto-char (match-beginning 2))
+      (goto-char (match-beginning 4))
     (error "No more functions/procedures/tasks")))
 
 (defun ada-previous-procedure ()
@@ -4438,7 +4513,7 @@ Moves to 'begin' if in a declarative part."
   (interactive)
   (beginning-of-line)
   (if (re-search-backward ada-procedure-start-regexp nil t)
-      (goto-char (match-beginning 2))
+      (goto-char (match-beginning 4))
     (error "No more functions/procedures/tasks")))
 
 (defun ada-next-package ()
@@ -4471,9 +4546,7 @@ Moves to 'begin' if in a declarative part."
   (define-key ada-mode-map "\t"       'ada-tab)
   (define-key ada-mode-map "\C-c\t"   'ada-justified-indent-current)
   (define-key ada-mode-map "\C-c\C-l" 'ada-indent-region)
-  (if (featurep 'xemacs)
-      (define-key ada-mode-map '(shift tab)    'ada-untab)
-    (define-key ada-mode-map [(shift tab)]    'ada-untab))
+  (define-key ada-mode-map [(shift tab)]    'ada-untab)
   (define-key ada-mode-map "\C-c\C-f" 'ada-format-paramlist)
   ;; We don't want to make meta-characters case-specific.
 
@@ -4496,9 +4569,9 @@ Moves to 'begin' if in a declarative part."
   ;; On XEmacs, you can easily specify whether DEL should deletes
   ;; one character forward or one character backward. Take this into
   ;; account
-  (if (boundp 'delete-key-deletes-forward)
-      (define-key ada-mode-map [backspace] 'backward-delete-char-untabify)
-    (define-key ada-mode-map "\177" 'backward-delete-char-untabify))
+  (define-key ada-mode-map
+    (if (boundp 'delete-key-deletes-forward) [backspace] "\177")
+    'backward-delete-char-untabify)
 
   ;; Make body
   (define-key ada-mode-map "\C-c\C-n" 'ada-make-subprogram-body)
@@ -4510,12 +4583,10 @@ Moves to 'begin' if in a declarative part."
   ;; The following keys are bound to functions defined in ada-xref.el or
   ;; ada-prj,el., However, RMS rightly thinks that the code should be shared,
   ;; and activated only if the right compiler is used
-  (if (featurep 'xemacs)
-      (progn
-       (define-key ada-mode-map '(shift button3) 'ada-point-and-xref)
-       (define-key ada-mode-map '(control tab) 'ada-complete-identifier))
-    (define-key ada-mode-map [C-tab] 'ada-complete-identifier)
-    (define-key ada-mode-map [S-mouse-3] 'ada-point-and-xref))
+  
+  (define-key ada-mode-map (if (featurep 'xemacs) '(shift button3) [S-mouse-3])
+    'ada-point-and-xref)
+  (define-key ada-mode-map [(control tab)] 'ada-complete-identifier)
 
   (define-key ada-mode-map "\C-co"     'ff-find-other-file)
   (define-key ada-mode-map "\C-c5\C-d" 'ada-goto-declaration-other-frame)
@@ -4525,6 +4596,7 @@ Moves to 'begin' if in a declarative part."
   (define-key ada-mode-map "\C-cc"     'ada-change-prj)
   (define-key ada-mode-map "\C-cd"     'ada-set-default-project-file)
   (define-key ada-mode-map "\C-cg"     'ada-gdb-application)
+  (define-key ada-mode-map "\C-c\C-m"  'ada-set-main-compile-application)
   (define-key ada-mode-map "\C-cr"     'ada-run-application)
   (define-key ada-mode-map "\C-c\C-o"  'ada-goto-parent)
   (define-key ada-mode-map "\C-c\C-r"  'ada-find-references)
@@ -4582,8 +4654,7 @@ Moves to 'begin' if in a declarative part."
               (eq ada-which-compiler 'gnat)]
              ["Gdb Documentation"      (info "gdb")
               (eq ada-which-compiler 'gnat)]
-             ["Ada95 Reference Manual" (info "arm95")
-              (eq ada-which-compiler 'gnat)])
+             ["Ada95 Reference Manual" (info "arm95") t])
             ("Options"  :included (eq major-mode 'ada-mode)
              ["Auto Casing" (setq ada-auto-case (not ada-auto-case))
               :style toggle :selected ada-auto-case]
@@ -4610,11 +4681,14 @@ Moves to 'begin' if in a declarative part."
              :included (fboundp 'customize-group)]
             ["Check file"    ada-check-current   t]
             ["Compile file"  ada-compile-current t]
+            ["Set main and Build" ada-set-main-compile-application t]
+            ["Show main" ada-show-current-main t]
             ["Build"         ada-compile-application t]
             ["Run"           ada-run-application     t]
             ["Debug"         ada-gdb-application (eq ada-which-compiler 'gnat)]
             ["------"        nil nil]
             ("Project"
+             ["Show project" ada-show-current-project t]
              ["Load..."      ada-set-default-project-file t]
              ["New..."       ada-prj-new                  t]
              ["Edit..."      ada-prj-edit                 t])
@@ -4958,13 +5032,14 @@ or the spec otherwise."
 
 (defun ada-which-function-are-we-in ()
   "Return the name of the function whose definition/declaration point is in.
-Redefines the function `ff-which-function-are-we-in'."
+Used in `ff-pre-load-hook'."
   (setq ff-function-name nil)
   (save-excursion
     (end-of-line);;  make sure we get the complete name
-    (if (or (re-search-backward ada-procedure-start-regexp nil t)
-           (re-search-backward ada-package-start-regexp nil t))
-       (setq ff-function-name (match-string 0)))
+    (or (if (re-search-backward ada-procedure-start-regexp nil t)
+            (setq ff-function-name (match-string 5)))
+        (if (re-search-backward ada-package-start-regexp nil t)
+            (setq ff-function-name (match-string 4))))
     ))
 
 
@@ -5113,8 +5188,7 @@ Return nil if no body was found."
   ;; This sets the properties of the characters, so that ada-in-string-p
   ;; correctly handles '"' too...
   '(("[^a-zA-Z0-9)]\\('\\)[^'\n]\\('\\)" (1 (7 . ?')) (2 (7 . ?')))
-    ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n)))
-    ))
+    ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n)))))
 
 (defvar ada-font-lock-keywords
   (eval-when-compile
@@ -5162,11 +5236,11 @@ Return nil if no body was found."
              '("abort" "abs" "abstract" "accept" "access" "aliased" "all"
                "and" "array" "at" "begin" "case" "declare" "delay" "delta"
                "digits" "do" "else" "elsif" "entry" "exception" "exit" "for"
-               "generic" "if" "in" "is" "limited" "loop" "mod" "not"
-               "null" "or" "others" "private" "protected" "raise"
+               "generic" "if" "in" "interface" "is" "limited" "loop" "mod" "not"
+               "null" "or" "others" "overriding" "private" "protected" "raise"
                "range" "record" "rem" "renames" "requeue" "return" "reverse"
-               "select" "separate" "tagged" "task" "terminate" "then" "until"
-               "when" "while" "with" "xor") t)
+               "select" "separate" "synchronized" "tagged" "task" "terminate"
+                "then" "until" "when" "while" "with" "xor") t)
             "\\>")
      ;;
      ;; Anything following end and not already fontified is a body name.
@@ -5324,10 +5398,8 @@ for `ada-procedure-start-regexp'."
 
 (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)
+The spec must be the previously visited buffer.
+This function typically is to be hooked into `ff-file-created-hook'."
   (delete-region (point-min) (point-max))
   (insert-buffer-substring (car (cdr (buffer-list))))
   (goto-char (point-min))
@@ -5358,7 +5430,7 @@ This function typically is to be hooked into `ff-file-created-hooks'."
 
 
 (defun ada-make-subprogram-body ()
-  "Make one dummy subprogram body from spec surrounding point."
+  "Create a dummy subprogram body in package body file from spec surrounding point."
   (interactive)
   (let* ((found (re-search-backward ada-procedure-start-regexp nil t))
         (spec  (match-beginning 0))
@@ -5417,35 +5489,34 @@ This function typically is to be hooked into `ff-file-created-hooks'."
 (ada-case-read-exceptions)
 
 ;;  Setup auto-loading of the other Ada mode files.
-(if (equal ada-which-compiler 'gnat)
-    (progn
-      (autoload 'ada-change-prj                   "ada-xref" nil t)
-      (autoload 'ada-check-current                "ada-xref" nil t)
-      (autoload 'ada-compile-application          "ada-xref" nil t)
-      (autoload 'ada-compile-current              "ada-xref" nil t)
-      (autoload 'ada-complete-identifier          "ada-xref" nil t)
-      (autoload 'ada-find-file                    "ada-xref" nil t)
-      (autoload 'ada-find-any-references          "ada-xref" nil t)
-      (autoload 'ada-find-src-file-in-dir         "ada-xref" nil t)
-      (autoload 'ada-find-local-references        "ada-xref" nil t)
-      (autoload 'ada-find-references              "ada-xref" nil t)
-      (autoload 'ada-gdb-application              "ada-xref" nil t)
-      (autoload 'ada-goto-declaration             "ada-xref" nil t)
-      (autoload 'ada-goto-declaration-other-frame "ada-xref" nil t)
-      (autoload 'ada-goto-parent                  "ada-xref" nil t)
-      (autoload 'ada-make-body-gnatstub           "ada-xref" nil t)
-      (autoload 'ada-point-and-xref               "ada-xref" nil t)
-      (autoload 'ada-reread-prj-file              "ada-xref" nil t)
-      (autoload 'ada-run-application              "ada-xref" nil t)
-      (autoload 'ada-set-default-project-file     "ada-xref" nil nil)
-      (autoload 'ada-set-default-project-file     "ada-xref" nil t)
-      (autoload 'ada-xref-goto-previous-reference "ada-xref" nil t)
-
-      (autoload 'ada-customize                    "ada-prj"  nil t)
-      (autoload 'ada-prj-edit                     "ada-prj"  nil t)
-      (autoload 'ada-prj-new                      "ada-prj"  nil t)
-      (autoload 'ada-prj-save                     "ada-prj"  nil t)
-      ))
+(autoload 'ada-change-prj                   "ada-xref" nil t)
+(autoload 'ada-check-current                "ada-xref" nil t)
+(autoload 'ada-compile-application          "ada-xref" nil t)
+(autoload 'ada-compile-current              "ada-xref" nil t)
+(autoload 'ada-complete-identifier          "ada-xref" nil t)
+(autoload 'ada-find-file                    "ada-xref" nil t)
+(autoload 'ada-find-any-references          "ada-xref" nil t)
+(autoload 'ada-find-src-file-in-dir         "ada-xref" nil t)
+(autoload 'ada-find-local-references        "ada-xref" nil t)
+(autoload 'ada-find-references              "ada-xref" nil t)
+(autoload 'ada-gdb-application              "ada-xref" nil t)
+(autoload 'ada-goto-declaration             "ada-xref" nil t)
+(autoload 'ada-goto-declaration-other-frame "ada-xref" nil t)
+(autoload 'ada-goto-parent                  "ada-xref" nil t)
+(autoload 'ada-make-body-gnatstub           "ada-xref" nil t)
+(autoload 'ada-point-and-xref               "ada-xref" nil t)
+(autoload 'ada-reread-prj-file              "ada-xref" nil t)
+(autoload 'ada-run-application              "ada-xref" nil t)
+(autoload 'ada-set-default-project-file     "ada-xref" nil nil)
+(autoload 'ada-set-default-project-file     "ada-xref" nil t)
+(autoload 'ada-xref-goto-previous-reference "ada-xref" nil t)
+(autoload 'ada-set-main-compile-application "ada-xref" nil t)
+(autoload 'ada-show-current-main            "ada-xref" nil t)
+
+(autoload 'ada-customize                    "ada-prj"  nil t)
+(autoload 'ada-prj-edit                     "ada-prj"  nil t)
+(autoload 'ada-prj-new                      "ada-prj"  nil t)
+(autoload 'ada-prj-save                     "ada-prj"  nil t)
 
 (autoload 'ada-array           "ada-stmt" nil t)
 (autoload 'ada-case            "ada-stmt" nil t)
@@ -5479,5 +5550,5 @@ This function typically is to be hooked into `ff-file-created-hooks'."
 ;;; provide ourselves
 (provide 'ada-mode)
 
-;;; arch-tag: 1b7d45ec-1698-43b5-8d4a-e479ea023270
+;; arch-tag: 1b7d45ec-1698-43b5-8d4a-e479ea023270
 ;;; ada-mode.el ends here