TOC PREV NEXT INDEX DOC LIST MASTER INDEX



The Ada Editor

The Ada editor is a powerful text editor with special features for editing Ada source files.

Note: The Ada editor is only available with Rational Apex Ada 95/83 and Rational Apex Duo.

About This Chapter

This chapter describes the Ada editor and shows how to use it. Specifically, this chapter covers the following topics:

This chapter describes the commands available from the Apex editor's File, Edit, View, Navigate, and Compile menus. The Control and Debug menus are covered in other chapters. The Control menu is examined in Using and Customizing Summit/CM and the Debug menu is described in Using the Apex Debugger.


The Ada Editor Window

The Ada editor window is similar to the text-editor window described in The Apex Editor Window

The Ada editor is used to create, view, and edit Ada source code. An Ada editor window with code is illustrated in Figure 17.

Figure 17 The Ada Editor Window

Note: The Ada editor was designed using the standard Motif text widget, so its basic editing commands are similar to those of many other Motif clients (and emacs, too). Some keystroke combinations recognized by the Apex editor are actually accelerators for the commands on the Edit menu.


Starting the Ada Editor

There are several ways to start the Ada editor. You can:


Editing Source Code

The editing commands recognized by the Ada editor are the same as those recognized by the Apex text editor described in The Apex Text Editor. By choosing commands from the Edit menu, you can:

There are two ways to execute editing commands: by choosing commands from the Edit menu and by typing keyboard shortcuts. For details, see Using the Text Editor.

Editor Modes

The Ada editor, like the text editor, is always in one of two modes: edit mode or the default read-only mode. When the editor is in edit mode, you can modify files. When the editor is in read-only mode, commands that modify files are inactive or grayed. To toggle between edit and read-only mode, select File > Edit or click the Edit button.

Searching for Text and Replacing Text

To search for text that matches a specified string in a source file, choose Search from the Edit menu or type keyboard shortcuts. You can also search for text and replace it with a different string. For details, see Selecting Text and Replacing Text.

Cutting and Pasting Text

To cut selected text from the Ada editor window and transfer it to an internal clipboard, choose the Cut command from the Edit menu. When text has been transferred from an Apex window to the clipboard, you can paste the text into windows displayed by other applications running under the Motif window manager. For more information on cutting and pasting text, see Editing Text.

To delete selected text from the edit window, choose Delete from the Edit menu or execute one of the keyboard shortcuts listed in Deleting Text from a Document.


Ada-Specific Editing

In addition to its standard text-editing features, the Apex editor offers many Ada-specific editing features. You choose commands from the editor's Compile and Navigate menus to use these features.

Ada units are made up of objects such as keywords, identifiers, statements, and declarations. These objects are arranged in a hierarchical structure and are related to each other in various ways. The Apex editor is designed to recognize the structure of Ada objects and the relationships that Ada objects have with each other, and to offer special browsing, selecting, formatting, and error-checking commands for Ada units.

Browsing

With the Ada editor, you can browse through interdependent Ada units in the same way you might browse through a printed cross-reference listing. However, with Apex, no listing is required; browsing is interactive and automatic. Browsing is useful, for example, when you are:

Coloring

The default Ada object editor now does both language coloring and "as you type casing". These can be turned off by setting the APEX_NO_ADA_LANGUAGE_MARKS and APEX_NO_AS_YOU_TYPE_CASING environment variables to true.

The casing is consistent with the pretty printer switches. Currently only the Ada object editor does language coloring. The C/C++ editor does not do this.

The new color scheme is consistent with the color scheme used with Apex NT and with other environments such as MSVC++. Language constructs (keywords, strings, comments, etc.) have a foreground color with a white background while messages and prompts have a background color and a white foreground.

Here are the default settings for the common constructs:

Messages and Prompts
white foreground
Error Messages
red background
Warning Messages
orange background
Text Messages
blue background
Prompts
dark grey background (as before)
Language Colors
white background
Comments
darkgreen foreground
Keywords
blue foreground
Strings
brown foreground
Character Constants
brown foreground (same as strings)
Number Constants
DarkKhaki foreground (not implemented for Ada)
Braces
CadetBlue foreground (not implemented for Ada)
Preprocessor Lines
red foreground (not implemented for Ada)

Traversing

