Table of Contents:
Whats New?
Introduction
ELSE
Commands
Supported
Languages
Compatibility
Customisation
Known
Limitations
Things
to do
Installation
Download
ELSE is a minor mode for Emacs and will co-exist with any major mode. ELSE is intended to offer language sensitive editing support for the current buffer. 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.
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.
Providing full support for a language is a very big job (to do 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 :-)).
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 officila distribution.
Compatibility
ELSE now uses custom variables (Custom group can be found under Programming
- Tools - ELSE) and is thus incompatible with versions earlier than 20.1.
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.
I am currently working with some people who are developing programming tools for programmers with RSI (see http://ii2.ai.iit.nrc.ca/VoiceCode/ ), so there are some changes in this release and I expect there will be some fine tuning over the coming period - so watch this space :-)
1. Unzip or untar the distribution 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"):
* else-mode.el |
|
Emacs ELSE minor mode. |
* setnu.el | unknown | Line numbering support package used by else-mode.el - thanks to Kyle E. Jones. |
* else.info |
|
Info file that describes the use of else-mode.el. (Users manual). |
else.texi |
|
TexInfo version of the ELSE info file. |
else.pdf |
|
PDF version of the Users manual. |
Ada83.lse |
|
Language Template file for Ada83, rename to Ada.lse for use with ada-mode. |
Ada83-cust.lse |
|
Example(optional) customisation file for the Ada83 Language Templates,
rename to Ada-cust.lse for use with ada-mode |
Ada95.lse |
|
Language Template file for Ada95, rename to Ada.lse for use with ada-mode. |
Ada95-cust.lse |
|
Example(optional) customisation file for the Ada95 Language Templates,
rename to Ada-cust.lse for use with ada-mode. |
C.lse |
|
Language Template file for use with cc-mode. |
C-cust.lse |
|
Example(optional) customisation file for the C Language Templates. |
Emacs-Lisp.lse |
|
Language Template file for use with Emacs-Lisp-mode. |
LaTeX.lse |
|
Language Template file for LaTeX-mode. |
LaTeX-cust.lse |
|
Example(optional) customisation file for the LaTeX Language Templates. |
Python.lse |
|
Language Template file for Python-mode. |
template.lse |
|
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. |
else-mode.el | BETA | This is a beta version of ELSE that contains support for multiple auto substitutions. |