Copyright © 1999 - 2014  Free Software Foundation, Inc.

     Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover texts being ``A GNU Manual'', and with the Back-Cover Texts as in (a) below.  A copy of the license is included in the section entitled ``GNU Free Documentation License''.

     (a) The FSF's Back-Cover Text is: ``You have the freedom to copy and modify this GNU manual.  Buying copies from the FSF supports it in developing GNU and promoting software freedom.''

Overview
********

The Emacs mode for programming in Ada helps the user in reading existing code and facilitates developing new code.

Cross-reference information output by the compiler is used to provide powerful code navigation (jump to definition, find all uses, etc).

When you open a file with a file extension of .ads or .adb, Emacs will automatically load and activate Ada mode.

Ada mode works without any customization, if you are using the GNAT compiler (https://libre2.adacore.com/) and the GNAT default naming convention.

You must customize a few things if you are using a different file naming convention or compiler; see Non-standard file names, see Other compiler.

In addition, you may want to customize the indentation, capitalization, and other things; see Other customization.

Finally, for large Ada projects, you will want to set up an Emacs Ada mode project file for each project; see Project files. Note that these are different from the GNAT project files used by the GNAT tools.

See Debuggers (Emacs User Guide), for general information on debugging.

Installation
************

Ada mode requires Emacs 24.2 or greater; it also requires the Emacs lisp sources (not just the compiled binaries).

Ada mode is distributed in the Gnu ELPA package archive; it can be installed via M-x list-packages (see Packages (Emacs User Guide)). You must first enable packages in your ~/.emacs, after customizing Info-default-directory-list (if you do that):

     (package-initialize)

Ada mode is also available as a separate distribution, from the Emacs Ada mode website http://stephe-leake.org/emacs/ada-mode/emacs-ada-mode.html.

For installing the separate distribution, see the README file in the distribution.

To see what version of Ada mode you have installed, invoke M-x ada-mode-version.

gnatinspect
===========

Ada mode has experimental support for the new AdaCore cross reference tool gnatinspect, which supports Ada, C, C++, and any other language for which gcc provices the -fdump-xref.

gnatinspect is distributed as part of gnatcoll. Ada mode requires the very latest version, in gnatcoll 1.7w distributed with GNAT GPL 2014.

To build gnatinspect, assuming GNAT GPL 2014 is installed in /usr/gnat-gpl-2014, and /usr/gnat-gpl-2014/bin is in PATH:

     tar xf ~/Downloads/gnatcoll-1.7x-src.tgz
     cd gnatcoll-1.7w-src
     ./configure --prefix=/usr/gnat-gpl-2014
     make Gnatcoll_Build=Debug
     sudo make Gnatcoll_Build=Debug install

To build an sqlite3 executable that is compatible with the database created by gnatinspect:

     cd gnatcoll-1.7w-src/src/sqlite/amalgamation/
     gcc -O2 -o sqlite3 shell.c sqlite3.c -ldl -lpthread

Upgrading from previous versions
================================

See the file NEWS for more details; here we summarize only important user interface changes.

from 5.0.1
     Nothing to do.

from 4.01
     There are many user interface and API changes between 4.01 and 5.0.1; we only document those that may be hard to diagnose here.

     prog-mode-hook is no longer run by ada-mode; ada-mode is no longer derived from prog-mode. Use ada-mode-hook instead.

Customizing Ada mode
********************

Here we assume you are familiar with setting variables in Emacs, either thru 'customize' or in elisp (in your .emacs file). For a basic introduction to customize, elisp, and Emacs in general, see the tutorial (C-h t).

Non-standard file names
=======================

By default, Ada mode is configured to use the GNAT file naming convention, where file names are a simple modification of the Ada names, and the extension for specs and bodies are .ads and .adb, respectively.

Emacs uses the file extension to enable Ada mode; Ada mode uses the file extentions to allow moving from a package body to the corresponding spec and back.

Emacs and Ada mode support ways to use alternative file extensions for specs and bodies. Note that you must also tell the compiler about these extensions; doing that is beyond the scope of this manual.

For instance, if your spec and bodies files are called UNIT_s.ada and UNIT_b.ada, respectively, you can add the following to your .emacs file:

     ;; Tell Ada mode about spec and body extensions
     (ada-add-extensions "_s.ada" "_b.ada")

     ;; Tell Emacs to use Ada mode for those extensions
     (add-to-list 'auto-mode-alist '("\\.ada\\'" . ada-mode))

You can define additional extensions:

     (ada-add-extensions ".ads" "_b.ada")
     (ada-add-extensions ".ads" ".body")

This means that whenever Ada mode looks for the body for a file whose extension is .ads, it will take the first available file that ends with either .adb, _b.ada or .body.

Simililarly, if Ada mode is looking for a spec, it will look for .ads or _s.ada.

If the filename excluding the extension is not derived from the Ada name following the GNAT convention, you need to provide an alternate function for ada-file-name-from-ada-name. Doing that is beyond the scope of this manual; see the current definitions in ada-mode.el and ada-gnat-xref.el for examples.

Other compiler
==============

The project variable ada_compiler (default elisp variable ada-compiler) is used to index several variables that point to the compiler-specific functions for corresponding Ada mode operations.

To use a compiler other than GNAT, you must write Emacs lisp code that provides the interface to the compiler, and set ada-compiler and the indirection variables.

See ada-gnat-compile.el for an example.

Other cross-reference
=====================

The project variable ada_xref (default elisp variable ada-xref-tool) is used to index several variables that point to the cross-reference-tool-specific functions for corresponding Ada mode operations.

To use a cross reference tool other than gnatxref, you must write Emacs lisp code that provides the interface to the compiler, and set ada-xref-tool and the indirection variables. This has already been done for gnatinspect; set ada-xref-tool to 'gnat_inspect.

See ada-gnat-xref.el and gnat-inspect.el for examples.

Other customization
===================

All user-settable Ada mode variables can be set via the menu Ada | Customize.  Click on the Help button there for help on using customize.

To modify a specific variable, you can directly call the function customize-variable; just type M-x customize-variable RET VARIABLE-NAME RET).