To traverse Ada objects, place the cursor on an object and select one of the following Visit or Visit In Place commands (for more information on the Visit or Visit In Place commands, see Using and Customizing the GUI),

For example, to traverse to the defining occurrence of a program object such as a subprogram, variable, or type:

1 . Place the cursor on any occurrence of the object.

2 . Choose the Navigate > Visit command. (Visit is also available on the button bar and pop-up menu.)

Note that browsing operations depend on semantic information about your Ada units that is collected during semantic analysis. If you have difficulty browsing because you have made changes since the last time you analyzed a unit, select Compile > Analyze and then try browsing again.

Viewing the Usage of Ada Objects

When you execute commands available from the Compile menu, you can find:

The commands for viewing the usage of Ada objects are:

By default, all three of the commands listed above display dialog boxes that let you specify Ada items. Alternatively, you can execute each of these three commands as a "just-do-it" command by holding down the Shift key while you choose the command you want to execute. (For more information on "just-do-it" menu items, see Using and Customizing the GUI.)

Table 12 lists the effects of executing the Show Usage, Local Usage, and Show Unused commands:

Table 12 Show Usage, Local Usage, and Show Unused Commands
Command
Default behavior
Optional behavior
Show Usage...
Displays a dialog box that lets you specify an Ada item, with the scope being the current view. Apex then highlights each usage of the specified item in the desired scope.
Displays the usage of the selected item in the scope of the current view.
Local Usage
By default, this is a "just-do-it" command that displays the usage of the selected item in the scope of the current unit and its body and subunits
Displays a dialog box that lets you specify an Ada item, with the scope of the item being the current unit, body, and subunit. Apex then highlights each usage of the specified item in the desired scope.
Show Unused...
Displays a dialog box that lets you specify an Ada unit, with the scope being the current view. Apex then highlights each unused declaration in that unit in the desired scope.
As a "just-do-it" command, displays unused declarations in the current unit in the scope of the current view.

When you execute one of the commands listed in the above table, Apex highlights each occurrence it finds. You can then traverse from one occurrence to another by clicking the Message -> button or the Message <- button in the Apex editor's button bar.

If many units reference an object, Apex displays a window listing all such units. You can then visit each unit in turn and click Message -> or Message <- to traverse between references.

Ada-Specific Selection Commands

Some of the selection commands available in the editor are Ada-specific. The Ada-specific selection commands are listed in Table 13.

Table 13 Ada-Specific Selection Commands
Command
Function
Control-¨
Parent —— Selects successively larger groups of Ada objects
Control-Æ
Child —— Selects successively smaller groups of Ada objects
Control-¦
Previous sibling —— Selects previous Ada object that is at same level
Control-Ø
Next sibling —— Selects next Ada object that is at same level

As an illustration of how Ada-specific selection commands work, consider the following Ada code fragment:

Assume the cursor is on the word Level in the statement Check (Level) and that no previous selections exist. Pressing Control-¨ repeatedly has these results:

After all this has taken place, Control-¦ and Control-Ø move the selection from one when alternative to another. Continuing to press Control-¨ has these results:

Ada-Specific Commands

Several commands available from the Compile menu make the formatting of Ada units easier and more convenient.

These are the Ada-specific formatting commands available from the Apex editor's Compile menu:

Pretty Printing

The Apex Ada pretty printer adjusts the following in your code:

The default pretty printer settings can be modified by changing the values of the pretty-printing switches. These switches are listed in Table 14 . Note that all these switches are only valid in Ada views.

Table 14 Pretty Printing Switches
Switch
Description
Default
BREAK_INDENT
Specifies the number of columns to indent the second and subsequent lines of a statement when either the statement has to be broken because it is longer than the line length, or there is no lexical construct with which the indented code can be "naturally" aligned
3
IDENTIFIER_CASE
The case to use for identifiers (procedure, function, and variable names). The default, Capitalized capitalizes the first letter and letters that follow underscores.
Capitalized
INDENTATION
The number of columns to indent nested constructs such as if, case, and loop statements.
4
KEYWORD_CASE
The case of reserved words, for example: package, procedure, begin, end, if, then, else, and so on
lower
LINE_LENGTH
The number of columns per line. Longer statements are broken and continued on subsequent line
80
MANUAL_PRETTY_PRINTING
Apex should do pretty-printing. When the value is False (the default), Apex does pretty-printing. When True, Apex leaves programs the way you enter them.
False
MINIMAL_BREAKING
Control the formatting of lists of the forms: (X: T1; Y: T2), as in subprogram formal parts and discriminants in type declarations or (X => P_One, Y => P_Two), as in subprogram calls and aggregates

