* progmodes/ada-mode.el: Deal with Ada 2005 "overriding" keyword.
[bpt/emacs.git] / lisp / progmodes / ada-mode.el
index 39e66b0..b25e540 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, 2007, 2008  Free Software Foundation, Inc.
+;;   2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
 ;; Author: Rolf Ebert      <ebert@inf.enst.fr>
 ;;      Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; 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 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,9 +22,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 ;; This mode is a major mode for editing Ada code.  This is a major
 (require 'which-func nil t)
 (require 'compile nil t)
 
-(defvar compile-auto-highlight)
 (defvar ispell-check-comments)
 (defvar skeleton-further-elements)
 
 (defun ada-mode-version ()
   "Return Ada mode version."
   (interactive)
-  (let ((version-string "3.7"))
-    (if (interactive-p)
+  (let ((version-string "4.00"))
+    (if (called-interactively-p 'interactive)
        (message version-string)
       version-string)))
 
@@ -235,6 +232,10 @@ It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
 (defcustom ada-clean-buffer-before-saving t
   "*Non-nil means remove trailing spaces and untabify the buffer before saving."
   :type 'boolean :group 'ada)
+(make-obsolete-variable 'ada-clean-buffer-before-saving
+                       "use the `write-file-functions' hook."
+                       "23.2")
+
 
 (defcustom ada-indent 3
   "*Size of Ada indentation.
@@ -450,6 +451,13 @@ The extensions should include a `.' if needed.")
 (defvar ada-mode-map (make-sparse-keymap)
   "Local keymap used for Ada mode.")
 
+(defvar ada-mode-extra-map (make-sparse-keymap)
+  "Keymap used for non-standard keybindings.")
+
+;; default is C-c C-q because it's free in ada-mode-map
+(defvar ada-mode-extra-prefix "\C-c\C-q"
+  "Prefix key to access `ada-mode-extra-map' functions.")
+
 (defvar ada-mode-abbrev-table nil
   "Local abbrev table for Ada mode.")
 
@@ -631,6 +639,7 @@ The package name is in (match-string 4).")
     (concat "\\("
            ";"                                        "\\|"
            "=>[ \t]*$"                                "\\|"
+           "=>[ \t]*--.*$"                            "\\|"
            "^[ \t]*separate[ \t]*(\\(\\sw\\|[_.]\\)+)"  "\\|"
            "\\<" (regexp-opt '("begin" "declare" "is" "do" "else" "generic"
                                "loop" "private" "record" "select"
@@ -665,7 +674,7 @@ A new statement starts after these.")
 
 (defvar ada-subprog-start-re
   (eval-when-compile
-    (concat "\\<" (regexp-opt '("accept" "entry" "function" "package" "procedure"
+    (concat "\\<" (regexp-opt '("accept" "entry" "function" "overriding" "package" "procedure"
                                "protected" "task") t) "\\>"))
   "Regexp for the start of a subprogram.")
 
@@ -712,7 +721,7 @@ displaying the menu if point was on an identifier."
 (defconst ada-imenu-comment-re "\\([ \t]*--.*\\)?")
 
 (defconst ada-imenu-subprogram-menu-re
-  (concat "^[ \t]*\\(procedure\\|function\\)[ \t\n]+"
+  (concat "^[ \t]*\\(overriding[ \t]*\\)?\\(procedure\\|function\\)[ \t\n]+"
          "\\(\\(\\sw\\|_\\)+\\)[ \t\n]*\\([ \t\n]\\|([^)]+)"
          ada-imenu-comment-re
          "\\)[ \t\n]*"
@@ -720,7 +729,7 @@ displaying the menu if point was on an identifier."
 
 (defvar ada-imenu-generic-expression
   (list
-   (list nil ada-imenu-subprogram-menu-re 2)
+   (list nil ada-imenu-subprogram-menu-re 3)
    (list "*Specs*"
         (concat
          "^[ \t]*\\(procedure\\|function\\)[ \t\n]+\\(\\(\\sw\\|_\\)+\\)"
@@ -785,13 +794,14 @@ the 4 file locations can be clicked on and jumped to."
 
       ;; set source marker
       (save-excursion
-        (compilation-find-file (point-marker) (match-string 1) "./")
-        (set-buffer file)
+       (compilation-find-file (point-marker) (match-string 1) "./")
+       (set-buffer file)
 
-        (if (stringp line)
-            (goto-line (string-to-number line)))
+       (when (stringp line)
+         (goto-char (point-min))
+         (forward-line (1- (string-to-number line))))
 
-        (setq source (point-marker)))
+       (setq source (point-marker)))
 
       (compilation-goto-locus error-pos source nil)
 
@@ -930,8 +940,7 @@ are treated as numbers instead of gnatprep comments."
        (buffer-undo-list t)
        (inhibit-read-only t)
        (inhibit-point-motion-hooks t)
-       (inhibit-modification-hooks t)
-       buffer-file-name buffer-file-truename)
+       (inhibit-modification-hooks t))
     (remove-text-properties (point-min) (point-max) '(syntax-table nil))
     (goto-char (point-min))
     (while (re-search-forward
@@ -1101,48 +1110,7 @@ the file name."
 
 ;;;###autoload
 (defun ada-mode ()
-  "Ada mode is the major mode for editing Ada code.
-
-Bindings are as follows: (Note: 'LFD' is control-j.)
-\\{ada-mode-map}
-
- Indent line                                          '\\[ada-tab]'
- Indent line, insert newline and indent the new line. '\\[newline-and-indent]'
-
- Re-format the parameter-list point is in             '\\[ada-format-paramlist]'
- Indent all lines in region                           '\\[ada-indent-region]'
-
- Adjust case of identifiers and keywords in region    '\\[ada-adjust-case-region]'
- Adjust case of identifiers and keywords in buffer    '\\[ada-adjust-case-buffer]'
-
- Fill comment paragraph, justify and append postfix   '\\[fill-paragraph]'
-
- 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]'
-
-Comments are handled using standard GNU Emacs conventions, including:
- Start a comment                                      '\\[indent-for-comment]'
- Comment region                                       '\\[comment-region]'
- Uncomment region                                     '\\[ada-uncomment-region]'
- Continue comment on next line                        '\\[indent-new-comment-line]'
-
-If you use imenu.el:
- Display index-menu of functions and procedures       '\\[imenu]'
-
-If you use find-file.el:
- Switch to other file (Body <-> Spec)                 '\\[ff-find-other-file]'
-                                                  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
-                        or '\\[ada-goto-declaration]' with point on the identifier
- Complete identifier:       '\\[ada-complete-identifier]'."
+  "Ada mode is the major mode for editing Ada code."
 
   (interactive)
   (kill-all-local-variables)
@@ -1192,14 +1160,10 @@ If you use ada-xref.el:
   (set (make-local-variable 'fill-paragraph-function)
        'ada-fill-comment-paragraph)
 
-  (set (make-local-variable 'imenu-generic-expression)
-       ada-imenu-generic-expression)
-
   ;;  Support for compile.el
   ;;  We just substitute our own functions to go to the error.
   (add-hook 'compilation-mode-hook
            (lambda()
-             (set (make-local-variable 'compile-auto-highlight) 40)
              ;; FIXME: This has global impact!  -stef
              (define-key compilation-minor-mode-map [mouse-2]
                'ada-compile-mouse-goto-error)
@@ -1209,23 +1173,13 @@ If you use ada-xref.el:
                'ada-compile-goto-error)))
 
   ;;  font-lock support :
-  ;;  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
-          '(ada-font-lock-keywords
-            nil t ((?\_ . "w") (?# . ".")) beginning-of-line))
-    ;;  Emacs
-    (set (make-local-variable 'font-lock-defaults)
-        '(ada-font-lock-keywords
-          nil t
-          ((?\_ . "w") (?# . "."))
-          beginning-of-line
-          (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords)))
-    )
+  (set (make-local-variable 'font-lock-defaults)
+       '(ada-font-lock-keywords
+        nil t
+        ((?\_ . "w") (?# . "."))
+        beginning-of-line
+        (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords)))
 
   ;; Set up support for find-file.el.
   (set (make-local-variable 'ff-other-file-alist)
@@ -1238,34 +1192,34 @@ If you use ada-xref.el:
 
   (make-local-variable 'ff-special-constructs)
   (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)))
-         ))
+       (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)
@@ -1273,6 +1227,8 @@ If you use ada-xref.el:
   (set (make-local-variable 'outline-level) 'ada-outline-level)
 
   ;;  Support for imenu : We want a sorted index
+  (setq imenu-generic-expression ada-imenu-generic-expression)
+
   (setq imenu-sort-function 'imenu--sort-by-name)
 
   ;;  Support for ispell : Check only comments
@@ -1285,40 +1241,40 @@ If you use ada-xref.el:
 
   ;; Exclude comments alone on line from alignment.
   (add-to-list 'align-exclude-rules-list
-               '(ada-solo-comment
-                 (regexp  . "^\\(\\s-*\\)--")
-                 (modes   . '(ada-mode))))
+              '(ada-solo-comment
+                (regexp  . "^\\(\\s-*\\)--")
+                (modes   . '(ada-mode))))
   (add-to-list 'align-exclude-rules-list
-               '(ada-solo-use
-                 (regexp  . "^\\(\\s-*\\)\\<use\\>")
-                 (modes   . '(ada-mode))))
+              '(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))))
+              '(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))))
+              '(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))))
+              '(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))))
+              '(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))))
+              '(ada-at
+                (regexp . "\\(\\s-+\\)at\\>")
+                (modes . '(ada-mode))))
 
   (setq align-mode-rules-list ada-align-modes)
 
@@ -1337,6 +1293,9 @@ If you use ada-xref.el:
   ;;  Support for indent-new-comment-line (Especially for XEmacs)
   (set (make-local-variable 'comment-multi-line) nil)
 
+  ;;  Support for add-log
+  (set (make-local-variable 'add-log-current-defun-function) 'ada-which-function)
+
   (setq major-mode 'ada-mode
        mode-name "Ada")
 
@@ -1346,14 +1305,6 @@ If you use ada-xref.el:
 
   (set-syntax-table ada-mode-syntax-table)
 
-  (if ada-clean-buffer-before-saving
-      (progn
-       ;; remove all spaces at the end of lines in the whole buffer.
-       (add-hook 'local-write-file-hooks 'delete-trailing-whitespace)
-       ;; convert all tabs to the correct number of spaces.
-       (add-hook 'local-write-file-hooks
-                 (lambda () (untabify (point-min) (point-max))))))
-
   (set (make-local-variable 'skeleton-further-elements)
        '((< '(backward-delete-char-untabify
              (min ada-indent (current-column))))))
@@ -1435,7 +1386,7 @@ Casing exception lists are `ada-case-exception' and `ada-case-exception-substrin
 (defun ada-create-case-exception (&optional word)
   "Define WORD as an exception for the casing system.
 If WORD is not given, then the current word in the buffer is used instead.
-The new words is added to the first file in `ada-case-exception-file'.
+The new word is added to the first file in `ada-case-exception-file'.
 The standard casing rules will no longer apply to this word."
   (interactive)
   (let ((previous-syntax-table (syntax-table))
@@ -1672,7 +1623,7 @@ ARG is the prefix the user entered with \\[universal-argument]."
   (interactive "P")
 
   (if ada-auto-case
-      (let ((lastk last-command-char)
+      (let ((lastk last-command-event)
            (previous-syntax-table (syntax-table)))
 
        (unwind-protect
@@ -1706,9 +1657,9 @@ ARG is the prefix the user entered with \\[universal-argument]."
 
     ;; Else, no auto-casing
     (cond
-     ((eq last-command-char ?\n)
+     ((eq last-command-event ?\n)
       (funcall ada-lfd-binding))
-     ((eq last-command-char ?\r)
+     ((eq last-command-event ?\r)
       (funcall ada-ret-binding))
      (t
       (self-insert-command (prefix-numeric-value arg))))
@@ -1755,7 +1706,7 @@ adapt to unusal auto-casing schemes.  Since it does nothing, you can for
 instance use it for `ada-case-identifier' if you don't want any special
 auto-casing for identifiers, whereas keywords have to be lower-cased.
 See also `ada-auto-case' to disable auto casing altogether."
-  )
+  nil)
 
 (defun ada-capitalize-word (&optional arg)
   "Upcase first letter and letters following '_', lower case other letters.
@@ -2192,7 +2143,7 @@ The original line is indented first if `ada-indent-after-return' is non-nil."
 
 (defun ada-batch-reformat ()
   "Re-indent and re-case all the files found on the command line.
-This function should be used from the Unix/Windows command line, with a
+This function should be used from the command line, with a
 command like:
   emacs -batch -l ada-mode -f ada-batch-reformat file1 file2 ..."
 
@@ -2214,8 +2165,8 @@ Return the new position of point or nil if not found."
 
 (defun ada-indent-current ()
   "Indent current line as Ada code.
-Return the calculation that was done, including the reference point and the
-offset."
+Return the calculation that was done, including the reference point
+and the offset."
   (interactive)
   (let ((previous-syntax-table (syntax-table))
        (orgpoint (point-marker))
@@ -2526,7 +2477,7 @@ offset."
            (list (progn (back-to-indentation) (point)) 'ada-indent))
        (save-excursion
          (ada-goto-stmt-start)
-         (if (looking-at "\\<package\\|procedure\\|function\\>")
+         (if (looking-at "\\<overriding\\|package\\|procedure\\|function\\>")
              (list (progn (back-to-indentation) (point)) 0)
            (list (progn (back-to-indentation) (point)) 'ada-indent)))))
 
@@ -2675,20 +2626,23 @@ offset."
           (looking-at "\\<\\(package\\|function\\|procedure\\)\\>"))
       (save-excursion
        ;;  Go up until we find either a generic section, or the end of the
-       ;;  previous subprogram/package
+       ;;  previous subprogram/package, or 'overriding' for this function/procedure
        (let (found)
          (while (and (not found)
                      (ada-search-ignore-string-comment
-            "\\<\\(generic\\|end\\|begin\\|package\\|procedure\\|function\\)\\>" t))
+            "\\<\\(generic\\|end\\|begin\\|overriding\\|package\\|procedure\\|function\\)\\>" t))
 
            ;;  avoid "with procedure"... in generic parts
            (save-excursion
              (forward-word -1)
              (setq found (not (looking-at "with"))))))
 
-       (if (looking-at "generic")
-           (list (progn (back-to-indentation) (point)) 0)
-         (ada-indent-on-previous-lines nil orgpoint orgpoint))))
+       (cond
+        ((looking-at "\\<generic\\|overriding\\>")
+         (list (progn (back-to-indentation) (point)) 0))
+
+        (t
+         (ada-indent-on-previous-lines nil orgpoint orgpoint)))))
 
      ;;---------------------------------
      ;; label
@@ -2825,7 +2779,7 @@ if INITIAL-POS is non-nil, moves point to INITIAL-POS before calculation."
      (t
       (goto-char (cdr (ada-search-ignore-string-comment "(\\|;" t nil t)))
       (ada-goto-next-non-ws)
-      (list (point) 0)))))
+      (list (point) 'ada-broken-indent)))))
 
 (defun ada-get-indent-end (orgpoint)
   "Calculate the indentation when point is just before an end statement.
@@ -2843,12 +2797,15 @@ ORGPOINT is the limit position used in the calculation."
          (forward-word 1)
          (ada-goto-next-non-ws)
          (cond
-          ((looking-at "\\<\\(loop\\|select\\|if\\|case\\)\\>")
+          ;;
+          ;; loop/select/if/case/return
+          ;;
+          ((looking-at "\\<\\(loop\\|select\\|if\\|case\\|return\\)\\>")
            (save-excursion (ada-check-matching-start (match-string 0)))
            (list (save-excursion (back-to-indentation) (point)) 0))
 
           ;;
-          ;; loop/select/if/case/record/select
+          ;; record
           ;;
           ((looking-at "\\<record\\>")
            (save-excursion
@@ -3191,7 +3148,7 @@ ORGPOINT is the limit position used in the calculation."
       (setq pos (ada-get-indent-block-start orgpoint))
       (if (equal label 0)
          pos
-       (list (+ (car pos) label) (cdr pos))))
+       (list (+ (car pos) label) (cadr pos))))
 
      ;;
      ;; 'for'- loop (or also a for ... use statement)
@@ -3501,11 +3458,13 @@ Moves point to the matching block start."
 Assumes point to be already positioned by `ada-goto-matching-start'.
 Moves point to the beginning of the declaration."
 
-  ;; named block without a `declare'
+  ;; named block without a `declare'; ada-goto-matching-start leaves
+  ;; point at start of 'begin' for a block.
   (if (save-excursion
        (ada-goto-previous-word)
        (looking-at (concat "\\<" defun-name "\\> *:")))
       t                                 ; do nothing
+    ;; else
     ;;
     ;; 'accept' or 'package' ?
     ;;
@@ -3519,7 +3478,9 @@ Moves point to the beginning of the declaration."
       ;; a named 'declare'-block ? => jump to the label
       ;;
       (if (looking-at "\\<declare\\>")
-         (backward-word 1)
+         (progn
+           (forward-comment -1)
+           (backward-word 1))
        ;;
        ;; no, => 'procedure'/'function'/'task'/'protected'
        ;;
@@ -3896,13 +3857,12 @@ If GOTOTHEN is non-nil, point moves to the 'then' following 'if'."
              (goto-char (match-beginning 0)))
 
             ;;
-            ;; found 'do' => skip back to 'accept'
+            ;; found 'do' => skip back to 'accept' or 'return'
             ;;
             ((looking-at "do")
              (unless (ada-search-ignore-string-comment
-                      "accept" t nil nil
-                      'word-search-backward)
-               (error "Missing 'accept' in front of 'do'"))))
+                      "\\<accept\\|return\\>" t)
+               (error "Missing 'accept' or 'return' in front of 'do'"))))
            (point))
 
        (if noerror
@@ -4539,6 +4499,9 @@ Moves to 'begin' if in a declarative part."
 (defun ada-create-keymap ()
   "Create the keymap associated with the Ada mode."
 
+  ;; All non-standard keys go into ada-mode-extra-map
+  (define-key ada-mode-map ada-mode-extra-prefix ada-mode-extra-map)
+
   ;; Indentation and Formatting
   (define-key ada-mode-map "\C-j"     'ada-indent-newline-indent-conditional)
   (define-key ada-mode-map "\C-m"     'ada-indent-newline-indent-conditional)
@@ -4587,23 +4550,23 @@ Moves to 'begin' if in a declarative part."
     '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-extra-map "o"     'ff-find-other-file)
   (define-key ada-mode-map "\C-c5\C-d" 'ada-goto-declaration-other-frame)
   (define-key ada-mode-map "\C-c\C-d"  'ada-goto-declaration)
   (define-key ada-mode-map "\C-c\C-s"  'ada-xref-goto-previous-reference)
   (define-key ada-mode-map "\C-c\C-c"  'ada-compile-application)
-  (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-extra-map "c"     'ada-change-prj)
+  (define-key ada-mode-extra-map "d"     'ada-set-default-project-file)
+  (define-key ada-mode-extra-map "g"     '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-extra-map "r"     '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)
-  (define-key ada-mode-map "\C-cl"     'ada-find-local-references)
+  (define-key ada-mode-extra-map "l"     'ada-find-local-references)
   (define-key ada-mode-map "\C-c\C-v"  'ada-check-current)
-  (define-key ada-mode-map "\C-cf"     'ada-find-file)
+  (define-key ada-mode-extra-map "f"     'ada-find-file)
 
-  (define-key ada-mode-map "\C-cu"  'ada-prj-edit)
+  (define-key ada-mode-extra-map "u"  'ada-prj-edit)
 
   ;;  The templates, defined in ada-stmt.el
 
@@ -4636,7 +4599,7 @@ Moves to 'begin' if in a declarative part."
     (define-key map "w"    'ada-while-loop)
     (define-key map "\C-x" 'ada-exception)
     (define-key map "x"    'ada-exit)
-    (define-key ada-mode-map "\C-ct" map))
+    (define-key ada-mode-extra-map "t" map))
   )
 
 
@@ -5035,9 +4998,9 @@ Used in `ff-pre-load-hook'."
   (save-excursion
     (end-of-line);;  make sure we get the complete name
     (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))))
+           (setq ff-function-name (match-string 5)))
+       (if (re-search-backward ada-package-start-regexp nil t)
+           (setq ff-function-name (match-string 4))))
     ))
 
 
@@ -5097,7 +5060,7 @@ Since the search can be long, the results are cached."
 
          ;; Get the function name, but not the properties, or this changes
          ;; the face in the modeline on Emacs 21
-         (setq func-name (match-string-no-properties 2))
+         (setq func-name (match-string-no-properties 3))
          (if (and (not (ada-in-comment-p))
                   (not (save-excursion
                          (goto-char (match-end 0))
@@ -5180,12 +5143,12 @@ Return nil if no body was found."
 
 (defconst ada-font-lock-syntactic-keywords
   ;; Mark single quotes as having string quote syntax in 'c' instances.
-  ;; As a special case, ''' will not be highlighted, but if we do not
-  ;; set this special case, then the rest of the buffer is highlighted as
-  ;; a string
+  ;; We used to explicitly avoid ''' as a special case for fear the buffer
+  ;; be highlighted as a string, but it seems this fear is unfounded.
+  ;;
   ;; 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 . ?')))
+  '(("[^a-zA-Z0-9)]\\('\\)[^\n]\\('\\)" (1 (7 . ?')) (2 (7 . ?')))
     ("^[ \t]*\\(#\\(if\\|else\\|elsif\\|end\\)\\)" (1 (11 . ?\n)))))
 
 (defvar ada-font-lock-keywords
@@ -5238,7 +5201,7 @@ Return nil if no body was found."
                "null" "or" "others" "overriding" "private" "protected" "raise"
                "range" "record" "rem" "renames" "requeue" "return" "reverse"
                "select" "separate" "synchronized" "tagged" "task" "terminate"
-                "then" "until" "when" "while" "with" "xor") t)
+               "then" "until" "when" "while" "with" "xor") t)
             "\\>")
      ;;
      ;; Anything following end and not already fontified is a body name.
@@ -5375,13 +5338,15 @@ for `ada-procedure-start-regexp'."
        (insert "end " procname ";")
        (ada-indent-newline-indent)
        )
-       ;; else
+
        ((looking-at "[ \t\n]*is")
        ;; do nothing
        )
+
        ((looking-at "[ \t\n]*rename")
        ;; do nothing
        )
+
        (t
        (message "unknown syntax"))))
      (t
@@ -5505,7 +5470,6 @@ This function typically is to be hooked into `ff-file-created-hook'."
 (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)