Alternately, you can specify variable settings in the Emacs configuration file, ~/.emacs. This file is coded in Emacs lisp, and the syntax to set a variable is the following:

     (setq variable-name value)

Some general Emacs settings that are useful for Ada files:

delete-trailing-whitespace
     Deletes space, tab at end of line and blank lines at end of buffer.

untabify
     Deletes tab characters that have crept into the file.

indent-tabs-mode
     Don't insert tab characters when indenting.

copyright-update
     Updates the copyright date in the file header comment, to the current year.

electric-pair-mode
     Insert a matching right paren when you type a left paren.

hippie-expand
     Bind hippie-expand to a key; it expands the word before point, using words from current buffer, other buffers, file names, etc; see hippie-expand-try-functions-list. You can also add ada-skel-hippie-try to that list. Note that ada-expand, which defaults to ada-skel-expand, is bound to C-c C-e (see Statement skeletons).

imenu

which-func

The above can all be set by the following code in your ~/.emacs. Note that some are functions are added to before-save-hook; they run just before a buffer is written to disk. Also, the order is important; ada-mode does not set up the Ada-specific features of imenu and which-func unless they are loaded first.

     (setq-default indent-tabs-mode nil)
     (electric-pair-mode 1)
     (require 'imenu)
     (require 'which-func)
     (require 'ada-mode)
     (add-to-list 'hippie-expand-try-functions-list 'ada-skel-hippie-try)
     (define-key ada-mode-map "\C-e"     'hippie-expand)
     (add-hook 'ada-mode-hook
        (lambda ()
         (add-hook 'before-save-hook 'delete-trailing-whitespace nil t)
         (add-hook 'before-save-hook 'copyright-update nil t)
         (add-hook 'before-save-hook
                   (lambda () (untabify (point-min) (point-max)))
                    nil t)))

Compiling Executing
*******************

Ada projects can be compiled, linked, and executed using commands on the Ada menu. All of these commands can be customized via a project file (see Project files), but the defaults are sufficient for using the GNAT compiler for simple projects (single files, or several files in a single directory).

For complex projects, you will want to use make or some other build tool; in that case, you will need an Emacs Ada mode project file to tell Emacs about the project directory tree and other settings.

Compile commands
================

Here are the commands for building an Ada project and running the main program.

In multi-file projects, there must be one file that is the main program. That is given by the main project file variable; it defaults to the current file if not yet set, but is also set by the ``set main and build'' command.

Check file
     Compiles the current file in syntax check mode, by running check_cmd defined in the current project file. This typically runs faster than full compile mode, speeding up finding and fixing compilation errors.

     This sets main only if it has not been set yet.

Compile file
     Compiles the current file, by running comp_cmd from the current project file.

     This does not set main.

Set main and Build
     Sets main to the current file, then executes the Build command.

Show main
     Display main in the message buffer.

Build
     Compiles all obsolete units of the current main, and links main, by running make_cmd from the current project.

     This sets main only if it has not been set yet.

Run
     Executes the main program in a shell, displayed in a separate Emacs buffer. This runs run_cmd from the current project. The execution buffer allows for interactive input/output.

     To modify the run command, in particular to provide or change the command line arguments, type C-u before invoking the command.

     This command is not available for a cross-compilation toolchain.

It is important when using these commands to understand how main is used and changed.

Build runs 'gnatmake' on the main unit. During a typical edit/compile session, this is the only command you need to invoke, which is why it is bound to C-c C-c. It will compile all files needed by the main unit, and display compilation errors in any of them.

Note that Build can be invoked from any Ada buffer; typically you will be fixing errors in files other than the main, but you don't have to switch back to the main to invoke the compiler again.

Novices and students typically work on single-file Ada projects. In this case, C-c C-m will normally be the only command needed; it will build the current file, rather than the last-built main.

There are three ways to change main:

 1. Invoke Ada | Set main and Build, which sets main to the current file.

 2. Invoke Ada | Project | Edit, edit main and main, and click [save]

 3. Invoke Ada | Project | Load, and load a project file that specifies main

Compiling Examples
==================

We present several small projects, and walk thru the process of compiling, linking, and running them.

The first example illustrates more Ada mode features than the others; you should work thru that example before doing the others.

All of these examples assume you are using GNAT.

The source for these examples is available on the Emacs Ada mode website mentioned in see Installation.

No project files
----------------

This example uses no project files.

First, create a directory Example_1, containing:

hello.adb:

     with Ada.Text_IO;
     procedure Hello
     is begin
        Put_Line("Hello from hello.adb");
     end Hello;

Yes, this is missing ``use Ada.Text_IO;'' - we want to demonstrate compiler error handling.

hello_2.adb has no errors:

     with Hello_Pkg;
     procedure Hello_2
     is begin
        Hello_Pkg.Say_Hello;
     end Hello_2;

hello_pkg.ads has no errors:

     package Hello_Pkg is
        procedure Say_Hello;
     end Hello_Pkg;

hello_pkg.adb:

     with Ada.Text_IO;
     package Hello_Pkg is
        procedure Say_Hello
        is begin
           Ada.Text_IO.Put_Line ("Hello from hello_pkg.adb");
        end Say_Hello;
     end Hello_Pkg;

Yes, this is missing the keyword body; another compiler error example. However, note that the indentation engine parser accepts this code with no errors, making it easier to indent slightly illegal Ada code.

In buffer hello.adb, invoke the menu entry Ada | Build | Check syntax. You should get a *compilation* buffer containing something like (the directory paths will be different):

     -*- mode: compilation; default-directory: "c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_1/" -*-
     Compilation started at Fri Oct 18 04:23:54

     gnatmake -u -c -gnatc  c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_1/hello.adb -cargs
     gcc -c -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_1/ -gnatc -I- c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_1/hello.adb
     hello.adb:4:04: "Put_Line" is not visible
     hello.adb:4:04: non-visible declaration at a-textio.ads:263
     hello.adb:4:04: non-visible declaration at a-textio.ads:259
     gnatmake: "c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_1/hello.adb" compilation error

     Compilation exited abnormally with code 4 at Fri Oct 18 04:23:54

The lines with actual errors (starting with hello.adb) are highlighted, with the file name in red.

Now invoke Ada | Build | Next compilation error.  Or you can click the middle mouse button on the first error line, or use the key binding shown on the menu.  The compilation buffer scrolls to put the first error on the top line, and point is put at the place of the error in the hello.adb buffer.

To fix the error, invoke Ada | Build | Fix compilation error; this adds ``Ada.Text_Io.'' to the line:

         Ada.Text_Io.Put_Line ("hello from hello.adb");

Now invoke Ada | Build | Show main; this displays Ada mode main: hello.

Now (in buffer hello.adb), invoke Ada | Build | Build. You are prompted to save the file (if you haven't already). Then the compilation buffer is displayed again, containing:

     -*- mode: compilation; default-directory: "c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_1/" -*-
     Compilation started at Fri Oct 18 20:39:33

     gnatmake -o hello hello  -cargs  -bargs  -largs
     gcc -c hello.adb
     gnatbind -x hello.ali
     gnatlink hello.ali -o hello.exe

     Compilation finished at Fri Oct 18 20:39:34

The compilation has succeeded without errors; hello.exe now exists in the same directory as hello.adb.

Now invoke Ada | Build | Run. The *compilation* buffer is displayed, containing

     -*- mode: compilation; default-directory: "c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_1/" -*-
     Compilation started at Fri Oct 18 20:41:53

     ./hello
     Hello from hello.adb

     Compilation finished at Fri Oct 18 20:41:53

That completes the first part of this example.

Now we will compile a multi-file project. Open the file hello_2.adb, invoke Ada | Build | Set main and Build. This finds an error in hello_pkg.adb:

     hello_pkg.adb:2:08: keyword "body" expected here [see file name]

This demonstrates that gnatmake finds the files needed by the main program. However, it cannot find files in a different directory, unless you use an Emacs Ada mode project file or a GNAT project file to specify the other directories; see Set source search path, Use GNAT project file.

Invoke Ada | Build | Show main; this displays Ada mode main: hello_2.

Move to the error with C-x `, and fix the error by adding body:

     package body Hello_Pkg is

Now, while still in hello_pkg.adb, invoke Ada | Build | Build.  gnatmake successfully builds hello_2. This demonstrates that Emacs has remembered the main file, in the project variable main, and used it for the Build command.

Finally, again while in hello_pkg.adb, invoke Ada | Build | Run.  The *compilation* buffer displays Hello from hello_pkg.adb.

One final point. If you switch back to buffer hello.adb, and
invoke Ada | Build | Run, hello_2.exe will be run. That
is because main is still set to hello_2, as you can see
when you invoke Ada | Build | Show main.

There are two ways to change main:

 1. Invoke Ada | Build | Set main and Build, which sets main to the current file.

 2. Invoke Ada | Build | Set Project ..., and select a project file that specifies main.

Set compiler options
--------------------

This example illustrates using an Emacs Ada mode project file to set a compiler option.

If you have files from Example_1 open in Emacs, you should close them so you don't get confused. Use menu File | Close (current buffer).

In directory Example_2, create these files:

hello.adb:

     with Ada.Text_IO;
     procedure Hello
     is begin
        Put_Line("Hello from hello.adb");
     end Hello;

This is the same as hello.adb from Example_1. It has two errors; missing ``use Ada.Text_IO;'', and no space between Put_Line and its argument list.

hello.adp:

     comp_opt=-gnatyt

This tells the GNAT compiler to check for token spacing; in particular, there must be a space preceding a parenthesis.

In buffer hello.adb, invoke Ada | Build | Set main and Build. This finds the project file hello.adp, uses it to set the compiler options, and builds the project. You should get a *compilation* buffer containing something like (the directory paths will be different):

     cd c:/Examples/Example_2/
     gnatmake -o hello hello -g -cargs -gnatyt  -bargs  -largs
     gcc -c -g -gnatyt hello.adb
     hello.adb:4:04: "Put_Line" is not visible
     hello.adb:4:04: non-visible declaration at a-textio.ads:264
     hello.adb:4:04: non-visible declaration at a-textio.ads:260
     hello.adb:4:12: (style) space required
     gnatmake: "hello.adb" compilation error

Compare this to the compiler output in No project files; the gnatmake option -cargs has been replaced by -cargs -gnaty, and an additional error is reported in hello.adb on line 4. This shows that hello.adp is being used to set the compiler options.

Fixing the error, linking and running the code proceed as in No project files.

Set source search path
----------------------

In this example, we show how to deal with files in more than one directory, using an Emacs Ada mode project file to set the search path.

Create the directory Example_3, containing:

hello_pkg.ads:

     package Hello_Pkg is
        procedure Say_Hello;
     end Hello_Pkg;

hello_pkg.adb:

     with Ada.Text_IO;
     package Hello_Pkg is
        procedure Say_Hello
        is begin
           Ada.Text_IO.Put_Line ("Hello from hello_pkg.adb");
        end Say_Hello;
     end Hello_Pkg;

These are the same files from example 1; hello_pkg.adb has an error on line 2.

In addition, create a directory Example_3/Other, containing these files:

Other/hello_3.adb:

     with Hello_Pkg;
     with Ada.Text_IO; use Ada.Text_IO;
     procedure Hello_3
     is begin
        Hello_Pkg.Say_Hello;
        Put_Line ("From hello_3");
     end Hello_3;

There are no errors in this file.

Other/other.adp:

     src_dir=..

Note that there must be no trailing spaces.

In buffer hello_3.adb, invoke Ada | Project files | Find and set project..., and select Example_3/Other/other.adp. This tells Emacs Ada mode to stop using the project file from Example_2, and use the one for Example_3. Also note that since this project file is not named hello_3.adp, it would not be found by default.

Then, again in hello_3.adb, invoke Ada | Set main and Build. You should get a *compilation* buffer containing something like (the directory paths will be different):

     cd c:/Examples/Example_3/Other/
     gnatmake -o hello_3 hello_3 -g -cargs -I.. -bargs  -largs
     gcc -c -g -I.. hello_3.adb
     gcc -c -I./ -g -I.. -I- C:\Examples\Example_3\hello_pkg.adb
     hello_pkg.adb:2:08: keyword "body" expected here [see file name]
     gnatmake: "C:\Examples\Example_3\hello_pkg.adb" compilation error

Compare the -cargs option to the compiler output in Set compiler options; this shows that other.adp is being used to set the compiler options.

Move to the error with C-x `. Ada mode searches the list of directories given by src_dir for the file mentioned in the compiler error message.

Fixing the error, linking and running the code proceed as in No project files.

Use GNAT project file
---------------------

In this example, we show how to use a GNAT project file, with no Ada mode project file.

Create the directory Example_4, containing:

hello_pkg.ads:

     package Hello_Pkg is
        procedure Say_Hello;
     end Hello_Pkg;

hello_pkg.adb:

     with Ada.Text_IO;
     package Hello_Pkg is
        procedure Say_Hello
        is begin
           Ada.Text_IO.Put_Line ("Hello from hello_pkg.adb");
        end Say_Hello;
     end Hello_Pkg;

These are the same files from example 1; hello_pkg.adb has an error on line 2.

In addition, create a directory Example_4/Gnat_Project, containing these files:

Gnat_Project/hello_4.adb:

     with Hello_Pkg;
     with Ada.Text_IO; use Ada.Text_IO;
     procedure Hello_4
     is begin
        Hello_Pkg.Say_Hello;
        Put_Line ("From hello_4");
     end Hello_4;

There are no errors in this file.

Gnat_Project/hello_4.gpr:

     project Hello_4 is
        for Source_Dirs use (".", "..");
     end Hello_4;

In buffer hello_4.adb, invoke Ada | Project | Load..., and select Example_4/Gnat_Project/hello_4.gpr.

Then, again in hello_4.adb, invoke Ada | Set main and Build. You should get a *compilation* buffer containing something like (the directory paths will be different):

     -*- mode: compilation; default-directory: "c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4/Gnat_Project/" -*-
     Compilation started at Mon Oct 21 11:28:31

     gnatmake -Pc:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4/Gnat_Project/hello_4.gpr -o hello_4 hello_4  -cargs -I. -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4/Gnat_Project -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4 -Ic:/Apps/GNAT-7.1.2/lib/gcc/i686-pc-mingw32/4.7.3/adainclude  -bargs  -largs
     gcc -c -I. -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4/Gnat_Project -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4 -Ic:/Apps/GNAT-7.1.2/lib/gcc/i686-pc-mingw32/4.7.3/adainclude -I- -gnatA C:\Projects\org.emacs.ada-mode.stephe-1\test\Example_4\hello_pkg.adb
     hello_pkg.adb:2:08: keyword "body" expected here [see file name]
     gnatmake: "C:\Projects\org.emacs.ada-mode.stephe-1\test\Example_4\hello_pkg.adb" compilation error

     Compilation exited abnormally with code 4 at Mon Oct 21 11:28:31

Compare the gcc options to the compiler output in Set compiler options; this shows that hello_4.gpr is being used to set the compiler options.

Fixing the error, linking and running the code proceed as in No project files.

Use multiple GNAT project files
-------------------------------

In this example, we show how to use multiple GNAT project files, specifying the GNAT project search path in an Ada mode project file.

Create the directory Example_4 as specified in Use GNAT project file.

Create the directory Example_5, containing:

hello_5.adb:

     with Hello_Pkg;
     with Ada.Text_IO; use Ada.Text_IO;
     procedure Hello_5
     is begin
        Hello_Pkg.Say_Hello;
        Put_Line ("From hello_5");
     end Hello_5;

There are no errors in this file.

hello_5.adp:

     ada_project_path=../Example_4/Gnat_Project
     gpr_file=hello_5.gpr

hello_5.gpr:

     with "hello_4";
     project Hello_5 is
        for Source_Dirs use (".");
        package Compiler is
           for Default_Switches ("Ada") use ("-g", "-gnatyt");
        end Compiler;
     end Hello_5;

In buffer hello_5.adb, invoke Ada | Project | Find and select project..., and select Example_5/hello_5.adp. This would also be found by default if no previous project file had been selected.

Then, again in hello_5.adb, invoke Ada | Build | Set main and Build. You should get a *compilation* buffer containing something like (the directory paths will be different):

     -*- mode: compilation; default-directory: "c:/Projects/org.emacs.ada-mode.stephe-1/test/Example_5/" -*-
     Compilation started at Mon Oct 21 11:32:05

     gnatmake -Pc:/Projects/org.emacs.ada-mode.stephe-1/test/Example_5/hello_5.gpr -o hello_5 hello_5  -cargs -I. -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_5 -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4/Gnat_Project -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4 -Ic:/Apps/GNAT-7.1.2/lib/gcc/i686-pc-mingw32/4.7.3/adainclude  -bargs  -largs
     gcc -c -I. -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_5 -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4/Gnat_Project -Ic:/Projects/org.emacs.ada-mode.stephe-1/test/Example_4 -Ic:/Apps/GNAT-7.1.2/lib/gcc/i686-pc-mingw32/4.7.3/adainclude -I- -gnatA C:\Projects\org.emacs.ada-mode.stephe-1\test\Example_4\hello_pkg.adb
     hello_pkg.adb:2:08: keyword "body" expected here [see file name]
     gnatmake: "C:\Projects\org.emacs.ada-mode.stephe-1\test\Example_4\hello_pkg.adb" compilation error

     Compilation exited abnormally with code 4 at Mon Oct 21 11:32:05

Now type C-x `. Example_4/hello_pkg.adb is shown, demonstrating that hello_5.gpr and hello_4.gpr are being used to set the compilation search path.

Use a Makefile
--------------

In this example, we show how to use a Makefile to build an Ada project with GNAT, run the result, and clean the build directories.

Create the directories Example_4, Example_5 as specified in Use GNAT project file,  Use multiple GNAT project files.

In Example_5, add the file:

Makefile:

     # build and run hello_5 project

     all : build run

     .PHONY : force

     build : force
             gprbuild -Phello_5.gpr hello_5

     run :
             ./hello_5

     clean :
             gnatclean -r -Phello_5

     export GPR_PROJECT_PATH = ../Example_4/Gnat_Project

     # Local Variables:
     # eval:(ada-parse-prj-file "hello_5.adp")
     # eval:(ada-select-prj-file "hello_5.adp")
     # End:

Close and re-open Makefile; the Local Variables section sets the project file to hello_5.adp when the Makefile is opened. You can also use C-x C-e to execute the select line after the Makefile is opened, to change the project file back to hello_5.adp.

In Makefile, invoke Tools | Compile..., and accept the default make command. This runs the all target, which builds hello_5 and runs it.

Compiler errors
===============

The Check syntax and Build commands, or running make, place compilation errors in a separate buffer named *compilation*.

Each line in this buffer will become active: you can simply click on it with the middle button of the mouse, or move point to it and press RET. Emacs will then display the relevant source file and put point on the line and column where the error was found.

You can also press the C-x ` key (next-error), and Emacs will jump to the first error. If you press that key again, it will move you to the second error, and so on.

Some error messages also include references to other files. These references are accessed via C-c `.

Project files
*************

An Emacs Ada mode project file specifies what directories hold sources for your project, and allows you to customize the compilation commands and other things on a per-project basis.

The default file extension for Ada mode project files is *.adp or *.prj. You can use a different extension by adding it to ada-prj-file-extensions, and a different syntax by adding a parser function to ada-prj-parser-alist.

Note that Ada mode project files *.adp are different than GNAT compiler project files *.gpr. However, Emacs Ada mode can use a GNAT project file to specify the project directories. If no other customization is needed, a GNAT project file can be used without an Emacs Ada mode project file.

If no Emacs Ada mode project file is specified, some Ada mode functions are not available.

Project file overview
=====================

Project files have a simple syntax; they may be edited directly. Each line specifies a project variable name and its value, separated by ``='' (spaces not allowed):

     src_dir=/Projects/my_project/src_1
     src_dir=/Projects/my_project/src_2

Any line that does not have an ``='' is a comment.

Some variables (like src_dir) are lists; multiple occurrences are concatenated.

There must be no space between the variable name and ``='', and no trailing spaces.

The current project file is given by the lisp variable ada-prj-default-project-file, and shown by the menu command Ada | Project Files | Show project.

To set the project file, use the menu command Ada | Set Project ..., or the elisp functions ada-parse-prj-file, ada-select-prj-file. The latter can be added to a Makefile:

     # Local Variables:
     # eval: (ada-parse-prj-file "ada-mode.prj")
     # eval: (ada-select-prj-file ada-mode.prj")
     # End:

You specify either a GNAT project file or an Emacs Ada mode project file; if the file extension is .gpr, the file is treated as a GNAT project file. Extensions given by ada-prj-file-extensions (default .adp, .prj) are treated as an Emacs Ada mode project file.

After a project file is parsed, you can make it current again with just ada-select-prj-file, or by selecting it from the menu.

Project file variables
======================

To set a project variable that is a list, specify each element of the list on a separate line in the project file.

Process environment variables can be referenced using the normal $var syntax.

Most project variables have defaults that can be changed by setting elisp variables; the table below identifies the elisp variable for each project variable. Elisp variables corresponding to project variables that are lists are elisp lists.

In general, project variables are evaluated when referenced in Emacs Ada mode commands. Relative file paths are expanded relative to the directory containing the project file.

Ada mode defines some project variables; others are defined by the compiler.

Here is the list of variables valid for all compilers. In the default values, the current directory "." is the directory containing the project file.

ada_compiler   [default: ada-compiler, gnat]
     Ada compiler for this project. It must occur in the project file before any compiler-specific project variable.

auto_case      [default: ada-auto-case, t]
     Non-nil means automatically change case of preceding word while typing.

case_identifier   [default: ada-case-identifier, ada-mixed-case]
     Function to call to adjust the case of an Ada identifier.

case_keyword   [default: ada-case-keyword, downcase-word]
     Function to call to adjust the case of an Ada keyword.

case_strict    [default: ada-case-strict, t]
     If non-nil, ada-mixed-case forces Mixed_Case for identifiers. Otherwise, ada-mixed-case allows UPPERCASE for identifiers.

casing         [default: ada-case-exception-file, nil]
     List of files containing casing exceptions. See Automatic casing.

el_file        [default: ]
     The value is a file name, which is loaded as an elisp file when the project file is parsed or selected. This allows setting Ada mode indentation variables, and any arbitrary elisp code used to customize the project.

path_sep       [default: path-separator]
     Separator character used in compiler search paths.

src_dir        [default: "."]
     A list of directories to search for source files.

xref_tool      [default: ada-xref-tool, gnat-xref]
     Cross reference tool for this project.

The following variables are valid with the GNAT compiler:

ada_project_path   [default: ""]
     A list of directories to search for GNAT project files.

     If set, the GPR_PROJECT_PATH process environment variable is set to this value in the child process that runs GNAT tools. If not set, GPR_PROJECT_PATH in the child process is inherited from the Emacs process.

     If you have the GPR_PROJECT_PATH or ADA_PROJECT_PATH environment variable set in the Emacs process correctly for all of your projects, you do not need to set this project variable.

     The project search path can also be set in GNAT aggregate projects. However, the gnat tools do not make that path available to Emacs, so you must duplicate it in an Emacs Ada project file.

gpr_file   [default: ""]
     The GNAT project file.

     If set, the source and project directories specified in the GNAT project file are appended to src_dir and ada_project_path. This allows specifying Ada source directories with a GNAT project file, and other source directories with the Emacs project file.

gpr_project_path   [default: ""]
     Same as ada_project_path.

Moving Through Ada Code
***********************

There are several commands to navigate through Ada code. All these functions are available through the Ada menu and keybindings.

Some of these commands rely on cross reference facilities provided by the compiler; the standard Emacs Ada mode only supports the GNAT compiler, but others can be added (see Other cross-reference).

C-c C-d
     Move from any use of an identifier to its declaration, for from a declaration to its body (if there is one).

C-c M-d
     Move from a child type declaration to the parent type declaration; display a list of references if there is more than one parent.

C-c C-n
     Move to the next keyword in the current statement.

     For example, if point is on if, move to then.

C-c C-p
     Move to the previous keyword in the current statement.

     For example, if point is on then, move to if.

C-c C-o
     Switch between corresponding spec and body. There are several special cases:

       * If the region is active, it is assumed to contain an Ada package name; position point on the corresponding package declaration.

       * If point is in the start line of a top level child package declaration (but not package body), or a child subprogram spec or body, position point on the corresponding parent package declaration.

       * If point is in the start line of a top level separate body, position point on the corresponding separate stub declaration.

       * If point is in a subprogram declaration or body, position point on the corresponding body or declaration in the other file.

       * If point is on a with clause, position point on the corresponding declaration.

C-c C-r
     Show all references to the identifier surrounding point. Use C-x ` (next-error) to visit each reference (as for compilation errors).

C-c C-x
     Show all declarations that override the primitive procedure at point. Use C-x ` (next-error) to visit each reference (as for compilation errors).

C-c M-x
     Show the declaration that the declaration at point overrides.

C-u SPACE
     Jump back to the previous location.

Ada | Misc | Refresh cross reference cache
     Cross reference information is loaded from the compiler output when the first cross reference command is issued. If the code is recompiled after that, the cross reference information is reloaded by invoking this menu command.

Identifier completion
*********************

Emacs provides a general way of completing identifiers: M-/ (bound to dabbrev-expand). This is an easy way to type faster: you just have to type the first few letters of an identifier, and then loop through all the possible completions.

M-/ works by parsing all open Ada files for possible completions.

For instance, if the words my_identifier and my_subprogram are the only words starting with my in any of the open Ada files, then you will have this scenario:

     You type:  myM-/
     Emacs inserts:  my_identifier
     If you press M-/ once again, Emacs replaces my_identifier with
     my_subprogram.
     Pressing M-/ once more will bring you back to my_identifier.

This is a very fast way to do completion, and the casing of words will also be respected.

Indentation
***********

Ada mode comes with a full set of rules for automatic indentation. You can also configure the indentation, via the following variables:

ada-indent                  (default value: 3)
     Number of columns for default indentation.

ada-indent-broken           (default value: 2)
     Number of columns to indent the continuation of a broken line.

ada-indent-comment-col-0  (default value: nil)
     If non-nil, comments currently starting in column 0 are left in column 0.  Otherwise, they are indented with previous comments or code.

ada-indent-label            (default value: -3)
     Number of columns to indent a label.

ada-indent-record-rel-type  (default value: 3)
     Indentation for record relative to type or use.

ada-indent-renames           (default value: 2)
     Indentation for renames relative to the matching subprogram keyword.

     If the subprogram has parameters then if ada-indent-renames is zero or less the indentation is abs ada-indent-renames relative to the open parenthesis; if ada-indent-renames is one or more the indentation is relative to the line containing the keyword.

     If the subprogram has no parameters then ada-indent-broken the indentation is relative to the indentation of the line containing the keyword.

ada-indent-return           (default value: 0)
     Indentation for return relative to the matching function.

     If the function has parameters, then if ada-indent-return is zero or less the indentation is abs ada-indent-return relative to the open parenthesis; if ada-indent-return is one or more, indentation is relative to line containing function.

     If the function has no parameters, ada-indent-broken is used relative to line containing function.

ada-indent-use  (default value: ada-indent-broken)
     Indentation for the lines in a use statement.

ada-indent-when             (default value: 3)
     Indentation for when relative to exception, case, or or in select.

ada-indent-with             (default value: ada-indent-broken)
     Indentation for the lines in a with context clause.

The indentation variables are buffer local; the global value may be overridden in an elisp file invoked by an el_file Emacs Ada mode project file statement, or in a file local variable section.

The following keys indent portions of the text:

RET
     Insert and indent a new line.

TAB
     Indent the current line, or the current region.

C-c TAB
     Indent the current statement or declaration.

The indentation algorithm relies on a grammar parser to identify the syntactic role for keywords and other words in the code. If the code is accepted by the parser, the indentation is done according to the rules in the indentation engine.

If the code is not accepted (because it is partially complete during editing), the indentation engine falls back to the trivial algorithm of indenting each new line the same as the previous line. Once enough new text has been entered to make the code acceptable to the parser, the statement or declaration is properly indented.

For example, if you are entering this code:

     if A then
        B;
     end if;

when you type RET B, B is indented to the same column as if, because the parser does not find end if;. Then when you type the final ; followed by TAB, all three lines are indented, putting B where it belongs.

To be more user friendly, the parser accepts a superset of the Ada grammer. For example, the parser accepts this code for an if statement:

     if then
     end if;

In general, any sequence of statements, and many expressions, may be omitted.

One way to easily insert empty statements like this is using Statement skeletons.

In rare cases, the parser gets confused; it can be reset by invoking menu Ada | Misc | Reset parser. Please report such cases as a bug.

Statement skeletons
*******************

C-c C-e expands the previous one or two words into a statment skeleton. For example, i f C-c C-e expands to:

     if  then
     elsif  then
     else
     end if;

All skeleton expansions are accepted by the indentation parser, so this is a convenient way to insert statements with correct indentation.

For named statements (packages, loops, etc), the name is taken from the word before point, and the name of the statement from the word before that.

Some expansions prompt for more information, such as whether a spec or body is desired. For example, package A_Package C-c C-e first prompts for ``body'' or ``spec''. If ``spec'' is selected, the following code is inserted:

     package A_Package is
     private
     end A_Package;

Named blocks work similarly: declare A_Block C-c C-e expands (without prompting) to:

     A_Block:
        declare
        begin
        exception
        end A_Block;

Note that the order of the keyword declare and the name A_Block are reversed in the expansion; this may take some getting used to. Alternately, if no name is present in the buffer, you are prompted for a name: declare C-c C-e first prompts for a name, then expands to the above.

The variable ada-skel-initial-string defines what to insert in a newly created empty buffer. It defaults to {header}, which is a placeholder defined by ada-skel-header, which inserts a typical header with a copyright license (choice of GPL or restricted). Users will typically want to override the definition of ada-skel-initial-string and/or ada-skel-header, or provide more choices of copyright license.

Aligning code
*************

Aligning code adds space in each line so that similar parts of successive lines are aligned vertically. For example, a sequence of declarations:

     A : Integer;
     Another : Float := 1.0;
     More : Integer := 2;

changes to this when aligned:

     A       : Integer;
     Another : Float   := 1.0;
     More    : Integer := 2;

Alignment is invoked by C-c C-a, which aligns the sequence of statements surrounding point, or within the selected region.

Parameter lists are also aligned:

        procedure Foo
          (A : in Integer;
           Another : out Float := 1.0;
           More : in out Integer := 2);

is aligned to:

        procedure Foo
          (A       : in     Integer;
           Another :    out Float   := 1.0;
           More    : in out Integer := 2);

Automatic casing
****************

Casing of identifiers, attributes and keywords is automatically performed while typing when the variable ada-auto-case is non-nil (the default). Every time you type a word separator, the previous word is automatically cased.

You can customize the automatic casing with the following variables:

ada-case-keyword
     Value must be one of:

     downcase-word
          Ada keywords will be lowercase.

     upcase-word
          Ada keywords will be uppercase.

ada-case-strict
     If non-nil, all identifiers are forced to Mixed_Case; first letter, and letter following ``_'' are uppercase; rest are lowercase.

     If nil, the mixed case characters in identifiers are forced to upper case, but the other characters are not modified. That allows typing all uppercase identifiers without defining a casing exception.

You can define exceptions to these rules, in files specified by the variable ada-case-exception-file. Each line in a case exception file specifies the casing of one word or word fragment. If an exception is defined in multiple files, the first occurrence is used.

If the word starts with an asterisk (*), it defines the casing of a word fragemnt (or ``substring''); part of a word between two underscores or word boundary.

For example:

     DOD
     *IO
     GNAT

The word fragment *IO applies to any word containing ``_io''; Text_IO, Hardware_IO, etc.

There are two ways to add new items to this file: you can simply edit it as you would edit any text file. Or you can position point on the word you want to add, and select menu Ada | Casing | Create full exception or Ada | Casing | Create partial exception.  The word will be added to the current list of exceptions and to the file.

It is sometimes useful to have multiple exception files. For example, one could be the standard Ada acronyms, the second some company specific exceptions, and the last one some project specific exceptions. If you set up the variable ada-case-exception-file as a list of files, each of them will be parsed and used in your emacs session. When you create a new exception, you are prompted for the file to save it in.

Other keys and menu entries are defined:

C-c C-w
     Adjust case of the word at point. With prefix arg, adjust case even if in comment. Normally, comments are not affected by case adjust.

Ada | Casing | Adjust case region
     Adjust case in the active region.

Ada | Casing | Adjust case buffer
     Adjust case in the active buffer.

Comment Handling
****************

By default, comment lines get indented like Ada code. There are a few additional functions to handle comments:

M-;
     If the region is active, comment or uncomment it.

     If the current line is empty, start a comment.

     Otherwise, add a comment at the end of the line, in a column given by comment-column.

M-q
     Fill the current comment paragraph.

Key summary
***********

This table summarizes the keys described in this manual. Other keys are bound by Ada mode; see C-h b for a complete list. The Ada menu also displays keys bound to menu operations.

M-/
     See Identifier completion. Complete the word before point; repeat to cycle thru possible completions.

M-;
     See Comment Handling. If the region is active, comment or uncomment it.

M-q
     See Comment Handling. Fill the current comment paragraph.

RET
     See Indentation. Insert and indent a new line.

TAB
     See Indentation. Indent the current line, or the current region.

C-c TAB
     See Indentation. Indent the current statement or declaration.

C-c `
     See Compiler errors. Move to the location of the secondary reference in the current compilation error.

C-c C-a
     See Aligning code. Align code.

C-c C-c
     See Compile commands. Build the current main program.

C-c C-d
     See Moving Through Ada Code. Move from any use of an identifier to its declaration, for from a declaration to its body.

C-c M-d
     See Moving Through Ada Code. Move from a child type declaration to the parent type declaration.

C-c C-e
     See Statement skeletons. Expand previous one or two words into a statement or declaration skeleton.

C-c C-c
     See Compile commands. Build the current file.

C-c C-n
     See Moving Through Ada Code. Move to the next keyword in the current statement.

C-c C-o
     See Moving Through Ada Code. Switch between corresponding spec and body, or find other spec.

C-c C-p
     See Moving Through Ada Code. Move to the previous keyword in the current statement.

C-c C-r
     See Moving Through Ada Code. Show all references to the identifier surrounding point.

C-c C-w
     See Automatic casing. Adjust case of the word at point. With prefix arg, adjust case even if in comment.

C-c C-x
     See Moving Through Ada Code. Show all declarations that override the primitive procedure at point.

C-c C-y
     See Automatic casing. Create case exception.

C-c `
     See Compiler errors. Move to the location of the next secondary compilation error.

C-x `
     See Compiler errors. Move to the location of the next compilation error or show result.

M-q
     See Comment Handling. Fill the current comment paragraph.

Developer overview
******************

If you'd like to contribute to Ada mode, or just understand the sources, here's an overview.

Directory structure
===================

org.emacs.ada-mode
     Main source.

     File extensions:

     *.el
          Elisp files; main code.

     *.elc
          Byte-compiled elisp files, not in the distribution. Generated by the Makefile target byte-compile, or by the Emacs package installer.

          Compiling the parse tables (*-wy.el) speeds up loading them significantly. Compiling other files speeds up parsing, but not noticeably.

          One reason to byte-compile files is to find errors; the byte compiler reports undefined variables, wrong argument counts, etc.

     *-wy.el
          Parse tables, generated from the corresponding grammar *.wy by the OpenToken tool wisi-generate.exe. These are in the tarball distribution and the monotone repository so users and Elisp developers don't have to install OpenToken.

     *-wy.output
          Diagnostic output from wisi-generate.exe, useful for tracing parses while debugging a grammar issue. Not in the tarball distribution or the monotone repository.

     *.wy
          Grammar files, specifying the language to be parsed. The syntax for these grammar files is similar to that for bison and wisent, but not the same; see the OpenToken documentation for more info.

          The wisi parser (in wisi-parse.el) is a generalized LALR parser, so it tolerates some conflicts and ambiguities. This makes the grammars easier to write, and in particular makes it possible to let the Ada grammar closely match Annex P of the Ada Language Reference Manual (the syntax summary).

     *.texi
          Texinfo source for the user guides.

     *.html
          Generated user guide in HTML format.

     *.info
          Generated user guide in Emacs info format.

build
     Makefile for building the user guides, publishing to the web page or Gnu ELPA. Test drivers.

build/wisi
     Makefile for building and testing with the wisi-based parser. Separate from build, because there used to be a SMIE-based parser, and there might be another parser someday.

     The emacs used to byte-compile and run tests is given by the 'make' variable EMACS_EXE, which defaults to 'emacs'; it can be overridden on the make command line or by an environment variable.

test
     All tests for Ada mode, gpr mode, parser.

     Each test is run in a separate invocation of Emacs, so it is completely independent of all other tests.

     The tests are driven by the elisp code in build/*.el.

     In general, the Ada mode tests open the file, execute test actions, re-indent, and re-captialize the entire file. The result is diffed with the original, and must match.

     The test actions are defined by comments with the prefix --EMACSCMD:; they are elisp forms that invoke Ada mode functions. This is used to test navigation features and other parser effects.

test/Example_*
     Starting files for examples in user guide.

test/gpr
     Tests for gpr mode.

test/subdir
     More tests; allows testing path search features.

test/wisi
     Tests of the elisp wisi grammar compiler and parser.

Package organization
====================

Ada mode
--------

Ada mode consists of all files with ada- prefix in the file name.

ada-mode.el
     The main file, implementing the keymap, menu, and top level functionality.

     It allows for different backend implementations for compiling, cross-referencing, and indenting. The functions for each of these backends dispatch thru global variables that are set by Emacs Ada mode project files. They default to the GNAT compiler, the gnatxref cross reference tool, and the ada-wisi indentation engine.

ada-build.el
     Provides functions for compiling Ada files without a Makefile (or similar tool).

ada-fix-error.el
     Provides an interface to utilities for automatically fixing errors reported by the compiler. It dispatches to a compiler-specific backend.

ada-gnat-compile.el
     Implements the Ada mode compiler functions for the GNAT compiler.

ada-gnat-xref.el
     Implements the Ada mode cross reference functions for the GNAT compiler.

ada-grammar.*
     The Ada language grammar, and files generated from it by the OpenToken tool wisi-generate.exe.

ada-indent-user-options.el
     All user-settable options for the Ada indentation engine.

ada-mode-compat-23.4.el
     Defines functions used by Ada mode that are not in Emacs 23.4.

     Emacs Ada mode is written for Emacs 24.3. Emacs version 23.4 is partially supported. Earlier versions of Emacs are not supported.

ada-mode.texi
     The Ada mode user guide source and compiled versions.

ada-skel.el
     Skeletons for expansion of Ada syntax (see Statement skeletons). Extends the Emacs skeleton functions with ``tokens'', inspired by the lamented Else package (which was inspired by DEC LSE).

ada-wisi-opentoken.el
     Indentation functions useful when editing OpenToken code; an example of extending the Ada mode indentation engine for special circumstances.

ada-wisi.el
     Implements the Ada mode indentation functions for the wisi indentation engine backend.

gpr mode
--------

gpr mode consists of all files with gpr- prefix in the file name. The functions in each file are similar to the similarly-named Ada mode files.

GNAT core
---------

gnat-core.el
     GNAT is actually a multi-language tool; it builds on top of the multi-language gcc.

     gnat-core.el is a start at a language-agnostic interface to the GNAT tools. It was first factored out from ada-gnat.el and ada-mode.el to support the multi-language gnat-inspect.el, which is still experimental.

     More code currently in ada-mode.el could be migrated to gnat-core.el, in particular the project file support.

gnat-inspect.el
     Provides an experimental interface to the experimental multi-language cross-reference tool gnatinspect from AdaCore, which will supercede gnatxref.

     Implements the Ada mode cross-reference functions for the gnatinspect backend, and a minor mode providing similar functions for C++.

Wisi
----

The ``wisi'' parser. ``wisi'' used to be an acronym, but now it's just a name.

wisi.el
     Implements the lexer, the main parser driver, parser actions that cache parser information in text properties, utilities for indenting and navigating using the cached information, and general setup.

wisi-compile.el
     Implements the parse table compiler. wisi-generate.exe processes the grammar source *.wy into an elisp source representation of a parse table *-wy.el. That is compiled into an internal structure containing the state transitions and executable actions. The actions can be any elisp form; the intent is that they be calls to the action functions provided by wisi.el. wisi-compile.el uses some features provided by semantic.

wisi-parse.el
     Implements the generalized LALR parser.

OpenToken
=========

Ada mode uses the OpenToken tool wisi-generate.exe to process the grammar sources into elisp parse tables. See http://stephe-leake.org/emacs/ada-mode/emacs-ada-mode.html for current information about which version of OpenToken is required, and how to get it.

The Makefile variable WISI_OPENTOKEN gives the path to the build directory for OpenToken; you probably need to override it with an external environment variable or on the make command line.

ELPA
====

Ada mode is published via the Gnu ELPA archive. To test a new version of Ada mode, we use a local Gnu ELPA archive. That requires fetching Gnu ELPA via git:

     cd /Projects
     git clone git://git.savannah.gnu.org/emacs/elpa.git

If you have an Emacs Savannah developer account, you can use:

     cd /Projects
     git clone <login>@git.savannah.gnu.org/emacs/elpa.git

build/Makefile contains targets for copying Ada mode source to the elpa workspace, and for building the elpa archive there.

GNU Free Documentation License
******************************

     [file doclicense.texi not included]