When the value is False and a list does not fit on a line, every element of the list is placed on a new line. When True and a list does not fit on a line, as many elements as fit are placed on each line.

False
NUMBER_CASE
The case of numbers, for example: 16#ABC# and 123E+1.
Upper
PRESERVE_WHITESPACE
Used for preserving manually inserted spaces. When True, this can be used to align colons, arrows, parameters, etc. When False, more than one blank space is compressed into one blank space.
False
REPLACE_TABS_WITH_BLANKS
Use spaces instead of tabs when indenting. When the value is False, tabs are used. When True, spaces are used.
False
TAB_SIZE
The number of spaces in a tab interaction with a text widget.
8

The pretty printer is invoked using the Compile > Pretty_Print command from the GUI, or the pretty_print command from the command line

Error Checking

When you write Ada source code using the Ada editor, you can check Ada units for syntactic and semantic errors as you edit them. The Compile > Syntax command performs syntactic checking. The Compile > Analyze command performs both semantic and syntactic checking.

When you execute the Syntax command or the Analyze command, Apex highlights any errors found. You can traverse from one error to another by clicking either the Message -> or Message <- button inside the Apex editor button bar.

For help in correcting each error that is found, you can execute the:


Semantic Completion

Overview

Semantic completion uses the semantic information (about names, visibility, types, etc.) available to the Ada editor to expand incomplete identifiers or constructs. It may be used when entering code to avoid the tedious and error-prone task of typing the parameters and components required for subprogram calls, generic instantiations, pragmas, constraints, aggregates and statements. It may also be used on existing code to normalize parameter and component lists, thereby improving the legibility of the code.

Designating Constructs to Complete

The constructs to complete may be designated either using the selection, or using the cursor.

If there is a selection, every identifier that intersects the selection is marked for completion. Also, every expandable construct that intersects the selection is marked for completion.See How Completion Works for more information.

If there is no selection, the cursor is used to determine the constructs to complete. If the cursor is on an identifier (including: immediately before or immediately after an identifier), then that identifier is marked for completion. Moreover, if the identifier is the name of a subprogram in a context where a subprogram call is legal, or the name of the generic in a generic instantiation, then the subprogram call or generic instantiation is marked for completion.

Note that in order to complete a case statement without completing any of the constructs that it contains, you must put the cursor on the reserved word "case".

At any place within an identifier, the character @ may be used as a wildcard to mean "any string of zero or more characters".

How Completion Works

Once the relevant identifiers and expandable constructs have been marked for completion, the compiler is called to check the legality of appropriate parts of the source code. When it encounters an identifier that has been marked for completion, the compiler checks the semantics of Ada. The default behavior is as follows:

The behavior of the compiler can be controlled by using the Completion Options dialog box described below.

After the compiler has analyzed the constructs to complete, the Ada editor first processes the identifiers marked for completion, and then the expandable construct.

Completion of Identifiers

For each identifier, all the candidate resolutions found by the compiler are considered. If there is only one such resolution, the identifier is completed without user intervention. If there is more than one candidate resolution, the identifier is completed by adding as many characters as possible, possibly followed by the character @ to avoid syntactic illegalities. A menu is then brought up which list, for each ambiguous identifier, the candidate declarations found by the compiler.

When users select an entry in the completion menu and hit Complete, the identifier is completed, and any expandable construct to which it belongs is completed.

For example, consider the code fragment:

When completion is run on the three assignment statements, it yields:

and a menu is brought up which lists the possible choices for the (incomplete) identifiers A_Very_@ and Protected@ (there are two instances of the latter).

Note that type information was used to disambiguate the second assignment. Also, note the @ character that was added to the end of the names in the first and third assignment; that's necessary because a name ending with an underscore is illegal, and because protected is a reserved word (in Ada 95).

Completion of Expandable Constructs

Once the identifiers have been unambiguously resolved the expandable constructs are processed. The constructs that are considered expandable by completion are the following:

