contact: peterm@resmed.com.au
Table of Contents:
Introduction
Abbreviations
ELSE_Commands
Compatibility
Customisation
Known_Limitations
Things_To_Do
ELSE is a minor mode for Emacs and will co-exist with any major mode. As such ELSE is intended to offer language sensitive editing support for the current buffer and can thus be used to generate code in several different languages during the same edit session. Use of ELSE is not restricted to use with programming languages, it can be used in any editing situation that requires the entry of information into a form like structure (that's all coding is, after all :-)). Examples are program language constructs, project file headers, project function/procedure headers etc.
ELSE works by loading a specific language template file (it derives the name of the file to look for from the name of the major mode in effect for the current buffer). A typical edit session can have multiple files open for multiple languages, ELSE will enable the appropriate language template for each language eg a user could be writing a C program in one buffer and an Ada program in another.
A typical ELSE language template (Ada) looks like this:
if
{condition} then
{statement}...
[elsif_part]...
[else_part]
end if;
Commands are available to move between the placeholders (items enclosed by {}'s and []'s) ie else-next-placeholder, else-previous-placeholder. Placeholders may be expanded (else-expand-placeholder) with one of three possible results:
1. Straight substitution of text eg expanding the "else_part" placeholder will leave:
if
{condition} then
{statement}...
[elsif_part]...
else
{statement}...
end if;
2. If there is more than one possibility from the language syntax then a menu of possible selections will be offered. eg expansion of the "statement" placeholder will provide the following menu (full list has been shortened for brevity):
{assignment_statement} -
{if_statement} -
{case_statement} -
{loop_statement} -
.
.
{select_statement} -
So, if the user selects the "case_statement" alternative, then the following would be the result:
if
{condition} then
case {expression} is
{case_statement_alternative}...
end case;
[statement]...
[elsif_part]...
else
{statement}...
end if;
Note in this example that the "statement" placeholder was repeated at the end of the expansion? (now in []'s rather than {}'s). This is because it was followed by an ellipse (...). ELSE interprets an ellipse after a placeholder as a command to "repeat" the placeholder, this is how repeating parts of the language syntax is catered for.
3. If this is a "terminal" placeholder, ie there are no further paths or options, then a prompt string is displayed for 3 seconds to the user eg. if the "expression" placeholder was expanded then the following prompt would be seen:
"Enter a valid expression
eg.
"
"VOLUME, not DESTROYED, 2*LINE_COUNT, -4.0, -4.0 +
A
"
"B**2 - 4.0*A*C, PASSWORD(1 .. 3) =
"BWV",
"
"COUNT in SMALL_INT, COUNT not in SMALL_INT, INDEX = 0 or ITEM_HIT"
"(COLD and SUNNY) or WARM, A**(B**C), (1 .. 10 => 0),
SUM, "
"INTEGER'LAST, SINE(X), COLOR'(BLUE), REAL(M*N), (LINE_COUNT + 10)"
If the user positions within a valid placeholder (not all text between {}'s or []'s are valid placeholders, the text string must be defined in the language template) and just starts typing then ELSE will automatically delete the placeholder string and replace it with the typed text eg. if the user positions to the "condition" placeholder and types "A = B" then the following would result:
if A = B
then
case {expression} is
{case_statement_alternative}...
end case;
[statement]...
[elsif_part]...
else
{statement}...
end if;
ELSE also supports "abbreviations" in the form of "tokens" eg if the user wishes to have "for" loop at the current location, he/she just types
for<else-expand-placeholder>
with the following result (C language construct used this time):
for ([expression];
[expression]; [expression])
{
{statement}...
}
Placeholders enclose by {}'s are mandatory entries i.e. the language syntax requires an entry at this point. Thus mandatory placeholders will not be deleted by the else-kill-placeholder command. Placeholders enclosed by []'s are optional and can thus be deleted safely. When deleting a placeholder, ELSE performs the specified housekeeping (specified in the language template definition, that is) e.g. in the following example the user has been adding alternatives into the case statement, each time the "choice" placeholder was expanded then the text "| [choice]..." was added automatically by ELSE.
case
INPUT_TOKEN is
when TOK_END | TOK_DIGIT | [choice]... =>
{statement}...
[case_statement_alternative]...
end case;
Now the user decides there is enough to cover this case, so he/she positions to the final "choice" placeholder and invokes else-kill-placeholder with the following results:
case
INPUT_TOKEN is
when TOK_END | TOK_DIGIT =>
{statement}...
[case_statement_alternative]...
end case;
Notice that not only the placeholder was deleted but also the "|"
character that preceeded it. Thus, with two keystrokes (else-next-placeholder +
else-kill-placeholder) the user has deleted "| [choice]... " and the
output now looks neat and tidy :-).
This has been a brief introduction, the ELSE manual (both info and Tex formats) has a more detailed description of its capabilities.
Most programmers, when they come looking for aids to code entry, start by looking for an "abbreviation" facility i.e. they are looking for something that will take a small unique string and generate a language construct with a single command. ELSE provides this functionality, it is called "token" expansion. An example of a token is the "if" statement expansion. Using the C language templates as an example, all the user has to type to get an if statement at some point in their code is "ifC-c / e" (C-c / e - is the keybinding for else-expand-placeholder). This key sequence provides the following text in the buffer:
if
({expression}) {
{statement}...
}
[elsif_part]...
[else_part]
ELSE positions the cursor within the first placeholder ({expression}) automatically after executing the expansion. Placeholder (text in {}'s or []'s) serve to provide navigation points for the ELSE navigation commands (else-next-placeholder and else-previous-placeholder - C-c / n and C-c / p respectively). These placeholders are textual in nature, rather than internal Emacs marker, such as offered by other template/skeleton packages available for Emacs. As such, the navigation marks or "placeholders" persist across edit sessions until they have been resolved (either by further expansion/code entry or deletion).
ELSE has the following commands:
1. Next/Previous placeholder;
2. Kill Placeholder (all "extraneous" language syntax is removed
automatically);
3. Expand placeholder (same command works for "tokens");
4. Compile placeholder/token definitions;
5. "Extract" placeholder/token definitions into current buffer for
localised modification;
6. Extract entire language definition;
7. Plus others :-), please read the manual.
Douglas Harter (dougharter@comcast.net) has very kindly made available language templates for a large number of languages. This list is growing and currently includes Bliss, Basic, Bourne Shell, C Shell, COBOL, DCL, Fortran90, Fortran, Pascal, Perl and HTML. These templates are available from http://mywebpages.comcast.net/dharter46.
Providing full support for a language is a very big job (to do it properly, that is, a "quick and dirty" hack for support of common constructs such as "if", "switch" and "loop" statements can be done relative quickly (1 - 2 hrs), less if using a base from another set of language templates). The following language templates are available, some are extremely brief but will give good examples of what can be done.
C, Ada (both 83 and 95), Latex, Emacs-Lisp, Python and ELSE Templates (of course :-)). There is some work in progress for C++ template definitions - I don't program in C++ and hope never to be forced into this position, so I have generated a base set from the EBNF and others have started to "run with the ball" on this one. As they produce updates, I will place the changes on this site (or point you to their site :-)). I have also generated a basic set of Java templates, anyone interested in runing with these are more than welcome to apply for the job :-).
The Ada83 templates are the most "complete". For the past couple of years, I have been a parasite on human society (manager :-)), so have had little time to indulge in my hobby of programming. I am now a Senior Software Engineer (geez, it feels nice to be a productive, useful human being again) and have been programming in Ada for about 12 months now. The Ada83 templates were produced from the EBNF in the Language Reference Manual and then "used in anger". So, many of the constructs have been tested through use, some portions are still as generated from the LRM syntax (tasking for instance) since I have not had a chance to use these constructs and thus make the minor corrections to make them useful and seemless i.e. currently a task declaration template will expand to the following:
task [type] {task_simple_name} [is is_task_part];
Unfortunately, the next step of expanding the "is is_task_part" will give this:
task
[type] {task_simple_name} is [entry_declaration]...
[representation_clause]...
end [task_simple_name];
Note very pretty :-). So, some thought and changes have to be made for this template definition. This is an example of some of the currently known deficiencies in the Ada language templates, not serious because the construct is not used often and when it is then the minor hassle of fixing it manually is quite acceptable.
The ELSE distribution now includes a set of language templates for Ada95. These where developed when I moved to an Ada95 project and have seen approximately 4 months use. They are reasonable but there are "holes" where the templates still reflect the LRM EBNF rather than any more usable structure that a programmer might find convenient. I have moved out of Defence, so don't anticipate ever getting back to fixing these templates up, so if anyone makes any changes, please let me know and I will add them to the official distribution.
Compatibility
ELSE now uses custom variables (Custom group can be found under Programming -
Tools - ELSE) and is thus incompatible with versions of Emacs earlier than 20.1.
ELSE *should* work with XEmacs. I did convert it at one stage and got it
working but I am not an XEmacs user, so it is possible that changes I make may
"break" it for XEmacs. Please provide feedback if you find it not
working and if I have the time I will get it working for you :-).
Language templates can be customised very easily. ELSE templates come as ASCII text files, definitions can be changed directly in the language template file or (and this is the recommended approach), definitions are appended to the end of the individual template file. The structure of a typical template definition is:
DELETE
PLACEHOLDER IF_STATEMENT -
/LANGUAGE="Ada" -
DEFINE PLACEHOLDER
IF_STATEMENT -
/LANGUAGE="Ada" -
/NOAUTO_SUBSTITUTE -
/DESCRIPTION=""
/DUPLICATION=CONTEXT_DEPENDENT -
/SEPARATOR="" -
/TYPE=NONTERMINAL -
"if {condition} then"
" {statement}..."
"[elsif_part]..."
"[else_part]"
"end if;"
END DEFINE
Notice the pattern is "DELETE PLACEHOLDER X -" and then "DEFINE PLACEHOLDER X -", thus any new definition will ALWAYS override any existing definition (as an example, the Ada template file has a bug, it has two definitions of FILE_HEADER, I didn't realise until a Beta tester pointed it out, the second definition always overrode the first and so I never noticed it :-)).
The "task declaration" problem mentioned earlier is fixed by the following definitions:
DELETE
PLACEHOLDER TASK_DECLARATION -
/LANGUAGE="Ada" -
DEFINE PLACEHOLDER
TASK_DECLARATION -
/LANGUAGE="Ada" -
/NOAUTO_SUBSTITUTE -
/DESCRIPTION=""
/DUPLICATION=CONTEXT_DEPENDENT -
/SEPARATOR="" -
/TYPE=NONTERMINAL -
"task [type] {task_simple_name}"
"[is is_task_part];"
END DEFINE
DELETE
PLACEHOLDER "IS IS_TASK_PART" -
/LANGUAGE="Ada" -
DEFINE PLACEHOLDER
"IS IS_TASK_PART" -
/LANGUAGE="Ada" -
/NOAUTO_SUBSTITUTE -
/DESCRIPTION=""
/DUPLICATION=CONTEXT_DEPENDENT -
/SEPARATOR="" -
/TYPE=NONTERMINAL -
"is "
"{is_task_part}"
END DEFINE
DELETE
PLACEHOLDER IS_TASK_PART -
/LANGUAGE="Ada" -
DEFINE PLACEHOLDER
IS_TASK_PART -
/LANGUAGE="Ada" -
/NOAUTO_SUBSTITUTE -
/DESCRIPTION=""
/DUPLICATION=CONTEXT_DEPENDENT -
/SEPARATOR="" -
/TYPE=NONTERMINAL -
" [entry_declaration]..."
" [representation_clause]..."
"end [task_simple_name]"
END DEFINE
ELSE has the following (known) limitations:
1. Currently supported templates do not have "descriptions" and "prompts". Descriptive strings should be available when a menu is displayed for each item, I just haven't typed in the strings, no time :-). Prompts - same problem, a standard prompt has been generated that is something like "XXXX is not implemented", this message is generated automatically by a program I have written which takes a language specification in EBNF and spits out ELSE templates at the other end.
Nothing currently planned – for some considerable time, this section described the potential addition of ELSE being able to run elisp as part of the template expansion – this has now been incorporated in ELSE, see the manual relating to the /RUN_CODE attribute.
1. Download the appropriate files (as shown in the Table below) and place the files somewhere in your Emacs load path (I use site-lisp). Note that the case of the language file names are important! ELSE appends an extension to the major mode name found in the mode line ie C.lse or LaTeX.lse, so if you get an message:
"Enter the language name (no file extensions, please):"
then this means that ELSE couldn't find the language template file.
2. Add the following to your .emacs file:
(require 'else-mode)
3. Install the help files (else.info*) into ~/info and add the following line to ~/info/dir:
* ELSE: (else.info). ELSE mode.
4. Read the documentation for best results :-)
Download
The following files are available for download, those listed with an '*' are
essential baseline files, others are optional (note that if you have trouble
downloading any of these files just right click and choose "Save Link
As"). Note that custom language definition files (files of the form
<lang>-cust.lse) are loaded after the primary language definition
file (<lang>.lse) and are meant to contain template definitions that override
definitions in the primary definition file - therefore you should examine and
use any of the custom definition files with care as they contain my personal
customisations and are included here only as examples of how those files
may be used.
For templates other than those listed here, a good site is http://mywebpages.comcast.net/dharter46. This site is maintained by Douglas Harter (dharter46@comcast.net) and contains a steadily growing set of language templates. Many thanks to Douglas for making these templates available.
|
1.21 |
Emacs ELSE minor mode. |
|
|
Unknown |
Line numbering support package used by else-mode.el - thanks to Kyle E. Jones. |
|
|
1.0 |
An alternate to abbrev-mode. Required by ELSE for auto-completion of TOKENs. See the manual – this is an excellent alternative to abbrev-mode and can be used as a separate utility to ELSE. |
|
|
1.6 |
Info file that describes the use of else-mode.el. (Users manual). |
|
|
1.6 |
TexInfo version of the ELSE info file. |
|
|
1.6 |
PDF version of the Users manual. |
|
|
1.5 |
Language Template file for Ada83, rename to Ada.lse for use with ada-mode. |
|
|
1.4 |
Example (optional) customisation file for the Ada83
Language Templates, |
|
|
1.5 |
Language Template file for Ada95, rename to Ada.lse for use with ada-mode. |
|
|
1.4 |
Example (optional) customisation file for the Ada95
Language Templates, |
|
|
1.14 |
Language Template file for use with cc-mode. |
|
|
1.9 |
Example(optional) customisation file for the C Language Templates. |
|
|
1.9 |
Language Template file for use with Emacs-Lisp-mode. |
|
|
1.10 |
Language Template file for LaTeX-mode. |
|
|
1.7 |
Example (optional) customisation file for the LaTeX Language Templates. |
|
|
1.10 |
Language Template file for Python-mode. |
|
|
1.1 |
Example (optional) customisation file for the Python Language Templates. |
|
|
1.8 |
Language Template file for creating new templates i.e. the "programming" language that ELSE uses! There is no associated major mode for this file. User must supply the file name when prompted by ELSE - see users manual on loading template files that are not automatically recognised. |
|
|
|
1.4 |
Example (optional) customisation file for the Template Language Templates. |
|
0.9 |
Generated directly from EBNF - not considered good examples of ELSE language definitions at all! Use at your own risk and don't blame ELSE for their shortcomings :-) They are placed here for anyone who wants a "start". If you take the challenge then please provide feedback for others to use. |
|
|
|
1.1 |
Example (optional) customization file for the Java Language Templates. |
|
0.2 |
Read the blurb for Java.lse |
|
|
0.1 |
Customisations kindly donated and produced by Stephen Leake. |