Ada Mode

Next: , Previous: , Up: (dir)   [Contents]

Top

Ada Mode Version 8.1

Table of Contents


Next: , Previous: , Up: Top   [Contents]

1 Overview

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

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://libre.adacore.com/) and the GNAT default naming convention. However, you must compile the parser; See Ada executables for how to do that.

If you want to use the Emacs cross reference facility xref, you must install one of the ELPA packages eglot or gpr-query. See wisi parser vs LSP vs ... for more on this.

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 Customizing Ada mode.

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 in Emacs User Guide, for general information on debugging.


1.1 wisi parser vs LSP vs ...

ada-mode can be configured to work with a wisi parser, or an LSP language server via eglot. It can also be configured to experiment with other backends, such as tree-sitter or lsp-mode, but these other backends are not yet fully supported.

The Language Server Protocol (LSP, https://langserver.org) defines an external language parser, and it is supported by the GNU ELPA package eglot, using an Ada language server provided by AdaCore (ada_language_server, https://github.com/AdaCore/ada_language_server/). LSP supports face, indent, and multi-file navigation. However, as of ada_language_server (als) version 23.0, als provides face and single line indent, but both have significant problems, so it is only useful for xref.

The Emacs wisi package provides an interface to a custom parser generated by the WisiToken package; the parser provides face, indent, and statement navigation.

The Emacs gpr-query package provides an xref backend that uses information output by the GNAT compiler.

By default, if the wisi parser is found, ada-mode uses it for face, indent, and statement navigation.

If the gpr-query executable is found, it is used for multi-file navigation. Otherwise, gnatxref is used. To use the eglot xref backend, you must explicitly set ada-xref-backend to eglot.

Otherwise, if the language server is found, it is used for face and/or indent (assuming a future version of the ada_language_server supports these features).

You can override the default choices by setting the elisp variables ada-diagnostics-backend, ada-face-backend, ada-indent-backend, ada-statement-backend, ada-xref-backend. These can all take the value other to experiment with other backends.


1.2 Supported features

The following table lists features supported in either wisi or LSP, and whether LSP, wisi, ada_language_server version 23, eglot version 1.9 supports them.

wisiLSPals 23eglot 1.9feature
ttt, bugtline/region indent
ttnilnilada-which-function; needs DocumentSymbol
tnilnilnilada-fix-context-clause; needs full syntax tree access
tnilnilnilwisi-goto-*; needs full syntax tree access
tnilnilnilwisi-goto-*; needs full syntax tree access
tnilnilnilforward-sexp goes to next keyword in statement; needs full syntax tree access
ttniltada-find-other-file moves to corresponding declaration; needs DocumentSymbol
ttnilnilsyntax-based identifier faces; needs SemanticToken
ttt?refactor; wisi and als 22 support different refactor operations.

als 23 supports range format, but has bugs; see https://github.com/AdaCore/ada_language_server/issues/1073. https://github.com/AdaCore/ada_language_server/issues/1074.

Some of the bugs can be fixed by using patched versions of some Alire crates:

alr index --add git+https://github.com/stephe-ada-guru/alire-index.git#stephe-patches --name stephepatches --before community

Similarly for gpr-query.

gpr-queryLSPals 22eglot 1.9feature
tnilnilnilshow overridden.
tnilnilnilshow overriding.
tnilnilnilshow parent types.
ttttshow definitions.
ttttshow references.

Next: , Previous: , Up: Top   [Contents]

2 Installation

Ada mode requires Emacs 25.3 or greater. Compiling the Ada code for the external process parser requires GNAT GPL 2017 or later; tested with GNAT Community Edition 2021, GNAT Pro 22.2 (see Known versions).

Ada mode is distributed in the Gnu ELPA package archive; it can be installed via M-x list-packages (see Packages in Emacs User Guide). Note that it requires several other packages as dependencies.

Before ada-mode version 8, the Emacs packages gpr-query and gpr-mode were bundled with ada-mode; they have now been split out, so it is easier to configure ada-mode with eglot instead of gpr-query; you must install one of these if you want to use xref.

In Emacs < 27 you must first enable packages in your ~/.emacs, after customizing Info-default-directory-list (if you do that):

(package-initialize)

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

You must also install the associated Ada executables (see below). You may want to install the Ada Reference Manual in info format, via the ELPA package ada-ref-man.


2.1 Ada executables

Ada mode requires either the wisi parser and gpr-query, or the Ada language server ada_language_server. All of these can be installed via the Alire Ada package manager (https://alire.ada.dev/), or compiled directly.

See the gpr-query package for information on compiling gpr-query.

To install the wisi parser:

cd ~/.emacs.d/elpa/ada-mode-i.j.xx
./build.sh
./install.sh

By default, install.sh installs the parser executable in $HOME/.local/bin, so you must put that in PATH. If you want to install somewhere else, use install.sh --prefix=<dir>.

These scripts default to use Alire (https://alire.ada.dev/) if it is found on PATH; otherwise they use gprbuild.

One step in build.sh is to run wisitoken-bnf-generate to generate the LR1 parse table for the parser. This can take up to 5.4GB of memory during the generate process; if your machine does not have that much, you can download the ada_annex_p_lr1_parse_table.txt from https://download.savannah.nongnu.org/releases/ada-mode/ - be sure to get the version that matches the current ada-mode, and put it in the same directory as ada_mode_wisi_lr1_parse.


Previous: , Up: Installation   [Contents]

2.2 Known versions

Here we list GNAT compiler versions that are known to work or not work with ada-mode.

There are various ways to get the GNAT compiler:

Community

Downloaded from https://www.adacore.com/download. The version number is the release year.

This version is provided by AdaCore, but they do not support users using it.

Pro

Downloaded from AdaCore via a support subscription. The version number is the last two digits of the release year, followed by a patch release digit.

This version is provided by AdaCore, and they support users using it.

FSF

Installed via a free software package manager, typically as part of the “gcc” package. The version number is the same as the gcc version, something like “10.3.0”, possibly followed by a date.

This version is derived from some AdaCore version, but is typically not identical to a released version. It may be supported by the packager.

Alire

Alire packages several recent versions of the FSF compiler. It is used by all Alire build commands. The versions available can be listed by:

alr toolchain

The compiler can be installed for external use by:

alr toolchain --install <version> --install-dir <prefix>

Sometimes compiler versions change what code they accept, particularly in the area of access types. So some compiler versions may require minor edits of the ada-mode code; there is a “WORKAROUND” comment in the code describing the edit required.

Compiler versions that work:

Community 2019

Reports an error about a dangling reference; see WORKAROUND comment in ~/.emacs.d/elpa/wisi-i.j.k/sal-gen_unbounded_definite_red_black_trees.adb

Community 2020

No edits required.

Community 2021

Requires ada-mode version 7.1.6 or later.

Pro 20.2

Requires ada-mode version 7.1.6 or later.

No edits required.

Pro 21.2

No edits required.

Pro 22.2

No edits required.

FSF 11.1.0

No edits required.

FSF 12.1

No edits required.

Compiler versions that fail:

FSF gnat 10.2.1 20210110

ada-mode uses compiler option -gnat2020; that causes bogus failures with this version of gnat. Reported at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99099


Next: , Previous: , Up: Top   [Contents]

3 Customizing Ada mode

All user-settable Ada mode variables can be set via the menu ‘Ada | Customize’; some can also be set in wisi project files (see Project files).

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)

ada-mode variables that you might consider changing:

Matching end names

By default, the option ada-end-name-optional is set to t, which matches the Ada standard. This is useful for new Ada users. Experienced users that follow a style guide requiring matching end names should set this to ’t’, since that gives better error correction.

Some general (non ada-mode) Emacs settings that are useful for Ada files:

context menu

By default, the context menu is bound to C-down-mouse-3, i.e. control-right-click. down-mouse-3 is already bound in the global map; you can override that global binding in the ada-mode-hook (see below for code).

other-frame-window-mode

Ada mode does not provide any other-frame or other-window variants of user operations. Instead, it is recommended to use the Gnu ELPA package other-frame-window.

delete-trailing-whitespace

Deletes space, tab at end of line and blank lines at end of buffer.

xref configuration
xref-prompt-for-identifier

Set to nil to be prompted less when finding definitions or references.

xref-show-xrefs-function

Determine placement of the window where references are shown.

xref-show-definitions-function

Determine placement of the window where definitions are shown.

xref--transient-buffer-mode-map

keymap used in some xref windows; you may want to disable the RET binding there.

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 wisi-skel-hippie-try to that list. Note that wisi-skel-expand is bound to C-c C-e (see Statement skeletons).

imenu

Navigate to subprograms and types by name, from a minibuffer menu.

speedbar

Navigate to subprograms and types by name, from a list in a dedicated window.

which-func

Display the current subprogram name in the mode bar.

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 speedbar unless imenu is loaded first.

(setq-default indent-tabs-mode nil)
(define-key xref--transient-buffer-mode-map (kbd "RET") 'xref-goto-xref)
(setq xref-prompt-for-identifier nil) ;; only prompt on C-u
(setq xref-show-xrefs-function #'xref--show-defs-buffer-at-bottom)
(setq xref-show-definitions-function #'xref--show-defs-buffer-at-bottom)

(electric-pair-mode 1)
(require 'imenu) ;; also enables speedbar
(require 'ada-mode)
(add-to-list 'hippie-expand-try-functions-list 'wisi-skel-hippie-try)
(define-key ada-mode-map "\C-e"     'hippie-expand)
(define-key ada-mode-map [down-mouse-3] 'ada-popup-menu)
(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)))

3.1 Ada with eglot

If you have ada_language_server installed, either in PATH or a gnat installation, eglot works without customization.

To override the default choice of server executable, set gnat-lsp-server-exec.

To customize the faces used for highlighting, see ada-eglot-token-faces, ada-eglot-modifier-faces.

To specify the gpr file for ada_language_server without using a wisi project file, set ada-eglot-gpr-file.

To turn off some LSP features, set eglot-ignored-server-capabilities; for example, to stop highlighting the identifier at point:

(eval-after-load "eglot.el"
  (progn
    (add-to-list 'eglot-ignored-server-capabilities :documentHighlightProvider)))

To turn off other features of eglot, set eglot-stay-out-of. For example, to turn off the progress reports about ada_language_server indexing:

(eval-after-load "eglot.el"
  (progn
    (add-to-list 'eglot-stay-out-of 'progress)))

3.2 Slow response

The external process that runs the Ada parser can be slow to start, due to loading the very large LR1 parse table. The impact of this can be minimized by starting the process before it is actually needed, by executing ada-parse-require-process as part of Emacs startup.

In addition, in large files, parsing takes a noticable amount of time, so it gets in the way of interactive typing due to immediate fontification triggering a parse.

There are several ways to deal with this:

  1. Set wisi-incremental-parse-enabled t This enables incremental parsing. In this mode, the entire file is parsed once when it is opened, and then changes to the text are parsed incrementally, which is both fast and accurate.
  2. Lower wisi-partial-parse-threshold This assumes wisi-incremental-parse-enabled is nil.

    In your ~./emacs:

    (setq wisi-partial-parse-threshold 100001)
    

    The default value (100001) may already be appropriate; it depends on how fast your machine is, and what your tolerance for slow response is.

    Files larger than wisi-partial-parse-threshold (in characters) will be parsed partially; only the part of the buffer needed for the current task will be parsed. For fontification, that is the visible part. For indent, it is approximately the current subprogram or package. For navigation, it is always the entire file, which will still be slow; that is the only way to ensure useful results.

    With this setting, indentation may not be correct; the Ada menu entry “Edit | Indent containing statement” will indent correctly.

  3. Delay fontification by setting jit-lock-defer-time in your ~./emacs:
    (setq jit-lock-defer-time 1.5)
    

    This is a global setting; it affects all buffers. Fontification will only be performed after you have stopped typing for the indicated number of seconds.

  4. Turn off parsing for fontification by setting wisi-disable-face in your ~./emacs
    (setq wisi-disable-face t)
    

    This turns of fontification for type, package, and function names; only Ada reserved words are fontified.


3.3 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 extensions 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 in a GNAT project file Naming package; 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.


3.4 Other compiler

The wisi project variable ada_compoiler (default elisp variable ada-compiler) (default 'gnat) controls dispatching in 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-compiler-gnat.el for an example.


3.5 Other cross-reference

The wisi project variable xref_tool (default elisp variable ada-xref-tool) controls dispatching in the cross-reference-tool-specific functions for corresponding Ada mode operations.

If gpr_query is found in PATH, the default cross-reference tool is gpr_query; otherwise it is gnatxref.

To use a cross reference tool other than the above, you must write Emacs lisp code that provides the interface to the tool, and set ada-xref-tool and the indirection variables.

See ada-gnat-xref.el and gpr-query.el for examples.


Next: , Previous: , Up: Top   [Contents]

4 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 may need a wisi project file to tell Emacs about the project directory tree and other settings.


4.1 Compile commands

Here are the commands for building an Ada project and running the main program; they are all on the Ada | Build menu.

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

Displays 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 ’gprbuild’ 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 two ways to change main:

  1. Invoke ‘Ada | Set main and Build’, which sets main to the current file.
  2. Invoke ‘Ada | Project | Load’, and load a project file that specifies main

4.2 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.


4.2.1 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, making it possible to indent 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

gprbuild  -u -c -gnatc  c:/Projects/org.emacs.ada-mode/test/Example_1/hello.adb
using project file D:\Apps\GNAT-gpl_2019\share\gpr\_default.gpr
Compile
   [Ada]          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
gprbuild: *** compilation phase failed

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. In the compilation buffer, a triangle is placed in the left fringe on the first error 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

gprbuild  hello
using project file D:\Apps\GNAT-gpl_2019\share\gpr\_default.gpr
Compile
   [Ada]          hello.adb
Bind
   [gprbind]      hello.bexch
   [Ada]          hello.ali
Link
   [link]         hello.adb

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 gprbuild finds the files needed by the main program. However, it cannot find files in a different directory, unless you use a GNAT project file to specify the other directories; Set source search path.

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’. gprbuild 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.

4.2.2 Set compiler options

This example illustrates using a gnat 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.gpr:

project Hello is
   package Compiler is
      for Default_Switches ("Ada") use ("-gnatyt");
   end Compiler;
end Hello;

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.gpr, 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):

gprbuild -Phello.gpr hello
Compile
   [Ada]          hello.adb
hello.adb:4:04: "Put_Line" is not visible
hello.adb:4:04: non-visible declaration at a-textio.ads:508
hello.adb:4:04: non-visible declaration at a-textio.ads:498
hello.adb:4:12: (style) space required
gprbuild: *** compilation phase failed

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

Use C-x`, C-c M-` to fix the errors, then ‘Ada | Build | Build’ and ‘Ada | Build | Run’ to build and run.


4.2.3 Set source search path

In this example, we show how to deal with files in more than one directory, setting the source search path in the gpr file.

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.

other.gpr:

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

In addition, create a directory Example_3/Other, containing this file:

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.

In buffer hello_3.adb, invoke ‘Ada | Project files | Find and select project...’, and select Example_3/other.gpr. 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.gpr, 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):

gprbuild -Pother.gpr hello_3
Compile
   [Ada]          hello_3.adb
   [Ada]          hello_pkg.adb
hello_pkg.adb:2:08: keyword "body" expected here [see file name]
gprbuild: "C:\Examples\Example_3\hello_pkg.adb" compilation error

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

Use C-x`, C-c M-` to fix the errors, then ‘Ada | Build | Build’ and ‘Ada | Build | Run’ to build and run.


4.2.4 Use wisi project file

In this example, we show how to use a wisi project file to set some options that cannot be set in a gpr project file. In addition, we change a setting so you are prompted for a project file, rather than using a default one.

Change the setting:

M-x set-variable ada-build-prompt-prj search-prompt

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 body Hello_Pkg is
   procedure Say_Hello
   is begin
      Put_Line ("Hello from hello_pkg.adb");
   end Say_Hello;
end Hello_Pkg;

These two files are the similar to files from example 1; hello_pkg.adb has an error on line 5 (missing “Ada.Text_IO.”).

example_4.prj:

-- Wisi project file

gpr_project_path=More

gpr_file=example_4.gpr

casing=example_4.casing

example_4.prj is a wisi project file; it specifies the gpr_project_path, telling gprbuild where to search for gpr files, and specifies the gpr file to use. Finally it specifies a casing exception file:

example_4.casing:

Text_IO

The default auto casing rules in ada-mode state that the Ada package “Ada.Text_IO” should be capitalized as “Ada.Text_Io”, which does not match the Ada Reference Manual. example_4.casing specifies that instead “Text_IO” should be capitalized as shown.

You can create a casing exception by editing the file directly, or via the Ada | Casing menu.

gpr_project_path and casing are list variables; each occurrence in a wisi project file adds an entry to the list.

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

more/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, except for the casing in “Ada.Text_Io”.

More/example_4.gpr:

project Example_4 is
   for Source_Dirs use (".", "..");

   package Compiler is
      for Default_Switches ("Ada") use ("-gnatyknpr");
   end Compiler;
end Example_4;

The compiler switch checks all casing; we will get errors for “Ada.Text_Io”.

Then, in hello_4.adb, invoke ‘Ada | Set main and Build’. ada-mode looks for a project file hello_4.prj or hello_4.gpr; since neither is found, you are prompted to find a project file. Select Example_4/example_4.prj; that is parsed and selected, and the build continues.

You should get a *compilation* buffer containing something like (the directory paths will be different):

gprbuild -Pexample_4.gpr hello_4
Compile
   [Ada]          hello_pkg.adb
hello_pkg.adb:1:16: (style) bad casing of "Text_IO" declared at a-textio.ads:57
hello_pkg.adb:5:07: "Put_Line" is not visible
hello_pkg.adb:5:07: non-visible declaration at a-textio.ads:508
hello_pkg.adb:5:07: non-visible declaration at a-textio.ads:498
gprbuild: *** compilation phase failed

When you fix the errors, note that C-c M-` inserts the correct case for “Ada.Text_IO”, and corrects the case where it is incorrect. The case is also corrected as you type; you can type “ada.text_io.” and the case will be corrected when you type each “.” or “_”.


4.2.5 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. This also requires explicitly setting project-find-functions.

If you haven’t already, create the directory Example_4 as specified in Use wisi project file. If you’ve already created it and run the tutorial, restore the compilation error in hello_pkg.adb; delete Ada.Text_IO. in front of Put_Line.

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.prj:

gpr_project_path=../Example_4/More
gpr_file=hello_5.gpr

casing=../Example_4/example_4.casing

hello_5.gpr:

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

In buffer hello_5.adb, invoke ‘Ada | Project | Find and select project...’, and select Example_5/hello_5.prj. This would also be found by default if no previous project file had been selected. Note that if example_5.gpr were named hello_5.gpr, the project file search would find more than one match, causing an error.

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/test/Example_5/" -*-
Compilation started at Mon Oct 21 11:32:05

gprbuild -Pexample_5.gpr hello_5
Compile
   [Ada]          hello_5.adb
   [Ada]          hello_pkg.adb
hello_pkg.adb:5:07: "Put_Line" is not visible
hello_pkg.adb:5:07: non-visible declaration at a-textio.ads:508
hello_pkg.adb:5:07: non-visible declaration at a-textio.ads:498
gprbuild: *** compilation phase failed

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.

Now, in buffer hello_pkg.adb invoke the menu Ada | Navigate | Find file in project (which calls ada-find-file) to get back to the hello_5.adb buffer. If you have not selected any project files previously in this emacs session, this gives an unexpected prompt for a “project directory”. Kill that with C-g. Otherwise, enter hel <tab> 5 <tab>; it will say “no match”.

The problem here the way Emacs projects work. To find the current project, the functions in project-find-functions are run; one should return a project. The ada-mode build functions add wisi-prj-find-dominating-cached to project-find-functions; that looks in the current directory tree for a project file with the same name as one that was previously selected.

If Example_5 is the only project in the current emacs session, wisi-prj-find-dominating-cached finds no project file (because Example_4 is not a child directory of Example_5), so the default strategy of “ask the user” is used, giving the prompt for a directory.

If Example_4 is also a project in the current emacs session, wisi-prj-find-dominating-cached finds that; since it does not contain hello_5.adb, ada-find-file cannot find it.

Any time you have a main project that depends on other projects that are not in the same directory tree, you will have this problem.

The fix is to use a different function in project-find-functions; wisi-prj-current-cached. This uses a global variable to indicate what the current project is. wisi provides four different functions for project-find-functions. See Selecting projects in Wisi User Guide.

To change project-find-functions, execute:

M-: (remove-hook 'project-find-functions 'wisi-prj-find-dominating-cached)
M-: (add-hook 'project-find-functions 'wisi-prj-current-cached)

Normally, you must set project-find-functions in your ~/.emacs, using the add-hook function. The ada-mode Build menu functions set it for you to make things simpler for novices, but they do not change it if you have put one of the wisi functions on it.

Now set the current project; invoke ‘Ada | Project | Find and select project...’, and select Example_5/hello_5.prj. Then in hello_pkg.adb, invoke Ada | Navigate | Find file in project; now we can find hello_5.adb.


4.2.6 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 wisi 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 -PExample_5.gpr hello_5

run :
        ./hello_5

clean :
        gnatclean -r -PExample_5

# Local Variables:
# eval:(unless (wisi-prj-find-function-set-p)(add-hook 'project-find-functions 'wisi-prj-current-cached))
# eval:(wisi-prj-dtrt-parse-file "hello_5.prj" (ada-prj-default "hello_5 # main") "Makefile")
# End:

Tell Emacs to allow eval in Local Variables:

M-: (setq enable-local-eval t)

Close and re-open Makefile; the ‘Local Variables’ section sets the project file to hello_5.prj when the Makefile is opened.

If you have set project-find-functions in your ~/.emacs, you can leave out the first eval line. Note that wisi-prj-dtrt-parse-file does the right thing depending on which wisi function is in project-find-functions.

In Makefile, invoke ‘Tools | Compile...’, and accept the default make command. This runs the ‘all’ target, which builds hello_5 and runs it (you may have to fix source errors first, depending on how fresh the Example_4 directory is).


4.3 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 `.


5 Project files

Ada mode uses wisi project files; Project files in Wisi User Guide.

A wisi 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 wisi 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 wisi project files 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 a wisi project file.

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


5.1 Project file overview

The current project file is shown by the menu command Ada | Project Files | Show project.

To set the project file, use the menu command Ada | Project Files | Find and select Project ....

You can also set the project file on the Emacs command line. For Example_2 in See Compiling Examples:

cd .../Example_2
emacs --eval "(ada-build-prompt-select-prj-file \"hello.gpr\")" hello.adb

Finally, you can set the project file in some lisp startup code using one of the elisp functions described in Selecting Projects in Wisi User Guide. The project file may also be a GNAT project file (with file extension is .gpr).


5.2 Project file variables

Some 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.

wisi defines some project variables, Ada mode defines some, others are defined by the compiler and the cross reference tool.

Here is the list of variables valid defined by Ada mode; Project files in Wisi User Guide for the variables defined by wisi. 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.

Setting this in the project file reinitializes all options for the compiler, so it must occur before any compiler-specific project variable.

gnat-stub-args

List of strings passed to gnat stub when it is run.

gnat-stub-cargs

List of strings passed to gnat stub after -cargs.

obj_dir

A list of directories to search for object and cross-reference files. Only needed if you are not using gpr files.

xref_backend [default: ada-xref-backend]

Cross reference backend for this project.

Setting this in the project file reinitializes all options for the xref backend, so it must occur in the project file before any other settings that affect the xref backend.

The following project file variables are defined by the GNAT compiler:

ada_project_path [default: ]

Same as gpr_project_path; see below.

gnat-stub-cargs [default: nil]

Arguments passed to gnat stub --cargs.

gnat-stub-opts [default: nil]

Arguments passed to gnat stub.

gpr_file [default: ]

The GNAT project file for the project.

If set, the source and project directories specified in the GNAT project file are appended to src_dir and gpr_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: nil]

A list of directories to search for GNAT project files. The list is passed to tools via the GPR_PROJECT_PATH process environment variable in the process used to run the gnat and gpr_query tools.

If not set, GPR_PROJECT_PATH in the child process is inherited from the Emacs process.

runtime [default: ]

If set, the name of the runtime, used as the value of the RTS command line option for tools.

target [default: nil]

If set, the name of the cross-compilation target, prepended to the gnat executable name.

The following project variables are used by the Ada | Build menu commands:

check_cmd [default: ada-build-check-cmd]

Compiler command to syntax check a single file.

main [default: basename of current file name]

File name of executable to build.

make_cmd [default: ada-build-make-cmd]

Command to compile and link the application.

run_cmd [default: ada-build-run-cmd]

Command to run the application.


Next: , Previous: , Up: Top   [Contents]

6 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).

This runs xref-find-definitions, which has a default global binding of M-.

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’.

This runs forward-sexp, which has a default global binding of C-M-f.

C-c C-p

Move to the previous keyword in the current statement.

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

This runs backward-sexp, which has a default global binding of C-M-b.

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 (or when the project file is parsed, if useing cached project files). If the code is recompiled after that, the cross reference information is reloaded by invoking this menu command.


Next: , Previous: , Up: Top   [Contents]

7 Identifier completion

Emacs provides two general ways of completing identifiers while typing: M-/ (bound to dabbrev-expand), and M-tab (bound to complete-symbol.

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.

complete-symbol completes on all the symbols defined in the current project, as returned by gpr_query. For a procedure declared as:

package Package_Name is
   procedure Procedure_Name (args);

the completion string looks like:

Procedure_Name(args)<Package_Name<line>>

so for example you can type "iterate<wisitok" to complete on WisiToken iterators, or "add(Data" to complete on all subprograms whose name starts with "add" and whose first argument starts with "Data".

If you have bound hippie-expand, that also uses dabbrev-expand.

dabbrev-expand completes on all words in all open Ada files for possible completions, using simple Emacs syntax-class parsing.

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.

Another place where identifier completion is used in the xref-find-definitions (C-u M-.) and wisi-goto-spec/body (C-u C-c C-d) commands; these complete on all symbols in the project (provided by gpr_query). With two C-u, the completion is limited to symbols defined in the current file.

Note that in Ada, for subprograms that have a specification in the .ads file and a body in the .adb file, C-u C-u C-c C-d returns the spec location only, so it will not find the function if invoked in the .adb file.


8 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-after-trailing-comment (default value t)

If t, align comment lines immediately following a comment on the same line as code with the preceding comment. Otherwise, ignore the preceding comment.

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-comment-gnat (default value: nil)

If non-nil, comments are indented to meet the GNAT style check; one of:

  • multiple of ada-indent
  • next non-blank line
  • previous non-blank line

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 function on ada-mode-hook, 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.

C-c S-TAB

Indent the statement or declaration containing 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.

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


Next: , Previous: , Up: Top   [Contents]

9 Statement skeletons

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

if  then
elsif  then
else
end if;

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.


Next: , Previous: , Up: Top   [Contents]

10 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);

Next: , Previous: , Up: Top   [Contents]

11 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 casing project variable; Casing exception files in Wisi User Guide.

There are two ways to add new items to a casing exception 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. 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 a comment or string. Normally, comments and strings 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.


Next: , Previous: , Up: Top   [Contents]

12 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.


Next: , Previous: , Up: Top   [Contents]

13 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 S-TAB

See Indentation. Indent the containing 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 or string.

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.


14 Developer overview

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


Next: , Up: Developer overview   [Contents]

14.1 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.

*.ad?

Ada code for the external process parser and other tools, some generated by the WisiToken tool wisitoken-bnf-generate.exe.

*.parse_table

Diagnostic output from wisitoken-bnf-generate.exe, useful for tracing parses while debugging a grammar issue. Not in any distribution.

*.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 WisiToken documentation for more info.

*.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 external process executable, gpr-query, and the user guides; for running tests; and for publishing to the web page or Gnu ELPA. The main targets are:

elisp

Builds ada-mode in place, runs all tests.

update-elisp

Builds ada-mode in place.

install

Installs executables in the GNAT executable directory.

pub

Builds the ELPA packages.

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 wisi-run-indent-test.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 the examples in this user guide.

test/gpr

Tests for gpr mode.

test/subdir

More tests; allows testing path search features.


14.2 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.


Previous: , Up: Developer overview   [Contents]

14.3 Savannah

The ada-mode git repository, web page, mailing list, and tarball download are hosted on savannah.non-gnu.org, project Emacs Ada mode (https://savannah.nongnu.org/projects/ada-mode/). See the project admin page there for more information.

To checkout all source required to build and test ada-mode, assuming you have ssh read/write git access to savannah ada-mode:

git clone [email protected]:/srv/git/ada-mode.git \
    -b org.emacs.ada-mode org.emacs.ada-mode
cd ada-mode
git worktree add -b org.emacs.wisi ../org.emacs.wisi origin/org.emacs.wisi
git worktree add -b org.wisitoken ../org.wisitoken origin/org.wisitoken
git worktree add -b org.stephe_leake.sal ../org.stephe_leake.sal origin/org.stephe_leake.sal
git worktree add -b org.stephe_leake.aunit_ext ../org.stephe_leake.aunit_ext origin/org.stephe_leake.aunit_ext
git worktree add -b org.stephe_leake.makerules ../org.stephe_leake.makerules origin/org.stephe_leake.makerules

In each worktree, there is a build directory containing the Makefile and all build outputs. The target ’all’ runs all tests and build documentation for that worktree.


Previous: , Up: Top   [Contents]

Appendix A GNU Free Documentation License

Version 1.3, 3 November 2008
Copyright © 2000, 2001, 2002, 2007, 2008, 2009 Free Software Foundation, Inc.
https://fsf.org/

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
  1. PREAMBLE

    The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

    This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

    We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

  2. APPLICABILITY AND DEFINITIONS

    This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

    A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

    A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

    The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

    The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

    A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.

    Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

    The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.

    The “publisher” means any person or entity that distributes copies of the Document to the public.

    A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.

    The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

  3. VERBATIM COPYING

    You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

    You may also lend copies, under the same conditions stated above, and you may publicly display copies.

  4. COPYING IN QUANTITY

    If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

    If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

    If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

    It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

  5. MODIFICATIONS

    You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

    1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
    2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
    3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
    4. Preserve all the copyright notices of the Document.
    5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
    6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
    7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice.
    8. Include an unaltered copy of this License.
    9. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
    10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
    12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
    13. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
    14. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
    15. Preserve any Warranty Disclaimers.

    If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.

    You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

    You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

    The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

  6. COMBINING DOCUMENTS

    You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

    The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

    In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”

  7. COLLECTIONS OF DOCUMENTS

    You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

    You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

  8. AGGREGATION WITH INDEPENDENT WORKS

    A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

    If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

  9. TRANSLATION

    Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

    If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

  10. TERMINATION

    You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.

    However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

    Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

    Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.

  11. FUTURE REVISIONS OF THIS LICENSE

    The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See https://www.gnu.org/copyleft/.

    Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.

  12. RELICENSING

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site.

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.

    “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.

    An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.

    The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

  Copyright (C)  year  your name.
  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, no Front-Cover Texts, and no Back-Cover
  Texts.  A copy of the license is included in the section entitled ``GNU
  Free Documentation License''.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with…Texts.” line with this:

    with the Invariant Sections being list their titles, with
    the Front-Cover Texts being list, and with the Back-Cover Texts
    being list.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.