The remainder of this section illustrates a few examples of completion, assuming that the behavior of completion is not modified using the Completion Options dialog box.

Completion of Subprogram Calls

In the following example, Ada.Text_IO.Create, Ada.Text_IO.Put and Ada.Streams.Stream_IO.End_@ are considered candidates for procedure calls and function calls, even though their name is incomplete and their parameters do not match the profile of any of the candidate subprograms:

When completion is run on the statement part of this unit, the calls to Create and End_@ are immediately completed:

Note that default values are provided for the parameters Mode, Name and Form in the call to Create. These default values come from the declaration of the subprogram Create.

In addition, a menu is brought up, which lists the possible completions of Put (there are six such completions: four named Put and two named Put_Line). If the user selects the first choice and hits Complete, the source text is changed to:

Completion of Generic Instantiations

In the following example the name G unambiguously refers to the preceding generic declaration:

When completion is run on the generic instantiation, a parameter part is created as follows:

Note that named associations are not usable for the first three parameters, because of the overloaded "-" operators. Also note that the default for parameter "*" (a box) is used to build an actual parameter in the instantiation.

Completion of Record Aggregates

In the following example we have a variant record type declaration, and two aggregates for that record type:

When completion is run on the first aggregate, the (static) value True for the discriminant D is used to select the proper variant, and a complete aggregate is generated:

When completion is run on the second aggregate, the prompt [id] is not sufficient to select a variant in type T, and a partial aggregate is generated, containing only the components which are not part of a variant:

If the prompt [id] is then filled with a static value, e.g., False, running completion again produces a complete aggregate:

Note that default values are provided for some of the components. These default values come from the declaration of the corresponding component.

Completion of Array Aggregates

The following example demonstrates the completion of both positional and named array aggregates:

If completion is run on the first aggregate, the Ada editor notices that the aggregate doesn't cover a contiguous range of indices, and it add a named association for the missing choices:

When completion is run on the second aggregate, each positional association is turned into a named association for the proper index:

Completion of Pragmas

In the following example the name P unambiguously refers to the preceding subprogram declaration:

When completion is run on the pragma, a parameter part is created as follows:

Completion of Discriminant Constraints

The following example demonstrates the completion of discriminant constraints. Type R has three defaulted discriminants, but the declaration of X only provides a constraint for the first one:

When completion is run on the declaration of X, the positional association for D1 is turned into a named association, and two new named associations are added for D2 and D3. The actual values provided in the constraint for D2 and D3 correspond to the defaults appearing in the record type declaration:

Completion of Index Constraints

The following example demonstrates the completion of index constraints. Type A has two dimensions, but the declaration of Y1 doesn't provide any index constraints, and the declaration of Y2 only provides a constraint for the first dimension:

When completion is run on the declarations of Y1 and Y2, two index constraints are added for Y1, and a constraint for the last dimension is added for Y2. Since there is no notion of default values for index constraints, prompts are generated for the bounds; the text of the prompt indicates the expected subtype of each expression:

Completion of Case Statements

The completion of case statements adds choices and alternatives to make sure that the subtype of the case expression is covered. In the following example, the case statement only covers the values Up and Top of type T:

When completion is run on the case statement, the prompt is replaced by a list of choices covering the values Down, Bottom, Charm and Strange. Completion uses ranges whenever possible to reduce the number of choices that it generates:

Note that in this case the last alternative had a single choice, which was a prompt. This caused completion to replace the prompt, rather than add a new alternative. The purpose of this behavior is to make it easy to remove an "others" choice in a case statement. Say that you start with the code:

You can select the word "others", delete it, and format the image. This effectively replaces "others" with the prompt "[expression]". Running completion on the case statement causes the prompt to be replaced by the appropriate choices. Thus, it is possible to eliminate an others choice with a few mouse clicks.

If the last alternative doesn't contain a single prompt, then completion leaves it alone and adds another alternative containing the missing choices. For instance, starting from:

completion adds a new alternative to covers the choices Bottom to Strange:


Controlling the Behavior of Completion

The previous sections have described the default behavior of completion. For most uses, the default behavior is appropriate. However, there might be circumstances under which finer control over completion is useful. If the Control key is depressed while clicking on the menu item Compile > Complete, the Completion Options dialog box is brought up:

