1;;; ada-mode.el --- major-mode for editing Ada sources 2 3;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 4;; 2005, 2006, 2007 Free Software Foundation, Inc. 5 6;; Author: Rolf Ebert <ebert@inf.enst.fr> 7;; Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de> 8;; Emmanuel Briot <briot@gnat.com> 9;; Maintainer: Stephen Leake <stephen_leake@member.fsf.org> 10;; Keywords: languages ada 11 12;; This file is part of GNU Emacs. 13 14;; GNU Emacs is free software; you can redistribute it and/or modify 15;; it under the terms of the GNU General Public License as published by 16;; the Free Software Foundation; either version 2, or (at your option) 17;; any later version. 18 19;; GNU Emacs is distributed in the hope that it will be useful, 20;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22;; GNU General Public License for more details. 23 24;; You should have received a copy of the GNU General Public License 25;; along with GNU Emacs; see the file COPYING. If not, write to the 26;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 27;; Boston, MA 02110-1301, USA. 28 29;;; Commentary: 30;;; This mode is a major mode for editing Ada code. This is a major 31;;; rewrite of the file packaged with Emacs-20. The Ada mode is 32;;; composed of four Lisp files: ada-mode.el, ada-xref.el, ada-prj.el 33;;; and ada-stmt.el. Only this file (ada-mode.el) is completely 34;;; independent from the GNU Ada compiler GNAT, distributed by Ada 35;;; Core Technologies. All the other files rely heavily on features 36;;; provided only by GNAT. 37;;; 38;;; Note: this mode will not work with Emacs 19. If you are on a VMS 39;;; system, where the latest version of Emacs is 19.28, you will need 40;;; another file, called ada-vms.el, that provides some required 41;;; functions. 42 43;;; Usage: 44;;; Emacs should enter Ada mode automatically when you load an Ada file. 45;;; By default, the valid extensions for Ada files are .ads, .adb or .ada 46;;; If the ada-mode does not start automatically, then simply type the 47;;; following command : 48;;; M-x ada-mode 49;;; 50;;; By default, ada-mode is configured to take full advantage of the GNAT 51;;; compiler (the menus will include the cross-referencing features,...). 52;;; If you are using another compiler, you might want to set the following 53;;; variable in your .emacs (Note: do not set this in the ada-mode-hook, it 54;;; won't work) : 55;;; (setq ada-which-compiler 'generic) 56;;; 57;;; This mode requires find-file.el to be present on your system. 58 59;;; History: 60;;; The first Ada mode for GNU Emacs was written by V. Broman in 61;;; 1985. He based his work on the already existing Modula-2 mode. 62;;; This was distributed as ada.el in versions of Emacs prior to 19.29. 63;;; 64;;; Lynn Slater wrote an extensive Ada mode in 1989. It consisted of 65;;; several files with support for dired commands and other nice 66;;; things. It is currently available from the PAL 67;;; (wuarchive.wustl.edu:/languages/ada) as ada-mode-1.06a.tar.Z. 68;;; 69;;; The probably very first Ada mode (called electric-ada.el) was 70;;; written by Steven D. Litvintchouk and Steven M. Rosen for the 71;;; Gosling Emacs. L. Slater based his development on ada.el and 72;;; electric-ada.el. 73;;; 74;;; A complete rewrite by M. Heritsch and R. Ebert has been done. 75;;; Some ideas from the Ada mode mailing list have been 76;;; added. Some of the functionality of L. Slater's mode has not 77;;; (yet) been recoded in this new mode. Perhaps you prefer sticking 78;;; to his version. 79;;; 80;;; A complete rewrite for Emacs-20 / GNAT-3.11 has been done by Ada Core 81;;; Technologies. 82 83;;; Credits: 84;;; Many thanks to John McCabe <john@assen.demon.co.uk> for sending so 85;;; many patches included in this package. 86;;; Christian Egli <Christian.Egli@hcsd.hac.com>: 87;;; ada-imenu-generic-expression 88;;; Many thanks also to the following persons that have contributed 89;;; to the ada-mode 90;;; Philippe Waroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular, 91;;; woodruff@stc.llnl.gov (John Woodruff) 92;;; jj@ddci.dk (Jesper Joergensen) 93;;; gse@ocsystems.com (Scott Evans) 94;;; comar@gnat.com (Cyrille Comar) 95;;; stephen.leake@gsfc.nasa.gov (Stephen Leake) 96;;; robin-reply@reagans.org 97;;; and others for their valuable hints. 98 99;;; Code: 100;;; Note: Every function in this package is compiler-independent. 101;;; The names start with ada- 102;;; The variables that the user can edit can all be modified through 103;;; the customize mode. They are sorted in alphabetical order in this 104;;; file. 105 106;;; Supported packages. 107;;; This package supports a number of other Emacs modes. These other modes 108;;; should be loaded before the ada-mode, which will then setup some variables 109;;; to improve the support for Ada code. 110;;; Here is the list of these modes: 111;;; `which-function-mode': Display the name of the subprogram the cursor is 112;;; in in the mode line. 113;;; `outline-mode': Provides the capability to collapse or expand the code 114;;; for specific language constructs, for instance if you want to hide the 115;;; code corresponding to a subprogram 116;;; `align': This mode is now provided with Emacs 21, but can also be 117;;; installed manually for older versions of Emacs. It provides the 118;;; capability to automatically realign the selected region (for instance 119;;; all ':=', ':' and '--' will be aligned on top of each other. 120;;; `imenu': Provides a menu with the list of entities defined in the current 121;;; buffer, and an easy way to jump to any of them 122;;; `speedbar': Provides a separate file browser, and the capability for each 123;;; file to see the list of entities defined in it and to jump to them 124;;; easily 125;;; `abbrev-mode': Provides the capability to define abbreviations, which 126;;; are automatically expanded when you type them. See the Emacs manual. 127 128(require 'find-file nil t) 129(require 'align nil t) 130(require 'which-func nil t) 131(require 'compile nil t) 132 133(defvar compile-auto-highlight) 134(defvar ispell-check-comments) 135(defvar skeleton-further-elements) 136 137(eval-and-compile 138 (defun ada-check-emacs-version (major minor &optional is-xemacs) 139 "Return t if Emacs's version is greater or equal to MAJOR.MINOR. 140If IS-XEMACS is non-nil, check for XEmacs instead of Emacs." 141 (let ((xemacs-running (or (string-match "Lucid" emacs-version) 142 (string-match "XEmacs" emacs-version)))) 143 (and (or (and is-xemacs xemacs-running) 144 (not (or is-xemacs xemacs-running))) 145 (or (> emacs-major-version major) 146 (and (= emacs-major-version major) 147 (>= emacs-minor-version minor))))))) 148 149(defun ada-mode-version () 150 "Return Ada mode version." 151 (interactive) 152 (let ((version-string "3.7")) 153 (if (interactive-p) 154 (message version-string) 155 version-string))) 156 157(defvar ada-mode-hook nil 158 "*List of functions to call when Ada mode is invoked. 159This hook is automatically executed after the `ada-mode' is 160fully loaded. 161This is a good place to add Ada environment specific bindings.") 162 163(defgroup ada nil 164 "Major mode for editing and compiling Ada source in Emacs." 165 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) 166 :group 'languages) 167 168(defcustom ada-auto-case t 169 "*Non-nil means automatically change case of preceding word while typing. 170Casing is done according to `ada-case-keyword', `ada-case-identifier' 171and `ada-case-attribute'." 172 :type 'boolean :group 'ada) 173 174(defcustom ada-broken-decl-indent 0 175 "*Number of columns to indent a broken declaration. 176 177An example is : 178 declare 179 A, 180 >>>>>B : Integer;" 181 :type 'integer :group 'ada) 182 183(defcustom ada-broken-indent 2 184 "*Number of columns to indent the continuation of a broken line. 185 186An example is : 187 My_Var : My_Type := (Field1 => 188 >>>>>>>>>Value);" 189 :type 'integer :group 'ada) 190 191(defcustom ada-continuation-indent ada-broken-indent 192 "*Number of columns to indent the continuation of broken lines in parenthesis. 193 194An example is : 195 Func (Param1, 196 >>>>>Param2);" 197 :type 'integer :group 'ada) 198 199(defcustom ada-case-attribute 'ada-capitalize-word 200 "*Function to call to adjust the case of Ada attributes. 201It may be `downcase-word', `upcase-word', `ada-loose-case-word', 202`ada-capitalize-word' or `ada-no-auto-case'." 203 :type '(choice (const downcase-word) 204 (const upcase-word) 205 (const ada-capitalize-word) 206 (const ada-loose-case-word) 207 (const ada-no-auto-case)) 208 :group 'ada) 209 210(defcustom ada-case-exception-file 211 (list (convert-standard-filename' "~/.emacs_case_exceptions")) 212 "*List of special casing exceptions dictionaries for identifiers. 213The first file is the one where new exceptions will be saved by Emacs 214when you call `ada-create-case-exception'. 215 216These files should contain one word per line, that gives the casing 217to be used for that word in Ada files. If the line starts with the 218character *, then the exception will be used for substrings that either 219start at the beginning of a word or after a _ character, and end either 220at the end of the word or at a _ character. Each line can be terminated 221by a comment." 222 :type '(repeat (file)) 223 :group 'ada) 224 225(defcustom ada-case-keyword 'downcase-word 226 "*Function to call to adjust the case of an Ada keywords. 227It may be `downcase-word', `upcase-word', `ada-loose-case-word' or 228`ada-capitalize-word'." 229 :type '(choice (const downcase-word) 230 (const upcase-word) 231 (const ada-capitalize-word) 232 (const ada-loose-case-word) 233 (const ada-no-auto-case)) 234 :group 'ada) 235 236(defcustom ada-case-identifier 'ada-loose-case-word 237 "*Function to call to adjust the case of an Ada identifier. 238It may be `downcase-word', `upcase-word', `ada-loose-case-word' or 239`ada-capitalize-word'." 240 :type '(choice (const downcase-word) 241 (const upcase-word) 242 (const ada-capitalize-word) 243 (const ada-loose-case-word) 244 (const ada-no-auto-case)) 245 :group 'ada) 246 247(defcustom ada-clean-buffer-before-saving t 248 "*Non-nil means remove trailing spaces and untabify the buffer before saving." 249 :type 'boolean :group 'ada) 250 251(defcustom ada-indent 3 252 "*Size of Ada indentation. 253 254An example is : 255procedure Foo is 256begin 257>>>>>>>>>>null;" 258 :type 'integer :group 'ada) 259 260(defcustom ada-indent-after-return t 261 "*Non-nil means automatically indent after RET or LFD." 262 :type 'boolean :group 'ada) 263 264(defcustom ada-indent-align-comments t 265 "*Non-nil means align comments on previous line comments, if any. 266If nil, indentation is calculated as usual. 267Note that indentation is calculated only if `ada-indent-comment-as-code' is t. 268 269For instance: 270 A := 1; -- A multi-line comment 271 -- aligned if ada-indent-align-comments is t" 272 :type 'boolean :group 'ada) 273 274(defcustom ada-indent-comment-as-code t 275 "*Non-nil means indent comment lines as code. 276A nil value means do not auto-indent comments." 277 :type 'boolean :group 'ada) 278 279(defcustom ada-indent-handle-comment-special nil 280 "*Non-nil if comment lines should be handled specially inside parenthesis. 281By default, if the line that contains the open parenthesis has some 282text following it, then the following lines will be indented in the 283same column as this text. This will not be true if the first line is 284a comment and `ada-indent-handle-comment-special' is t. 285 286type A is 287 ( Value_1, -- common behavior, when not a comment 288 Value_2); 289 290type A is 291 ( -- `ada-indent-handle-comment-special' is nil 292 Value_1, 293 Value_2); 294 295type A is 296 ( -- `ada-indent-handle-comment-special' is non-nil 297 Value_1, 298 Value_2);" 299 :type 'boolean :group 'ada) 300 301(defcustom ada-indent-is-separate t 302 "*Non-nil means indent 'is separate' or 'is abstract' if on a single line." 303 :type 'boolean :group 'ada) 304 305(defcustom ada-indent-record-rel-type 3 306 "*Indentation for 'record' relative to 'type' or 'use'. 307 308An example is: 309 type A is 310 >>>>>>>>>>>record" 311 :type 'integer :group 'ada) 312 313(defcustom ada-indent-renames ada-broken-indent 314 "*Indentation for renames relative to the matching function statement. 315If `ada-indent-return' is null or negative, the indentation is done relative to 316the open parenthesis (if there is no parenthesis, `ada-broken-indent' is used). 317 318An example is: 319 function A (B : Integer) 320 return C; 321 >>>renames Foo;" 322 :type 'integer :group 'ada) 323 324(defcustom ada-indent-return 0 325 "*Indentation for 'return' relative to the matching 'function' statement. 326If `ada-indent-return' is null or negative, the indentation is done relative to 327the open parenthesis (if there is no parenthesis, `ada-broken-indent' is used). 328 329An example is: 330 function A (B : Integer) 331 >>>>>return C;" 332 :type 'integer :group 'ada) 333 334(defcustom ada-indent-to-open-paren t 335 "*Non-nil means indent according to the innermost open parenthesis." 336 :type 'boolean :group 'ada) 337 338(defcustom ada-fill-comment-prefix "-- " 339 "*Text inserted in the first columns when filling a comment paragraph. 340Note: if you modify this variable, you will have to invoke `ada-mode' 341again to take account of the new value." 342 :type 'string :group 'ada) 343 344(defcustom ada-fill-comment-postfix " --" 345 "*Text inserted at the end of each line when filling a comment paragraph. 346Used by `ada-fill-comment-paragraph-postfix'." 347 :type 'string :group 'ada) 348 349(defcustom ada-label-indent -4 350 "*Number of columns to indent a label. 351 352An example is: 353procedure Foo is 354begin 355>>>>Label: 356 357This is also used for <<..>> labels" 358 :type 'integer :group 'ada) 359 360(defcustom ada-language-version 'ada95 361 "*Ada language version; one of `ada83', `ada95', `ada2005'." 362 :type '(choice (const ada83) (const ada95) (const ada2005)) :group 'ada) 363 364(defcustom ada-move-to-declaration nil 365 "*Non-nil means `ada-move-to-start' moves to the subprogram declaration, not to 'begin'." 366 :type 'boolean :group 'ada) 367 368(defcustom ada-popup-key '[down-mouse-3] 369 "*Key used for binding the contextual menu. 370If nil, no contextual menu is available." 371 :type '(restricted-sexp :match-alternatives (stringp vectorp)) 372 :group 'ada) 373 374(defcustom ada-search-directories 375 (append '(".") 376 (split-string (or (getenv "ADA_INCLUDE_PATH") "") ":") 377 '("/usr/adainclude" "/usr/local/adainclude" 378 "/opt/gnu/adainclude")) 379 "*Default list of directories to search for Ada files. 380See the description for the `ff-search-directories' variable. This variable 381is the initial value of `ada-search-directories-internal'." 382 :type '(repeat (choice :tag "Directory" 383 (const :tag "default" nil) 384 (directory :format "%v"))) 385 :group 'ada) 386 387(defvar ada-search-directories-internal ada-search-directories 388 "Internal version of `ada-search-directories'. 389Its value is the concatenation of the search path as read in the project file 390and the standard runtime location, and the value of the user-defined 391`ada-search-directories'.") 392 393(defcustom ada-stmt-end-indent 0 394 "*Number of columns to indent the end of a statement on a separate line. 395 396An example is: 397 if A = B 398 >>>>then" 399 :type 'integer :group 'ada) 400 401(defcustom ada-tab-policy 'indent-auto 402 "*Control the behavior of the TAB key. 403Must be one of : 404`indent-rigidly' : always adds `ada-indent' blanks at the beginning of the line. 405`indent-auto' : use indentation functions in this file. 406`always-tab' : do `indent-relative'." 407 :type '(choice (const indent-auto) 408 (const indent-rigidly) 409 (const always-tab)) 410 :group 'ada) 411 412(defcustom ada-use-indent ada-broken-indent 413 "*Indentation for the lines in a 'use' statement. 414 415An example is: 416 use Ada.Text_IO, 417 >>>>Ada.Numerics;" 418 :type 'integer :group 'ada) 419 420(defcustom ada-when-indent 3 421 "*Indentation for 'when' relative to 'exception' or 'case'. 422 423An example is: 424 case A is 425 >>>>when B =>" 426 :type 'integer :group 'ada) 427 428(defcustom ada-with-indent ada-broken-indent 429 "*Indentation for the lines in a 'with' statement. 430 431An example is: 432 with Ada.Text_IO, 433 >>>>Ada.Numerics;" 434 :type 'integer :group 'ada) 435 436(defcustom ada-which-compiler 'gnat 437 "*Name of the compiler to use. 438This will determine what features are made available through the Ada mode. 439The possible choices are: 440`gnat': Use Ada Core Technologies' GNAT compiler. Add some cross-referencing 441 features. 442`generic': Use a generic compiler." 443 :type '(choice (const gnat) 444 (const generic)) 445 :group 'ada) 446 447 448;;; ---- end of user configurable variables 449 450 451(defvar ada-body-suffixes '(".adb") 452 "List of possible suffixes for Ada body files. 453The extensions should include a `.' if needed.") 454 455(defvar ada-spec-suffixes '(".ads") 456 "List of possible suffixes for Ada spec files. 457The extensions should include a `.' if needed.") 458 459(defvar ada-mode-menu (make-sparse-keymap "Ada") 460 "Menu for Ada mode.") 461 462(defvar ada-mode-map (make-sparse-keymap) 463 "Local keymap used for Ada mode.") 464 465(defvar ada-mode-abbrev-table nil 466 "Local abbrev table for Ada mode.") 467 468(defvar ada-mode-syntax-table nil 469 "Syntax table to be used for editing Ada source code.") 470 471(defvar ada-mode-symbol-syntax-table nil 472 "Syntax table for Ada, where `_' is a word constituent.") 473 474(eval-when-compile 475 ;; These values are used in eval-when-compile expressions. 476 (defconst ada-83-string-keywords 477 '("abort" "abs" "accept" "access" "all" "and" "array" "at" "begin" 478 "body" "case" "constant" "declare" "delay" "delta" "digits" "do" 479 "else" "elsif" "end" "entry" "exception" "exit" "for" "function" 480 "generic" "goto" "if" "in" "is" "limited" "loop" "mod" "new" 481 "not" "null" "of" "or" "others" "out" "package" "pragma" "private" 482 "procedure" "raise" "range" "record" "rem" "renames" "return" 483 "reverse" "select" "separate" "subtype" "task" "terminate" "then" 484 "type" "use" "when" "while" "with" "xor") 485 "List of Ada 83 keywords. 486Used to define `ada-*-keywords'.") 487 488 (defconst ada-95-string-keywords 489 '("abstract" "aliased" "protected" "requeue" "tagged" "until") 490 "List of keywords new in Ada 95. 491Used to define `ada-*-keywords'.") 492 493 (defconst ada-2005-string-keywords 494 '("interface" "overriding" "synchronized") 495 "List of keywords new in Ada 2005. 496Used to define `ada-*-keywords.'")) 497 498(defvar ada-ret-binding nil 499 "Variable to save key binding of RET when casing is activated.") 500 501(defvar ada-case-exception '() 502 "Alist of words (entities) that have special casing.") 503 504(defvar ada-case-exception-substring '() 505 "Alist of substrings (entities) that have special casing. 506The substrings are detected for word constituant when the word 507is not itself in `ada-case-exception', and only for substrings that 508either are at the beginning or end of the word, or start after '_'.") 509 510(defvar ada-lfd-binding nil 511 "Variable to save key binding of LFD when casing is activated.") 512 513(defvar ada-other-file-alist nil 514 "Variable used by `find-file' to find the name of the other package. 515See `ff-other-file-alist'.") 516 517(defvar ada-align-list 518 '(("[^:]\\(\\s-*\\):[^:]" 1 t) 519 ("[^=]\\(\\s-+\\)=[^=]" 1 t) 520 ("\\(\\s-*\\)use\\s-" 1) 521 ("\\(\\s-*\\)--" 1)) 522 "Ada support for align.el <= 2.2. 523This variable provides regular expressions on which to align different lines. 524See `align-mode-alist' for more information.") 525 526(defvar ada-align-modes 527 '((ada-declaration 528 (regexp . "[^:]\\(\\s-*\\):[^:]") 529 (valid . (lambda() (not (ada-in-comment-p)))) 530 (modes . '(ada-mode))) 531 (ada-assignment 532 (regexp . "[^=]\\(\\s-+\\)=[^=]") 533 (valid . (lambda() (not (ada-in-comment-p)))) 534 (modes . '(ada-mode))) 535 (ada-comment 536 (regexp . "\\(\\s-*\\)--") 537 (modes . '(ada-mode))) 538 (ada-use 539 (regexp . "\\(\\s-*\\)use\\s-") 540 (valid . (lambda() (not (ada-in-comment-p)))) 541 (modes . '(ada-mode))) 542 ) 543 "Ada support for align.el >= 2.8. 544This variable defines several rules to use to align different lines.") 545 546(defconst ada-align-region-separate 547 (eval-when-compile 548 (concat 549 "^\\s-*\\($\\|\\(" 550 "begin\\|" 551 "declare\\|" 552 "else\\|" 553 "end\\|" 554 "exception\\|" 555 "for\\|" 556 "function\\|" 557 "generic\\|" 558 "if\\|" 559 "is\\|" 560 "procedure\\|" 561 "record\\|" 562 "return\\|" 563 "type\\|" 564 "when" 565 "\\)\\>\\)")) 566 "See the variable `align-region-separate' for more information.") 567 568;;; ---- Below are the regexp used in this package for parsing 569 570(defconst ada-83-keywords 571 (eval-when-compile 572 (concat "\\<" (regexp-opt ada-83-string-keywords t) "\\>")) 573 "Regular expression matching Ada83 keywords.") 574 575(defconst ada-95-keywords 576 (eval-when-compile 577 (concat "\\<" (regexp-opt 578 (append 579 ada-95-string-keywords 580 ada-83-string-keywords) t) "\\>")) 581 "Regular expression matching Ada95 keywords.") 582 583(defconst ada-2005-keywords 584 (eval-when-compile 585 (concat "\\<" (regexp-opt 586 (append 587 ada-2005-string-keywords 588 ada-83-string-keywords 589 ada-95-string-keywords) t) "\\>")) 590 "Regular expression matching Ada2005 keywords.") 591 592(defvar ada-keywords ada-2005-keywords 593 "Regular expression matching Ada keywords.") 594;; FIXME: make this customizable 595 596(defconst ada-ident-re 597 "\\(\\sw\\|[_.]\\)+" 598 "Regexp matching Ada (qualified) identifiers.") 599 600;; "with" needs to be included in the regexp, to match generic subprogram parameters 601;; Similarly, we put '[not] overriding' on the same line with 'procedure' etc. 602(defvar ada-procedure-start-regexp 603 (concat 604 "^[ \t]*\\(with[ \t]+\\)?\\(\\(not[ \t]+\\)?overriding[ \t]+\\)?\\(procedure\\|function\\|task\\)[ \t\n]+" 605 606 ;; subprogram name: operator ("[+/=*]") 607 "\\(" 608 "\\(\"[^\"]+\"\\)" 609 610 ;; subprogram name: name 611 "\\|" 612 "\\(\\(\\sw\\|[_.]\\)+\\)" 613 "\\)") 614 "Regexp matching Ada subprogram start. 615The actual start is at (match-beginning 4). The name is in (match-string 5).") 616 617(defconst ada-name-regexp 618 "\\([a-zA-Z][a-zA-Z0-9_.']*[a-zA-Z0-9]\\)" 619 "Regexp matching a fully qualified name (including attribute).") 620 621(defconst ada-package-start-regexp 622 (concat "^[ \t]*\\(private[ \t]+\\)?\\(package\\)[ \t\n]+\\(body[ \t]*\\)?" ada-name-regexp) 623 "Regexp matching start of package. 624The package name is in (match-string 4).") 625 626(defconst ada-compile-goto-error-file-linenr-re 627 "\\([-_.a-zA-Z0-9]+\\):\\([0-9]+\\)\\(:\\([0-9]+\\)\\)?" 628 "Regexp matching filename:linenr[:column].") 629 630 631;;; ---- regexps for indentation functions 632 633(defvar ada-block-start-re 634 (eval-when-compile 635 (concat "\\<\\(" (regexp-opt '("begin" "declare" "else" 636 "exception" "generic" "loop" "or" 637 "private" "select" )) 638 "\\|\\(\\(limited\\|abstract\\|tagged\\)[ \t\n]+\\)*record\\)\\>")) 639 "Regexp for keywords starting Ada blocks.") 640 641(defvar ada-end-stmt-re 642 (eval-when-compile 643 (concat "\\(" 644 ";" "\\|" 645 "=>[ \t]*$" "\\|" 646 "^[ \t]*separate[ \t]*(\\(\\sw\\|[_.]\\)+)" "\\|" 647 "\\<" (regexp-opt '("begin" "declare" "is" "do" "else" "generic" 648 "loop" "private" "record" "select" 649 "then abort" "then") t) "\\>" "\\|" 650 "^[ \t]*" (regexp-opt '("function" "package" "procedure") 651 t) "\\>\\(\\sw\\|[ \t_.]\\)+\\<is\\>" "\\|" 652 "^[ \t]*exception\\>" 653 "\\)") ) 654 "Regexp of possible ends for a non-broken statement. 655A new statement starts after these.") 656 657(defvar ada-matching-start-re 658 (eval-when-compile 659 (concat "\\<" 660 (regexp-opt 661 '("end" "loop" "select" "begin" "case" "do" "declare" 662 "if" "task" "package" "procedure" "function" "record" "protected") t) 663 "\\>")) 664 "Regexp used in `ada-goto-matching-start'.") 665 666(defvar ada-matching-decl-start-re 667 (eval-when-compile 668 (concat "\\<" 669 (regexp-opt 670 '("is" "separate" "end" "declare" "if" "new" "begin" "generic" "when") t) 671 "\\>")) 672 "Regexp used in `ada-goto-matching-decl-start'.") 673 674(defvar ada-loop-start-re 675 "\\<\\(for\\|while\\|loop\\)\\>" 676 "Regexp for the start of a loop.") 677 678(defvar ada-subprog-start-re 679 (eval-when-compile 680 (concat "\\<" (regexp-opt '("accept" "entry" "function" "package" "procedure" 681 "protected" "task") t) "\\>")) 682 "Regexp for the start of a subprogram.") 683 684(defvar ada-named-block-re 685 "[ \t]*\\(\\sw\\|_\\)+[ \t]*:[^=]" 686 "Regexp of the name of a block or loop.") 687 688(defvar ada-contextual-menu-on-identifier nil 689 "Set to true when the right mouse button was clicked on an identifier.") 690 691(defvar ada-contextual-menu-last-point nil 692 "Position of point just before displaying the menu. 693This is a list (point buffer). 694Since `ada-popup-menu' moves the point where the user clicked, the region 695is modified. Therefore no command from the menu knows what the user selected 696before displaying the contextual menu. 697To get the original region, restore the point to this position before 698calling `region-end' and `region-beginning'. 699Modify this variable if you want to restore the point to another position.") 700 701(easy-menu-define ada-contextual-menu nil 702 "Menu to use when the user presses the right mouse button. 703The variable `ada-contextual-menu-on-identifier' will be set to t before 704displaying the menu if point was on an identifier." 705 '("Ada" 706 ["Goto Declaration/Body" ada-point-and-xref 707 :included ada-contextual-menu-on-identifier] 708 ["Goto Body" ada-point-and-xref-body 709 :included ada-contextual-menu-on-identifier] 710 ["Goto Previous Reference" ada-xref-goto-previous-reference] 711 ["List References" ada-find-references 712 :included ada-contextual-menu-on-identifier] 713 ["List Local References" ada-find-local-references 714 :included ada-contextual-menu-on-identifier] 715 ["-" nil nil] 716 ["Other File" ff-find-other-file] 717 ["Goto Parent Unit" ada-goto-parent])) 718 719 720;;------------------------------------------------------------------ 721;; Support for imenu (see imenu.el) 722;;------------------------------------------------------------------ 723 724(defconst ada-imenu-comment-re "\\([ \t]*--.*\\)?") 725 726(defconst ada-imenu-subprogram-menu-re 727 (concat "^[ \t]*\\(procedure\\|function\\)[ \t\n]+" 728 "\\(\\(\\sw\\|_\\)+\\)[ \t\n]*\\([ \t\n]\\|([^)]+)" 729 ada-imenu-comment-re 730 "\\)[ \t\n]*" 731 "\\(return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?is[ \t\n]")) 732 733(defvar ada-imenu-generic-expression 734 (list 735 (list nil ada-imenu-subprogram-menu-re 2) 736 (list "*Specs*" 737 (concat 738 "^[ \t]*\\(procedure\\|function\\)[ \t\n]+\\(\\(\\sw\\|_\\)+\\)" 739 "\\(" 740 "\\(" ada-imenu-comment-re "[ \t\n]+\\|[ \t\n]*([^)]+)" 741 ada-imenu-comment-re "\\)";; parameter list or simple space 742 "\\([ \t\n]*return[ \t\n]+\\(\\sw\\|[_.]\\)+[ \t\n]*\\)?" 743 "\\)?;") 2) 744 '("*Tasks*" "^[ \t]*task[ \t]+\\(type[ \t]+\\)?\\(\\(body[ \t]+\\)?\\(\\sw\\|_\\)+\\)" 2) 745 '("*Type Defs*" "^[ \t]*\\(sub\\)?type[ \t]+\\(\\(\\sw\\|_\\)+\\)" 2) 746 '("*Protected*" 747 "^[ \t]*protected[ \t]+\\(type[ \t]+\\)?\\(\\(body[ \t]+\\)?\\(\\sw\\|_\\)+\\)" 2) 748 '("*Packages*" "^[ \t]*package[ \t]+\\(\\(body[ \t]+\\)?\\(\\sw\\|[_.]\\)+\\)" 1)) 749 "Imenu generic expression for Ada mode. 750See `imenu-generic-expression'. This variable will create several submenus for 751each type of entity that can be found in an Ada file.") 752 753 754;;------------------------------------------------------------ 755;; Support for compile.el 756;;------------------------------------------------------------ 757 758(defun ada-compile-mouse-goto-error () 759 "Mouse interface for `ada-compile-goto-error'." 760 (interactive) 761 (mouse-set-point last-input-event) 762 (ada-compile-goto-error (point)) 763 ) 764 765(defun ada-compile-goto-error (pos) 766 "Replace `compile-goto-error' from compile.el. 767If POS is on a file and line location, go to this position. It adds 768to compile.el the capacity to go to a reference in an error message. 769For instance, on these lines: 770 foo.adb:61:11: [...] in call to size declared at foo.ads:11 771 foo.adb:61:11: [...] in call to local declared at line 20 772the 4 file locations can be clicked on and jumped to." 773 (interactive "d") 774 (goto-char pos) 775 776 (skip-chars-backward "-a-zA-Z0-9_:./\\") 777 (cond 778 ;; special case: looking at a filename:line not at the beginning of a line 779 ;; or a simple line reference "at line ..." 780 ((and (not (bolp)) 781 (or (looking-at ada-compile-goto-error-file-linenr-re) 782 (and 783 (save-excursion 784 (beginning-of-line) 785 (looking-at ada-compile-goto-error-file-linenr-re)) 786 (save-excursion 787 (if (looking-at "\\([0-9]+\\)") (backward-word 1)) 788 (looking-at "line \\([0-9]+\\)")))) 789 ) 790 (let ((line (if (match-beginning 2) (match-string 2) (match-string 1))) 791 (file (if (match-beginning 2) (match-string 1) 792 (save-excursion (beginning-of-line) 793 (looking-at ada-compile-goto-error-file-linenr-re) 794 (match-string 1)))) 795 (error-pos (point-marker)) 796 source) 797 798 ;; set source marker 799 (save-excursion 800 (compilation-find-file (point-marker) (match-string 1) "./") 801 (set-buffer file) 802 803 (if (stringp line) 804 (goto-line (string-to-number line))) 805 806 (setq source (point-marker))) 807 808 (compilation-goto-locus error-pos source nil) 809 810 )) 811 812 ;; otherwise, default behavior 813 (t 814 (compile-goto-error)) 815 ) 816 (recenter)) 817 818 819;;------------------------------------------------------------------------- 820;; Grammar related function 821;; The functions below work with the syntax class of the characters in an Ada 822;; buffer. Two syntax tables are created, depending on whether we want '_' 823;; to be considered as part of a word or not. 824;; Some characters may have multiple meanings depending on the context: 825;; - ' is either the beginning of a constant character or an attribute 826;; - # is either part of a based litteral or a gnatprep statement. 827;; - " starts a string, but not if inside a constant character. 828;; - ( and ) should be ignored if inside a constant character. 829;; Thus their syntax property is changed automatically, and we can still use 830;; the standard Emacs functions for sexp (see `ada-in-string-p') 831;; 832;; On Emacs, this is done through the `syntax-table' text property. The 833;; modification is done automatically each time the user as typed a new 834;; character. This is already done in `font-lock-mode' (in 835;; `font-lock-syntactic-keywords', so we take advantage of the existing 836;; mechanism. If font-lock-mode is not activated, we do it by hand in 837;; `ada-after-change-function', thanks to `ada-deactivate-properties' and 838;; `ada-initialize-properties'. 839;; 840;; on XEmacs, the `syntax-table' property does not exist and we have to use a 841;; slow advice to `parse-partial-sexp' to do the same thing. 842;; When executing parse-partial-sexp, we simply modify the strings before and 843;; after, so that the special constants '"', '(' and ')' do not interact 844;; with parse-partial-sexp. 845;; Note: this code is slow and needs to be rewritten as soon as something 846;; better is available on XEmacs. 847;;------------------------------------------------------------------------- 848 849(defun ada-create-syntax-table () 850 "Create the two syntax tables use in the Ada mode. 851The standard table declares `_' as a symbol constituent, the second one 852declares it as a word constituent." 853 (interactive) 854 (setq ada-mode-syntax-table (make-syntax-table)) 855 (set-syntax-table ada-mode-syntax-table) 856 857 ;; define string brackets (`%' is alternative string bracket, but 858 ;; almost never used as such and throws font-lock and indentation 859 ;; off the track.) 860 (modify-syntax-entry ?% "$" ada-mode-syntax-table) 861 (modify-syntax-entry ?\" "\"" ada-mode-syntax-table) 862 863 (modify-syntax-entry ?: "." ada-mode-syntax-table) 864 (modify-syntax-entry ?\; "." ada-mode-syntax-table) 865 (modify-syntax-entry ?& "." ada-mode-syntax-table) 866 (modify-syntax-entry ?\| "." ada-mode-syntax-table) 867 (modify-syntax-entry ?+ "." ada-mode-syntax-table) 868 (modify-syntax-entry ?* "." ada-mode-syntax-table) 869 (modify-syntax-entry ?/ "." ada-mode-syntax-table) 870 (modify-syntax-entry ?= "." ada-mode-syntax-table) 871 (modify-syntax-entry ?< "." ada-mode-syntax-table) 872 (modify-syntax-entry ?> "." ada-mode-syntax-table) 873 (modify-syntax-entry ?$ "." ada-mode-syntax-table) 874 (modify-syntax-entry ?\[ "." ada-mode-syntax-table) 875 (modify-syntax-entry ?\] "." ada-mode-syntax-table) 876 (modify-syntax-entry ?\{ "." ada-mode-syntax-table) 877 (modify-syntax-entry ?\} "." ada-mode-syntax-table) 878 (modify-syntax-entry ?. "." ada-mode-syntax-table) 879 (modify-syntax-entry ?\\ "." ada-mode-syntax-table) 880 (modify-syntax-entry ?\' "." ada-mode-syntax-table) 881 882 ;; a single hyphen is punctuation, but a double hyphen starts a comment 883 (modify-syntax-entry ?- ". 12" ada-mode-syntax-table) 884 885 ;; See the comment above on grammar related function for the special 886 ;; setup for '#'. 887 (if (featurep 'xemacs) 888 (modify-syntax-entry ?# "<" ada-mode-syntax-table) 889 (modify-syntax-entry ?# "$" ada-mode-syntax-table)) 890 891 ;; and \f and \n end a comment 892 (modify-syntax-entry ?\f "> " ada-mode-syntax-table) 893 (modify-syntax-entry ?\n "> " ada-mode-syntax-table) 894 895 ;; define what belongs in Ada symbols 896 (modify-syntax-entry ?_ "_" ada-mode-syntax-table) 897 898 ;; define parentheses to match 899 (modify-syntax-entry ?\( "()" ada-mode-syntax-table) 900 (modify-syntax-entry ?\) ")(" ada-mode-syntax-table) 901 902 (setq ada-mode-symbol-syntax-table (copy-syntax-table ada-mode-syntax-table)) 903 (modify-syntax-entry ?_ "w" ada-mode-symbol-syntax-table) 904 ) 905 906;; Support of special characters in XEmacs (see the comments at the beginning 907;; of the section on Grammar related functions). 908 909(if (featurep 'xemacs) 910 (defadvice parse-partial-sexp (around parse-partial-sexp-protect-constants) 911 "Handles special character constants and gnatprep statements." 912 (let (change) 913 (if (< to from) 914 (let ((tmp from)) 915 (setq from to to tmp))) 916 (save-excursion 917 (goto-char from) 918 (while (re-search-forward "'\\([(\")#]\\)'" to t) 919 (setq change (cons (list (match-beginning 1) 920 1 921 (match-string 1)) 922 change)) 923 (replace-match "'A'")) 924 (goto-char from) 925 (while (re-search-forward "\\(#[0-9a-fA-F]*#\\)" to t) 926 (setq change (cons (list (match-beginning 1) 927 (length (match-string 1)) 928 (match-string 1)) 929 change)) 930 (replace-match (make-string (length (match-string 1)) ?@)))) 931 ad-do-it 932 (save-excursion 933 (while change 934 (goto-char (caar change)) 935 (delete-char (cadar change)) 936 (insert (caddar change)) 937 (setq change (cdr change))))))) 938 939(defun ada-deactivate-properties () 940 "Deactivate Ada mode's properties handling. 941This would be a duplicate of font-lock if both are used at the same time." 942 (remove-hook 'after-change-functions 'ada-after-change-function t)) 943 944(defun ada-initialize-properties () 945 "Initialize some special text properties in the whole buffer. 946In particular, character constants are said to be strings, #...# are treated 947as numbers instead of gnatprep comments." 948 (save-excursion 949 (save-restriction 950 (widen) 951 (goto-char (point-min)) 952 (while (re-search-forward "'.'" nil t) 953 (add-text-properties (match-beginning 0) (match-end 0) 954 '(syntax-table ("'" . ?\")))) 955 (goto-char (point-min)) 956 (while (re-search-forward "^[ \t]*#" nil t) 957 (add-text-properties (match-beginning 0) (match-end 0) 958 '(syntax-table (11 . 10)))) 959 (set-buffer-modified-p nil) 960 961 ;; Setting this only if font-lock is not set won't work 962 ;; if the user activates or deactivates font-lock-mode, 963 ;; but will make things faster most of the time 964 (add-hook 'after-change-functions 'ada-after-change-function nil t) 965 ))) 966 967(defun ada-after-change-function (beg end old-len) 968 "Called when the region between BEG and END was changed in the buffer. 969OLD-LEN indicates what the length of the replaced text was." 970 (let ((inhibit-point-motion-hooks t) 971 (eol (point))) 972 (save-excursion 973 (save-match-data 974 (beginning-of-line) 975 (remove-text-properties (point) eol '(syntax-table nil)) 976 (while (re-search-forward "'.'" eol t) 977 (add-text-properties (match-beginning 0) (match-end 0) 978 '(syntax-table ("'" . ?\")))) 979 (beginning-of-line) 980 (if (looking-at "^[ \t]*#") 981 (add-text-properties (match-beginning 0) (match-end 0) 982 '(syntax-table (11 . 10)))))))) 983 984;;------------------------------------------------------------------ 985;; Testing the grammatical context 986;;------------------------------------------------------------------ 987 988(defsubst ada-in-comment-p (&optional parse-result) 989 "Return t if inside a comment. 990If PARSE-RESULT is non-nil, use it instead of calling `parse-partial-sexp'." 991 (nth 4 (or parse-result 992 (parse-partial-sexp 993 (line-beginning-position) (point))))) 994 995(defsubst ada-in-string-p (&optional parse-result) 996 "Return t if point is inside a string. 997If PARSE-RESULT is non-nil, use it instead of calling `parse-partial-sexp'." 998 (nth 3 (or parse-result 999 (parse-partial-sexp 1000 (line-beginning-position) (point))))) 1001 1002(defsubst ada-in-string-or-comment-p (&optional parse-result) 1003 "Return t if inside a comment or string. 1004If PARSE-RESULT is non-nil, use it instead of calling `parse-partial-sexp'." 1005 (setq parse-result (or parse-result 1006 (parse-partial-sexp 1007 (line-beginning-position) (point)))) 1008 (or (ada-in-string-p parse-result) (ada-in-comment-p parse-result))) 1009 1010 1011;;------------------------------------------------------------------ 1012;; Contextual menus 1013;; The Ada mode comes with contextual menus, bound by default to the right 1014;; mouse button. 1015;; Add items to this menu by modifying `ada-contextual-menu'. Note that the 1016;; variable `ada-contextual-menu-on-identifier' is set automatically to t 1017;; if the mouse button was pressed on an identifier. 1018;;------------------------------------------------------------------ 1019 1020(defun ada-call-from-contextual-menu (function) 1021 "Execute FUNCTION when called from the contextual menu. 1022It forces Emacs to change the cursor position." 1023 (interactive) 1024 (funcall function) 1025 (setq ada-contextual-menu-last-point 1026 (list (point) (current-buffer)))) 1027 1028(defun ada-popup-menu (position) 1029 "Pops up a contextual menu, depending on where the user clicked. 1030POSITION is the location the mouse was clicked on. 1031Sets `ada-contextual-menu-last-point' to the current position before 1032displaying the menu. When a function from the menu is called, the 1033point is where the mouse button was clicked." 1034 (interactive "e") 1035 1036 ;; declare this as a local variable, so that the function called 1037 ;; in the contextual menu does not hide the region in 1038 ;; transient-mark-mode. 1039 (let ((deactivate-mark nil)) 1040 (setq ada-contextual-menu-last-point 1041 (list (point) (current-buffer))) 1042 (mouse-set-point last-input-event) 1043 1044 (setq ada-contextual-menu-on-identifier 1045 (and (char-after) 1046 (or (= (char-syntax (char-after)) ?w) 1047 (= (char-after) ?_)) 1048 (not (ada-in-string-or-comment-p)) 1049 (save-excursion (skip-syntax-forward "w") 1050 (not (ada-after-keyword-p))) 1051 )) 1052 (if (fboundp 'popup-menu) 1053 (funcall (symbol-function 'popup-menu) ada-contextual-menu) 1054 (let (choice) 1055 (setq choice (x-popup-menu position ada-contextual-menu)) 1056 (if choice 1057 (funcall (lookup-key ada-contextual-menu (vector (car choice))))))) 1058 1059 (set-buffer (cadr ada-contextual-menu-last-point)) 1060 (goto-char (car ada-contextual-menu-last-point)) 1061 )) 1062 1063 1064;;------------------------------------------------------------------ 1065;; Misc functions 1066;;------------------------------------------------------------------ 1067 1068;;;###autoload 1069(defun ada-add-extensions (spec body) 1070 "Define SPEC and BODY as being valid extensions for Ada files. 1071Going from body to spec with `ff-find-other-file' used these 1072extensions. 1073SPEC and BODY are two regular expressions that must match against 1074the file name." 1075 (let* ((reg (concat (regexp-quote body) "$")) 1076 (tmp (assoc reg ada-other-file-alist))) 1077 (if tmp 1078 (setcdr tmp (list (cons spec (cadr tmp)))) 1079 (add-to-list 'ada-other-file-alist (list reg (list spec))))) 1080 1081 (let* ((reg (concat (regexp-quote spec) "$")) 1082 (tmp (assoc reg ada-other-file-alist))) 1083 (if tmp 1084 (setcdr tmp (list (cons body (cadr tmp)))) 1085 (add-to-list 'ada-other-file-alist (list reg (list body))))) 1086 1087 (add-to-list 'auto-mode-alist 1088 (cons (concat (regexp-quote spec) "\\'") 'ada-mode)) 1089 (add-to-list 'auto-mode-alist 1090 (cons (concat (regexp-quote body) "\\'") 'ada-mode)) 1091 1092 (add-to-list 'ada-spec-suffixes spec) 1093 (add-to-list 'ada-body-suffixes body) 1094 1095 ;; Support for speedbar (Specifies that we want to see these files in 1096 ;; speedbar) 1097 (if (fboundp 'speedbar-add-supported-extension) 1098 (progn 1099 (funcall (symbol-function 'speedbar-add-supported-extension) 1100 spec) 1101 (funcall (symbol-function 'speedbar-add-supported-extension) 1102 body))) 1103 ) 1104 1105 1106;;;###autoload 1107(defun ada-mode () 1108 "Ada mode is the major mode for editing Ada code. 1109 1110Bindings are as follows: (Note: 'LFD' is control-j.) 1111\\{ada-mode-map} 1112 1113 Indent line '\\[ada-tab]' 1114 Indent line, insert newline and indent the new line. '\\[newline-and-indent]' 1115 1116 Re-format the parameter-list point is in '\\[ada-format-paramlist]' 1117 Indent all lines in region '\\[ada-indent-region]' 1118 1119 Adjust case of identifiers and keywords in region '\\[ada-adjust-case-region]' 1120 Adjust case of identifiers and keywords in buffer '\\[ada-adjust-case-buffer]' 1121 1122 Fill comment paragraph, justify and append postfix '\\[fill-paragraph]' 1123 1124 Next func/proc/task '\\[ada-next-procedure]' Previous func/proc/task '\\[ada-previous-procedure]' 1125 Next package '\\[ada-next-package]' Previous package '\\[ada-previous-package]' 1126 1127 Goto matching start of current 'end ...;' '\\[ada-move-to-start]' 1128 Goto end of current block '\\[ada-move-to-end]' 1129 1130Comments are handled using standard GNU Emacs conventions, including: 1131 Start a comment '\\[indent-for-comment]' 1132 Comment region '\\[comment-region]' 1133 Uncomment region '\\[ada-uncomment-region]' 1134 Continue comment on next line '\\[indent-new-comment-line]' 1135 1136If you use imenu.el: 1137 Display index-menu of functions and procedures '\\[imenu]' 1138 1139If you use find-file.el: 1140 Switch to other file (Body <-> Spec) '\\[ff-find-other-file]' 1141 or '\\[ff-mouse-find-other-file] 1142 Switch to other file in other window '\\[ada-ff-other-window]' 1143 or '\\[ff-mouse-find-other-file-other-window] 1144 If you use this function in a spec and no body is available, it gets created with body stubs. 1145 1146If you use ada-xref.el: 1147 Goto declaration: '\\[ada-point-and-xref]' on the identifier 1148 or '\\[ada-goto-declaration]' with point on the identifier 1149 Complete identifier: '\\[ada-complete-identifier]'." 1150 1151 (interactive) 1152 (kill-all-local-variables) 1153 1154 (set (make-local-variable 'require-final-newline) mode-require-final-newline) 1155 1156 ;; Set the paragraph delimiters so that one can select a whole block 1157 ;; simply with M-h 1158 (set (make-local-variable 'paragraph-start) "[ \t\n\f]*$") 1159 (set (make-local-variable 'paragraph-separate) "[ \t\n\f]*$") 1160 1161 ;; comment end must be set because it may hold a wrong value if 1162 ;; this buffer had been in another mode before. RE 1163 (set (make-local-variable 'comment-end) "") 1164 1165 ;; used by autofill and indent-new-comment-line 1166 (set (make-local-variable 'comment-start-skip) "---*[ \t]*") 1167 1168 ;; used by autofill to break a comment line and continue it on another line. 1169 ;; The reason we need this one is that the default behavior does not work 1170 ;; correctly with the definition of paragraph-start above when the comment 1171 ;; is right after a multi-line subprogram declaration (the comments are 1172 ;; aligned under the latest parameter, not under the declaration start). 1173 (set (make-local-variable 'comment-line-break-function) 1174 (lambda (&optional soft) (let ((fill-prefix nil)) 1175 (indent-new-comment-line soft)))) 1176 1177 (set (make-local-variable 'indent-line-function) 1178 'ada-indent-current-function) 1179 1180 (set (make-local-variable 'comment-column) 40) 1181 1182 ;; Emacs 20.3 defines a comment-padding to insert spaces between 1183 ;; the comment and the text. We do not want any, this is already 1184 ;; included in comment-start 1185 (unless (featurep 'xemacs) 1186 (progn 1187 (if (ada-check-emacs-version 20 3) 1188 (progn 1189 (set (make-local-variable 'parse-sexp-ignore-comments) t) 1190 (set (make-local-variable 'comment-padding) 0))) 1191 (set (make-local-variable 'parse-sexp-lookup-properties) t) 1192 )) 1193 1194 (set 'case-fold-search t) 1195 (if (boundp 'imenu-case-fold-search) 1196 (set 'imenu-case-fold-search t)) 1197 1198 (set (make-local-variable 'fill-paragraph-function) 1199 'ada-fill-comment-paragraph) 1200 1201 (set (make-local-variable 'imenu-generic-expression) 1202 ada-imenu-generic-expression) 1203 1204 ;; Support for compile.el 1205 ;; We just substitute our own functions to go to the error. 1206 (add-hook 'compilation-mode-hook 1207 (lambda() 1208 (set (make-local-variable 'compile-auto-highlight) 40) 1209 ;; FIXME: This has global impact! -stef 1210 (define-key compilation-minor-mode-map [mouse-2] 1211 'ada-compile-mouse-goto-error) 1212 (define-key compilation-minor-mode-map "\C-c\C-c" 1213 'ada-compile-goto-error) 1214 (define-key compilation-minor-mode-map "\C-m" 1215 'ada-compile-goto-error))) 1216 1217 ;; font-lock support : 1218 ;; We need to set some properties for XEmacs, and define some variables 1219 ;; for Emacs 1220 1221 (if (featurep 'xemacs) 1222 ;; XEmacs 1223 (put 'ada-mode 'font-lock-defaults 1224 '(ada-font-lock-keywords 1225 nil t ((?\_ . "w") (?# . ".")) beginning-of-line)) 1226 ;; Emacs 1227 (set (make-local-variable 'font-lock-defaults) 1228 '(ada-font-lock-keywords 1229 nil t 1230 ((?\_ . "w") (?# . ".")) 1231 beginning-of-line 1232 (font-lock-syntactic-keywords . ada-font-lock-syntactic-keywords))) 1233 ) 1234 1235 ;; Set up support for find-file.el. 1236 (set (make-local-variable 'ff-other-file-alist) 1237 'ada-other-file-alist) 1238 (set (make-local-variable 'ff-search-directories) 1239 'ada-search-directories-internal) 1240 (setq ff-post-load-hook 'ada-set-point-accordingly 1241 ff-file-created-hook 'ada-make-body) 1242 (add-hook 'ff-pre-load-hook 'ada-which-function-are-we-in) 1243 1244 (make-local-variable 'ff-special-constructs) 1245 (mapc (lambda (pair) (add-to-list 'ff-special-constructs pair)) 1246 (list 1247 ;; Top level child package declaration; go to the parent package. 1248 (cons (eval-when-compile 1249 (concat "^\\(private[ \t]\\)?[ \t]*package[ \t]+" 1250 "\\(body[ \t]+\\)?" 1251 "\\(\\(\\sw\\|[_.]\\)+\\)\\.\\(\\sw\\|_\\)+[ \t\n]+is")) 1252 (lambda () 1253 (ff-get-file 1254 ada-search-directories-internal 1255 (ada-make-filename-from-adaname (match-string 3)) 1256 ada-spec-suffixes))) 1257 1258 ;; A "separate" clause. 1259 (cons "^separate[ \t\n]*(\\(\\(\\sw\\|[_.]\\)+\\))" 1260 (lambda () 1261 (ff-get-file 1262 ada-search-directories-internal 1263 (ada-make-filename-from-adaname (match-string 1)) 1264 ada-spec-suffixes))) 1265 1266 ;; A "with" clause. 1267 (cons "^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)" 1268 (lambda () 1269 (ff-get-file 1270 ada-search-directories-internal 1271 (ada-make-filename-from-adaname (match-string 1)) 1272 ada-spec-suffixes))) 1273 )) 1274 1275 ;; Support for outline-minor-mode 1276 (set (make-local-variable 'outline-regexp) 1277 "\\([ \t]*\\(procedure\\|function\\|package\\|if\\|while\\|for\\|declare\\|case\\|end\\|begin\\|loop\\)\\|--\\)") 1278 (set (make-local-variable 'outline-level) 'ada-outline-level) 1279 1280 ;; Support for imenu : We want a sorted index 1281 (setq imenu-sort-function 'imenu--sort-by-name) 1282 1283 ;; Support for ispell : Check only comments 1284 (set (make-local-variable 'ispell-check-comments) 'exclusive) 1285 1286 ;; Support for align 1287 (add-to-list 'align-dq-string-modes 'ada-mode) 1288 (add-to-list 'align-open-comment-modes 'ada-mode) 1289 (set (make-local-variable 'align-region-separate) ada-align-region-separate) 1290 1291 ;; Exclude comments alone on line from alignment. 1292 (add-to-list 'align-exclude-rules-list 1293 '(ada-solo-comment 1294 (regexp . "^\\(\\s-*\\)--") 1295 (modes . '(ada-mode)))) 1296 (add-to-list 'align-exclude-rules-list 1297 '(ada-solo-use 1298 (regexp . "^\\(\\s-*\\)\\