Welcome to the

Emacs Language Sensitive Editor (ELSE)

Home Page



Please note that this page is currently under construction, any suggestions or comments are welcome. Please send comments to peter.milliken@gtech.com.

Table of Contents:
    Whats New?
    Introduction
    ELSE Commands
    Supported Languages
    Compatibility
    Customisation
    Known Limitations
    Things to do
    Installation
    Download
 

Whats New?

  1. Several new features are worth mentioning here. ELSE now has support for "customising" language templates without having to change the main language template file (allows compatibility back to this site, if desired). The user should now make any customisation changes in the file <language>-cust.lse where <language> is the major mode name i.e. Ada-cust.lse.
  2. Followed the minor mode recommendations of Emacs Lisp for key bindings i.e. C-c / e will perform an else-expand-placeholder command - see the documentation for the rest of the keybindings.
  3. Hooks added for enhanced usability with the enabled major mode i.e. if the functions are available then ELSE can now run things like adjust-case functions prior to executing a movement command, or run a function to indent each line as the template is inserted etc - see documentation on custom variables.
  4. Support for Ada95 and Python (Python template files should be considered "experimental" at the moment - please register your interest with me and I will email regular updates as I start to use these templates.
  5. Prompt and Menu windows now shrink to either the number of lines to be displayed or half of the current window, whichever is smaller.
  6. Added a number of "usability" features which are controlled by custom variables for support of VR programming efforts.


Introduction

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 Commands

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.

Supported Languages

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.

Customisation

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

Known Limitations

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.

Things to Do

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 :-)

Installation Instructions

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
v1.14
Emacs ELSE minor mode.
* setnu.el unknown Line numbering support package used by else-mode.el - thanks to Kyle E. Jones.
* else.info
v1.2.1
Info file that describes the use of else-mode.el. (Users manual).
 else.texi
v1.2.1
TexInfo version of the ELSE info file.
 else.pdf
v1.2.1
PDF version of the Users manual.
 Ada83.lse
v1.3
Language Template file for Ada83, rename to Ada.lse for use with ada-mode.
 Ada83-cust.lse
v1.3
Example(optional) customisation file for the Ada83 Language Templates,
rename to Ada-cust.lse for use with ada-mode
 Ada95.lse
v1.3
Language Template file for Ada95, rename to Ada.lse for use with ada-mode.
 Ada95-cust.lse
v1.3
Example(optional) customisation file for the Ada95 Language Templates,
rename to Ada-cust.lse for use with ada-mode.
 C.lse
v1.6
Language Template file for use with cc-mode.
 C-cust.lse
v1.3
Example(optional) customisation file for the C Language Templates.
 Emacs-Lisp.lse
v1.2
Language Template file for use with Emacs-Lisp-mode.
 LaTeX.lse
v1.7
Language Template file for LaTeX-mode.
 LaTeX-cust.lse
v1.6
Example(optional) customisation file for the LaTeX Language Templates.
 Python.lse
v1.3
Language Template file for Python-mode.
 template.lse
v1.4
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.