The Completion Options dialog box has six tabs, which are described in detail in the Online Reference.

Hints and Tips

Most of the time, completion will have no difficulties identifying and completing constructs. However, there are a number of guidelines that make it more likely that completion will "do the right thing".

For each identifier marked for completion, the compiler will have to consider a large number of meanings; for instance, if the identifier B is marked for completion, Boolean is a candidate that will be considered in all cases (because it's a name declared in Standard). Most of the time the compiler will be able to lift the ambiguities created by all these candidates, but in some cases it will fail. When that happens the Ada editor will be unable to complete some constructs, or will bring up inordinately long menus. This is more likely to happen if you select a large area of the program text (maybe even the entire unit), in this situation, try selecting a smaller area (e.g., only one statement or only one declaration), to reduce the number of ambiguities, or try disabling implicit wildcarding in the Completion Options dialog box.

In some cases, the Ada editor may need syntactic clues to perform the proper completion. For instance in the declaration:

the token "=" is considered to be a string literal, not the name of an operator, so it is not completed. You need to add parentheses to make it clear that the construct is intended to be a call to an operator:

Similarly a call to a member of an entry family must have two sets of parentheses; otherwise, only procedures and simple entries are considered:

While the compiler is capable of dealing with incomplete or otherwise incorrect constructs, there are limits to the illegalities that it is prepared to handle. In particular, the candidates that are considered when resolving names are essentially based on the visibility rules of Ada. This means that the proper visibility must be achieved (by means of with clauses, use clauses, renamings, etc.) for completion to work satisfactorily.

Also, completion is not going to work on constructs that are grossly illegal. For instance, an attempt to complete an array aggregate having both named and positional associations, or to complete the name of a procedure in the condition of an if statement, are bound to fail.

When completion creates expressions using the default values provided for parameters or components, it assumes that the entities referenced by the expressions are visible at the place of the call, instantiation or aggregate. If this is not the case, with clauses may have to be added. Consider for instance the code fragment:


Delimiter Alignment

Starting with version 4.0.2, the Apex Ada editor supports delimiter alignment. Delimiter alignment is an option of the pretty-printer, which causes lexical delimiters to be vertically aligned to improve readability of the source code.

Context Switch

Delimiter alignment is controlled by the boolean context switch ALIGN_DELIMITERS. This switch defaults to False. To enable delimiter alignment, the switch must be set to True by editing the switch file for the appropriate view(s):

Once this switch has been set, the pretty-printer, which can be invoked either by selecting Compile > Pretty Print or by Compile > Syntax, will automatically perform delimiter alignment.

Effects of Delimiter Alignment

Delimiter alignment causes the colon (:), arrow (=>) and assignment (:=) delimiters to be vertically aligned, by appropriate insertion of white space. The following code fragments show simple examples of alignment for each of these delimiters:

A given construct may contain more than one kind of delimiter, so more complex alignment patterns are possible:

Preventing Alignment

The delimiters are aligned as shown above as long as the statements or declarations form a consecutive group. If it is desirable to prevent alignment from happening for some piece of code (e.g., because it results in the insertion of too much white space), it is possible to do so by inserting a blank line. In the example above, the presence of the word "constant" in the declaration of Un causes the insertion of lots of white space in the declarations of Deux and Trois. This can be avoided by inserting a blank line before the declaration of Deux:

With this change we now have two groups of declarations where the delimiters are independently aligned.

Effect of Large Statements or Declarations

In order to avoid aligning the delimiters of statements or declarations which are separated by hundreds of lines of code, the pretty-printer breaks alignment groups when it encounters a "large" statement or declaration. Consider the following variation of one of the simple examples shown above:

Because case statements are generally large statements which may contain tens or hundreds of lines of code, it would not make sense to align the assignment delimiters for the assignment to Un with those for the assignments to Deux and Trois: the resulting presentation would probably be unappealing and surprising. Therefore, a case statement acts as a separator for alignment purposes, regardless of the occurrence of blank lines.

Exactly what statements and declarations are considered "large" is the subject of a heuristic decision, but the general rule is that compound statements and nested declarative parts are all large for alignment purposes.


Rational Software Corporation 
http://www.rational.com
support@rational.com
techpubs@rational.com
Copyright © 1993-2002, Rational Software Corporation. All rights reserved.
TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS