Utah Symbolic Computation Group                         June 1982
Operating Note No. 69









                        A Guide to EMODE
                        A Guide to EMODE
                        A Guide to EMODE

                               by

              William F. Galway and Martin L. Griss

                 Department of Computer Science
                       University of Utah
                   Salt Lake City, Utah  84112

                 Last Revision: 31 January 1983














                            ABSTRACT
                            ABSTRACT
                            ABSTRACT


EMODE  is  a  LISP-based  EMACS-like  editor that runs on the PSL
system.  This document is meant to serve  as  a  guide  to  using
EMODE--but  will  only be roughly up to date, since the system is
in a state of transition.








Work supported in part by the National Science  Foundation  under
Grant No.  MCS80-07034.
Guide to EMODE                                                  1


1. Introduction and Acknowledgments
1. Introduction and Acknowledgments
1. Introduction and Acknowledgments

     This  paper  describes  the EMODE editor being developed for
PSL [Griss 81].  EMODE is an  interactive,  EMACS  like [Stallman
81a],  screen  editor.    EMODE  provides  multiple  windows, can
simultaneously support different "modes" of editing in  different
buffers,  and  supports  a  variety  of CRT terminals such as the
Teleray 1061 and the DEC VT-100.


     Several people have made  contributions  to  EMODE.    EMODE
itself  is  based  on  an  earlier  editor  EMID [Armantrout 81],
written by Robert Armantrout and Martin Griss for LISP 1.6.  Tony
Carter has used EMODE to develop several large packages for  VLSI
circuitry  design [Carter  81, Carter 82].  Optimizations for the
Vax version, and many useful comments, have been provided by Russ
Fish.  Several features have been added by Alan Snyder  and  Cris
Perdue  at  Hewlett  Packard Research Labs.  Cris implemented the
current version of "mode lists", while  Alan  has  implemented  a
huge  number  of  commands and improved the efficiency of several
operations.



2. Running EMODE
2. Running EMODE
2. Running EMODE

     EMODE is available as a "loadable" file.  It can be  invoked
as follows:

    @PSL:RLISP
    [1] load emode;
    [2] emode();


     Of   course,  you  may  choose  to  invoke  RLISP  (or  PSL)
differently, and to perform other operations before  loading  and
running EMODE.  From this point on the term "PSL" will be used to
refer  to  this  family of systems, independently of whether they
use Lisp or RLISP syntax.


     The terminal that EMODE uses by default is determined by its
LOADing the file DEFAULT-TERMINAL.  At  the  University  of  Utah
this  is  the  TELERAY driver.  At other sites, some other driver
may be chosen as the default.  To use a  different  terminal  you
must  LOAD in a different "driver file" after loading EMODE.  For
example, to run EMODE on the Hewlett Packard 2648A terminal,  you
could type:

    @PSL:RLISP
    [1] load emode, hp2648a;
    [2] emode();
Guide to EMODE                                                  2


     The following drivers are currently available:

AAA             For the Ann Arbor Ambassador.
DM1520          For the Datamedia 1520.
HP2648A         For the Hewlett Packard 2648A and similar Hewlett
                Packard terminals.
TELERAY         For the Teleray 1061.
VT52            For the DEC VT52.
VT100           For the DEC VT100.

See section 9 for information on creating new terminal drivers.


     EMODE  is  quite  similar  to  EMACS [Stallman 81b, Stallman
81a], although it doesn't  have  nearly  as  many  commands.    A
detailed  list  of  commands  is  given  in  appendix  I.    This
information can also be  obtained  by  typing  "HELP  EMODE;"  to
RLISP, or (equivalently) by reading the file PH:EMODE.HLP.


     The  notation  used  here  to  describe  character  codes is
basically the same as that used for  EMACS.    For  example:  C-Z
means  "control-Z", the character code produced by typing Z while
holding down the control key.   The  ascii  code  for  a  control
character  is  the  same  as the 5 low order bits of the original
character--the code for Z is 132 octal, while the code for C-Z is
32 octal.  M-Z means "meta-Z", the character produced by typing Z
while holding down the meta key.    To  support  those  terminals
without  a  meta key, the same result can normally be achieved by
typing two characters--first the ESCAPE  character,  then  the  Z
character.    The  ascii code for a meta character is the same as
the original character with the parity bit set--the code for  M-Z
is 332 octal.  (Some terminals use the ESCAPE character for other
purposes,  in  which  case  the  "META prefix" will be some other
character.)  Rather than using the  EMACS  convention,  we  write
"control-meta"  characters  (such  as  C-M-Z)  as  "meta-control"
characters (M-C-Z), since the latter notation better reflects the
internal code (232 octal for M-C-Z).  The C-Z character  is  used
as  a  "meta-control" prefix, so one way to type M-C-Z is to type
C-Z C-Z.  (Another way to type it is to hold down  the  meta  and
control keys and type "Z".)


     When  EMODE  is  started  up  as  described  above,  it will
immediately enter "two window mode".  To enter "one window mode",
you can type "C-X 1" (as in EMACS).  Commands can be typed into a
buffer shown in the top window.    The  result  of  evaluating  a
command  is  printed  into  the  OUT_WINDOW  buffer (shown in the
bottom window).  To  evaluate  the  expression  starting  on  the
current  line, type M-E.  M-E will (normally) automatically enter
two window mode  if  anything  is  "printed"  to  the  OUT_WINDOW
buffer.    If  you  don't want to see things being printed to the
Guide to EMODE                                                  3


output  window, you can set the variable !*OUTWINDOW to NIL.  (Or
use the RLISP command "OFF OUTWINDOW;".)    This  prevents  EMODE
from  automatically  going into two window mode when something is
printed to OUT_WINDOW.  You must still use the "C-X 1" command to
enter one window mode initially.


     Figure 2-1 shows EMODE in two window mode.  In this mode the
top window includes everything above (and  including)  the  first
line  of  dashes.    This  is  followed  by a single line window,
showing the current prompt from PSL.  Beneath this is the "output
window", the window which usually shows  the  OUT_WINDOW  buffer.
This  is followed by another single line window, which EMODE uses
to prompt the user for values (not the same as PSL's prompt).

    % Commands can be typed in the top window.
    % When they're executed the value is printed into
    % the OUT_WINDOW buffer.

    x := '(now is the time);
    y := cddr x;


    ----MAIN-----------------------------------------85%---
    [7]
    -------------------------------------------------------
    NIL
    (NOW IS THE TIME)
    (THE TIME)






    ----OUT_WINDOW-----------------------------------75%---
    File for photo: s:twowindow.photo


                  Figure 2-1:
                  Figure 2-1:
                  Figure 2-1:   Two window mode


     Figure 2-2 shows EMODE in one window mode.  The "top window"
takes up most of the screen, followed by EMODE's prompt line, and
then by PSL's prompt line.


     The BREAK handler has been modified by EMODE to "pop  up"  a
"break  window  menu".    This is illustrated in figure 2-3.  The
commands in the menu can be executed with the  M-E  command,  and
you  can  also  edit the BREAK buffer just like any other buffer.
If you wish to move to another window, use  the  C-X  N  command.
Guide to EMODE                                                  4


    % Commands can be typed in the top window.
    % When they're executed the value is printed into
    % the OUT_WINDOW buffer.

    x := '(now is the time);
    y := cddr x;













    ----MAIN-----------------------------------------85%---
    File for photo: s:onewindow.photo
    [7]


                  Figure 2-2:
                  Figure 2-2:
                  Figure 2-2:   One window mode


This  may cause the break window to disappear as it is covered by
some other window, but C-X P will find it and pop it to the "top"
of the screen again.


     EMODE is not very robust in its handling of errors.   Here's
a  summary  of known problems and suggestions on how to deal with
them:

Garbage collection messages "blow up":
                Printing messages  into  EMODE  buffers  involves
                CONSing,  so  the  system blows up if it tries to
                print  a  message   from   inside   the   garbage
                collector.    EMODE  sets  GC  OFF  at load time.
                Always run EMODE with GC OFF.

Terminal doesn't echo:
                This can be caused by abnormal exits from  EMODE.
                If PSL is still running, you can call the routine
                "EchoOn"  to  turn  echoing  back  on.  (It's the
                routine "EchoOff" that  turns  echoing  off,  and
                starts "raw output" mode.)

                Otherwise, as may happen on the Vax running Unix,
                you  will  have  to  give  shell commands to turn
Guide to EMODE                                                  5



    cdr 2;             +------------------------------+
                       |A ;% To abort                 |
                       |Q ;% To quit                  |
                       |T ;% To traceback             |
                       |I ;% Trace interpreted stuff  |
                       |R ;% Retry                    |
                       |C ;% Continue,                |
                       |   % using last value         |
    ----MAIN-----------|? ;% For more help            |-
    4 lisp break>      +----BREAK---------------11%---+
    ----------------------------------------------------
    NIL
    ***** An attempt was made to do CDR on `2', which is
     not a pair {99}
    Break loop




    ----OUT_WINDOW-----------------------------------75%---
    File for photo: s:breakwindow.photo


    Figure 2-3:
    Figure 2-3:
    Figure 2-3:   A break window (doctored from the original)


                echoing  back  on.  This is best done by defining
                the following alias in your ".login" file.

                    alias rst 'reset; stty -litout intr ^C'

                (That's a "control-C", not  "uparrow  C".)    The
                "rst"  command  must  be  typed  as "<LF>rst<LF>"
                because carriage-return processing is turned off.

"Garbled" printout:
                This is probably caused by EMODE's not running in
                "raw output" mode--a problem which can be  caused
                by  some other errors.  A cure is to type C-Z C-Z
                to leave EMODE, and then  to  call  EMODE  again.
                This should reset the terminal mode to "raw mode"
                (by  calling  EchoOff).    (The  C-Z  C-Z must be
                followed by a linefeed on the Vax, to  force  the
                C-Z C-Z to be read.)

Stuck in an error:
                This  is  often  caused  by trying to evaluate an
                expression that lacks a closing  parenthesis  (or
                some   other   terminator)--producing  a  message
                something like:
Guide to EMODE                                                  6


                    ***** Unexpected EOF while reading ...

                If  it's  obvious  that an additional parenthesis
                will cure the problem,  you  can  use  C-X  N  to
                select  the  input  window  and  insert it.  Then
                position  the  cursor  to   the   left   of   the
                parenthesis  and  use  C-X  N to select the break
                window and "Quit".

                Otherwise you should use the  "Abort"  option  of
                the  break  handler.    Currently this resets the
                terminal mode (at least on the DEC-20), so you'll
                have to restart EMODE as described  above.    The
                BREAK  window will still be present on the screen
                after restarting, even though you are  no  longer
                in  the  break  loop.    You can use the C-X 2 or
                C-X 1 command to get rid of the break window, and
                then use the C-X B command to select some  buffer
                other than the break buffer.



3. A Guide to the Sources and Rebuilding
3. A Guide to the Sources and Rebuilding
3. A Guide to the Sources and Rebuilding

     The "primary" sources for EMODE reside on UTAH-20:

PES:            Is  defined  locally  as <GALWAY.EMODE.V2>.  This
                directory is for the "version 2" of  EMODE--being
                maintained now.  The corresponding "logical name"
                on the VAX is "$pes".

PE:             Is  defined  as  <PSL.EMODE>.   Holds sources and
                documentation which may be  generally  useful  to
                the  public.  It includes sources for the various
                terminal drivers available for EMODE.    (Further
                described  in  section  9.)    The  corresponding
                logical name on the VAX is "$pe".


     The  file  PES:BUILD-EMODE.CTL  is  the  command  file   for
building  EMODE  on  the  DEC-20.    Use  SUBMIT or DO to run the
command file, which builds  EMODE  in  two  parts  on  the  local
directory:  EMODE-B-1.B and EMODE-B-2.B.  PES:BUILD-EMODE.CSH (or
$pes/build-emode.csh) is the build file for the  VAX.    It  also
builds  the  binary  files  on  the  "local  directory".  On both
machines the ".B" files for the terminal drivers and for  RAWIO.B
are built separately.


     The  PES:EMODE.TAGS  file can be used with the TAGS facility
provided by EMACS on the DEC-20.  (Highly recommended!)
Guide to EMODE                                                  7


4. Terminology:  Buffers, Views/Windows, and Virtual Screens
4. Terminology:  Buffers, Views/Windows, and Virtual Screens
4. Terminology:  Buffers, Views/Windows, and Virtual Screens

     "Buffers",  "views",  and  "virtual  screens"  are the three
major data structures  in  EMODE.    Virtual  screens  correspond
                                        _______
fairly closely to what are often called windows in other systems.
They are rectangular regions on the screen, possibly overlapping,
that  characters  can be written to.  A virtual screen provides a
sort of pseudo-hardware.  The operations that can be performed on
a virtual screen are modeled after what can be done with  a  real
terminal.  The use of a virtual screen provides these advantages:

   - Operations on a virtual screen are machine independent.
     (To  some  extent,  this will be less true if we try to
     support "fancier" graphics.)
   - The "bandwidth problem" of maintaining the screen image
     is  isolated  to  the  virtual  screen   package--other
     programs don't have to worry about the problem.
   - Several  virtual  screens  can be shown on one physical
     screen.

Virtual  screens  are  implemented   as   "Structs"   using   the
"DefStruct" facility provided by the loadable file "NSTRUCT".


     Buffers hold the data to be edited, possibly something other
than text, depending on the buffer's "data mode".  Views are data
structures  used  to  display  buffers on the screen, they may be
                                            ______
made of several virtual screens.  The term "window" is often used
instead of "view", when  you  see  the  one  term  it  should  be
possible to substitute the other.


     Buffers  and  views  are  implemented as "environments".  An
environment is an association  list  of  (NAME  .  VALUE)  pairs.
(These   association   lists   are   sometimes   referred  to  as
"descriptors".)  The usual method for working with an environment
is "restoring" (or "selecting") the environment  by  calling  the
procedure "RestoreEnv".  This sets each variable name in the list
to  its  associated  value.    The  procedure  "SaveEnv" does the
inverse operation of updating the values of each variable name in
the association list.    (This  is  done  "destructively",  using
RPLACD.)    The  names  in  an  environment  are sometimes called
"per-environment" variables.  Names in "buffer environments"  are
called   "per-buffer  variables",  and  similarly  for  "per-view
variables".


     Buffers and views are just environments that follow  certain
conventions.    These  conventions  are  that they always include
certain (name .  value)  pairs--i.e.  that  they  always  include
certain  "per-buffer"  or "per-view" variables.  For example, the
required per-buffer variables include:
Guide to EMODE                                                  8


buffers_file    The name (a string) of a file associated with the
                buffer,  or NIL if no file is associated with the
                buffer.

buffers_view_creator
                A routine that creates  a  "view"  (or  "window")
                looking into the buffer.

In  addition  to  the required per-buffer variables, text buffers
include variables containing things like the text being edited in
the buffer and the location of "point" in the buffer.


     The required per-view variables include:

windows_refresher
                (Which   should   actually    be    called    the
                "views_refresher")  defines  a  routine to be the
                refresh algorithm  for  whatever  data  structure
                this view looks into.

WindowsBufferName
                Is  the  name (an ID) of the buffer that the view
                looks into.

Views into text buffers include additional information such as  a
virtual screen to display the text in, and "cache" information to
make refreshing faster.


     The  choice  of  whether  variables  should be per-buffer or
per-view is sometimes unclear.  For example,  it  would  seem  to
make  better sense to have "point" be part of a view, rather than
a buffer.  This would allow the user to have two windows  looking
into  different parts of the same buffer.  However, it would also
require the selection of a window for  the  many  functions  that
insert  strings  into the buffer, delete strings from the buffer,
etc., since these routines all work around the  current  "point".
                                                         ____
Somehow it seems unnatural to require the selection of a view for
      ______
these buffer operations.  The current decision is to make point a
per-buffer variable.


     Further details on buffers and views for different modes are
given in section 6.


     A list of all the buffers in EMODE is stored in the variable
"BufferNames"  as  a  list of (name . environment) pairs .  These
pairs are created with the routine "CreateBuffer".
Guide to EMODE                                                  9


     A  list of "active" views in EMODE is stored in the variable
"WindowList".    This  is  simply  a   list   of   "environments"
(association  lists  as  described above).  Unlike buffers, views
are not referred to by name.   Instead,  specific  views  can  be
referred  to  by storing their environment in a variable (such as
"BreakWindow").



5. Modes and Key bindings in EMODE
5. Modes and Key bindings in EMODE
5. Modes and Key bindings in EMODE

     There are two aspects to "modes"  in  EMODE.    One  is  the
choice of the data structure to be edited within a buffer.  Until
recently  there  has only been one kind of structure: "text".  As
discussed in section 6  EMODE  now  provides  tools  for  editing
other, user defined, structures.


     The  other  aspect of "modes", discussed in this section, is
the binding of "handler" routines to terminal keys (or  sequences
of  keys for multi-key commands).  A simple version of this would
associate a table of handlers (indexed by  character  code)  with
each  buffer  (or  view).    The  method  actually  used  is more
complicated due to a desire  to  divide  keyboard  bindings  into
groups  that  can be combined in different ways.  For example, we
might have a text mode and an Rlisp mode, and  an  optional  Word
Abbreviation  Mode  that could be combined with either of them to
cause automatic expansion of abbreviations as they are typed.


                                                      _______
     Implementing optional keyboard bindings that can removed  as
          _____
well  as  added  is  difficult.    Consider the situation with an
optional "Abbreviation Mode" and an optional  "Auto  Fill  Mode".
Turning  on  either  mode  redefines  the  space character to act
differently.  In each case, the new definition for space would be
something like "do some fancy stuff for this submode, and then do
whatever space used to do".  Imagine the difficulties involved in
turning on "Abbreviation Mode" and then "Auto Fill Mode" and then
turning off "Abbreviation Mode".


     EMODE's solution to the  problem  is  based  on  the  method
                              ______  ______
suggested in [Finseth 80].  A single, global "dispatch vector" is
used,  but  is  rebuilt when switching between buffers.  The mode
for each buffer  is  stored  as  a  list  of  expressions  to  be
evaluated.  Evaluating each expression enters the bindings for an
associated  group of keys into the vector.  Incremental modes can
be added or deleted by adding or deleting  expressions  from  the
list.    Although  changing  modes is fairly time consuming (more
than a few microseconds), we assume that this is rare enough that
the overhead is acceptable.  NOTE that simply changing  an  entry
in the dispatch vector will not work--since any switching between
Guide to EMODE                                                 10


buffers will cause the entry to be permanently lost.


     The   dispatch   "vector"   is  actually  implemented  as  a
combination of a  true  PSL  vector  "MainDispatch",  indexed  by
character  code, and an association list "PrefixAssociationLists"
used to implement two character commands.  Currently the only two
character  commands  start  with  the  "prefix  character"   C-X,
although  the  mechanism  is more general.  Prefix characters are
"declared"  by  calling  the  routine   "define_prefix_character"
(refer  to  code  for  details).    Bindings for prefix-character
commands are stored in PrefixAssociationLists as  an  association
list  of  association  lists.    The  top  level  of  the list is
"indexed" by  the  prefix  character,  the  next  level  contains
(character  .  handler)  pairs indexed by the character following
the prefix character.


     The list of expressions for building the dispatch vector  is
called  the "mode list", and is stored in the per-buffer variable
"ModeEstablishExpressions".  See the following section  for  more
on  how  ModeEstablishExpressions is used in the declaration of a
mode.    The  procedure  "EstablishCurrentMode"  evaluates  these
expressions  in reverse order (the last expression in the list is
evaluated first) to establish the keyboard dispatch  vector  used
for  editing  the  current buffer.  Reverse order is used so that
    ____                           _____
the last expression added to  the  front  of  the  list  will  be
evaluated  last.    EstablishCurrentMode  must  be  called  after
changing the mode list for the current buffer and when  switching
                      ___ _______ ____ ___ ________
to a different buffer for editing from the keyboard.  The routine
SelectBuffer  switches  to  a  buffer  without "establishing" the
buffer's mode.  This saves the cost of setting  up  the  dispatch
vector when it isn't needed (which is the case for most "internal
operations" on buffers).


                                                              ___
     The  expressions in ModeEstablishExpressions can execute any
code desired.  This generality is rarely needed, the usual action
is   to   call   the   routine   SetKeys   with   a    list    of
(character . handler) pairs.  For example, the mode list for text
mode is defined by this Lisp code:

    (setf FundamentalTextMode
      '((SetKeys TextDispatchList)
         (SetKeys BasicDispatchList)
         (NormalSelfInserts)))

The  RLISP  mode  is  built  "on  top  of" FundamentalTextMode as
follows:
Guide to EMODE                                                 11


    (setf RlispMode
      (cons
        '(SetKeys RlispDispatchList)
        FundamentalTextMode))


     This    section    taken   from   the   code   that   builds
BasicDispatchList shows what a "key list" for the SetKeys routine
should look like:

    (setf BasicDispatchList
      (list
        (cons (char ESC) 'EscapeAsMeta)
        (cons (char (cntrl U)) '$Iterate)
        (cons (char (cntrl Z)) 'DoControlMeta)

        % "C-X O" switches to "next window" (or "other
        % window" if in "two window mode").
        (cons (CharSequence (cntrl X) O) 'next_window)

        (cons (CharSequence (cntrl X) (cntrl F)) 'find_file)
              .
              .
              .

Note that the pairs in a key list can specify character sequences
like "(cntrl X) O" as well as single characters.


     At runtime, after they're created, key  lists  can  be  most
easily modified by calling the routine AddToKeyList.  For example

    (AddToKeyList
      'RlispDispatchList
      (char (meta (cntrl Z)))
      'DeleteComment)

could be executed to add a new, "delete comment" handler to RLISP
mode.


     The  routine  SetTextKey  is equivalent to adding to the key
list TextDispatchList (see code).  For example

    (SetTextKey (char (meta !$)) 'CheckSpelling)

could be executed to add a new "spelling checker" command to text
mode (and other modes such as RLISP mode  that  incorporate  text
mode).    SetTextKey  seems to correspond most closely to EMACS's
"Set Key" command.
Guide to EMODE                                                 12


     The routine "SetLispKey" is also defined for adding bindings
to  "Lisp  mode".    (There is no "SetRlispKey" routine in EMODE,
although it would be easy to define for yourself if desired.)



6. Creating New Modes
6. Creating New Modes
6. Creating New Modes

     To define a new mode you must  provide  a  "buffer  creator"
routine  that  returns  a  "buffer environment" with the required
per-buffer variables  along  with  any  other  state  information
needed  for the type of data being edited.  You need to "declare"
the mode by calling the routine "declare_data_mode".   It's  also
possible  to  associate the mode with a file extension by calling
the routine "declare_file_mode".


     For example, the current EMODE declares  the  modes,  "text"
and "rlisp", as follows:

    (declare_data_mode "text" 'create_text_buffer)
    (declare_data_mode "rlisp" 'create_rlisp_buffer)

    (declare_file_mode "txt" 'create_text_buffer)
    (declare_file_mode "red" 'create_rlisp_buffer)

The  second  argument  to  both  routines is the "buffer creator"
routine for that mode.  The first argument  to  declare_data_mode
is   a   "name"   for   the   mode.      The  first  argument  to
declare_file_mode is a file extension associated with that mode.


     The conventions for  "buffer  environments"  are  that  they
always  include  certain  (name  .  value)  pairs--i.e. that they
always include certain "per-buffer" variables.   These  variables
are:

ModeEstablishExpressions
                A   list   of   expressions   to   evaluate   for
                establishing  the  keyboard  bindings   for   the
                buffer's mode.

buffers_file    The name (a string) of a file associated with the
                buffer,  or NIL if no file is associated with the
                buffer.

buffers_file_reader
                A  routine  to  APPLY  to  one  argument--a   PSL
                io-channel.   The routine should read the channel
                into the current buffer.

buffers_file_writer
Guide to EMODE                                                 13


                A routine to APPLY to an io-channel.  The routine
                writes the current buffer out to that channel.

buffers_view_creator
                A  routine  to  create  a  "view"  (or  "window")
                looking into the buffer.  This  is  described  in
                more detail below.


     For example, the buffer creator for "text mode" is:

    (de create_text_buffer ()
      (cons
        (cons 'ModeEstablishExpressions  FundamentalTextMode)
        (create_raw_text_buffer)))

Most  of  the  work is done by create_raw_text_buffer, which does
everything but determine the keyboard bindings  for  the  buffer.
Here's the code with comments removed:

    (de create_raw_text_buffer ()
      (list
        (cons 'buffers_view_creator  'create_text_view)
        (cons
          'buffers_file_reader
          'read_channel_into_text_buffer)
        (cons
          'buffers_file_writer
          'write_text_buffer_to_channel)
        (cons 'buffers_file  NIL)

        (cons 'CurrentBufferText (MkVect 0))
        (cons 'CurrentBufferSize  1)
        (cons 'CurrentLine  NIL)
        (cons 'CurrentLineIndex  0)
        (cons 'point  0)
        (cons 'MarkLineIndex  0)
        (cons 'MarkPoint  0)
        ))

Other  modes based on text can be similarly defined by consing an
appropriate   binding   for   ModeEstablishExpressions   to   the
environment returned by create_raw_text_buffer.


     Of course we need some way of "viewing" buffers once they've
been  created.  The per-buffer variable "buffers_view_creator" is
responsible for creating  a  view  into  a  buffer.    The  "view
creator"     is     typically     invoked    by    the    routine
"select_or_create_buffer".
Guide to EMODE                                                 14


     The required per-view variables are:

windows_refresher
                Which    should    actually    be    called   the
                "views_refresher", is a routine to  APPLY  to  no
                arguments.  This routine is the refresh algorithm
                for whatever data structure this view looks into.
WindowsBufferName
                Is  the  name (an ID) of the buffer that the view
                looks into.
views_cleanup_routine
                A routine that's called  when  a  view  is  being
                deleted  from  the  screen.   Different views may
                require different kinds of cleaning  up  at  this
                point.    For example, they should "deselect" any
                "virtual screens" that make up the view.


     The view creator for text structures is  "create_text_view".
This  routine  typically  modifies  and  returns the current view
(which is almost certainly also looking into text in the  current
system)  so that the current view looks into the new text buffer.
Most of the real work of creating  text  views  is  done  by  the
routine  "FramedWindowDescriptor",  which is typically invoked by
the routines "OneWindow" and "TwoRFACEWindows".    (So,  although
select_or_create_buffer  is  one  way  of  creating  views into a
buffer, there's quite a bit of freedom in using other methods for
creating views.)



7. Manipulating Text Buffers
7. Manipulating Text Buffers
7. Manipulating Text Buffers

     The text in "text buffers" is stored as a vector of  strings
in   the   per-buffer   variable   "CurrentBufferText"--with  the
exception of a "current line" (stored in the per-buffer  variable
"CurrentLine"),  which  is a linked list of character codes.  The
CurrentLine is the line indexed by "CurrentLineIndex".  Refer  to
the  routine  create_text_buffer for details of the contents of a
text buffer.


     It's an easy mistake to modify CurrentLine but to forget  to
update the CurrentBufferText when moving to a new line.  For this
reason,  and  because the representation used for text may change
in the future, you should use the utilities provided (mostly)  in
PES:EMODE1.RED  to  manipulate  text.  The procedure "GetLine(x)"
can be used to get line x as the current  line.    The  procedure
"PutLine()"   is  used  to  store  the  current  line  back  into
CurrentBufferText.  The  procedure  "SelectLine(x)"  first  "puts
away" the current line, and then "gets" line x. 
Guide to EMODE                                                 15


     It  would seem natural to move forward a line in the text by
doing something like

    SelectLine(CurrentLineIndex + 1);

but you should resist the temptation.  For one thing,  SelectLine
makes  little attempt to check that you stay within the limits of
the buffer.  Furthermore, future representations of text may  not
use  integers  to  index lines.  For example, some future version
may use a doubly linked list of "line structures"  instead  of  a
vector of strings.


     So,   you   should   use   the   routines   "NextIndex"  and
"PreviousIndex" to calculate new "indices"  into  text,  and  you
should  also  check  to make sure that CurrentLineIndex is within
the bounds of the buffer.  You can probably just use the routines
"!$ForwardLine" and  "!$BackwardLine",  (or  "!$ForwardCharacter"
and  "!$BackwardCharacter").    You  should also read some of the
code in EMODE1.RED  before  attempting  your  own  modifications.
(Much of the code is rather ugly, but it does seem to work!)



8. Evaluating Expressions in EMODE Buffers
8. Evaluating Expressions in EMODE Buffers
8. Evaluating Expressions in EMODE Buffers

     The  "M-E"  command for evaluating an expression in a buffer
(of the appropriate mode) depends on I/O channels that read  from
and  write  to  EMODE  buffers.   This is implemented in a fairly
straightforward manner, using the general I/O hooks  provided  by
PSL.  (See the Input/Output chapter of the PSL Manual for further
details.)    The  code  for  EMODE buffer I/O resides in the file
RFACE.RED.


     The tricky part of implementing M-E is making  it  fit  with
the READ/EVAL/PRINT loop that Lisp and other front ends use.  The
most   obvious   scheme   would  be  to  have  EMODE  invoke  one
"READ/EVAL/PRINT" for each M-E typed.  However, this doesn't work
well when a break loop, or a user's program, unexpectedly prompts
for input.


     Instead, the top level read functions in PSL call the "hook"
function, MakeInputAvailable(), which allows the user to  edit  a
buffer  before  the  reader  actually  takes  characters from the
current standard input channel.    Examples  of  top  level  read
functions  are  READ  (for  Lisp), and XREAD (for RLISP).  If you
define your own read  function,  for  example--to  use  with  the
general TopLoop mechanism, it should also call MakeInputAvailable
before trying to actually read anything.
Guide to EMODE                                                 16


     When EMODE dispatches on M-E, it RETURNS to the routine that
called it (e.g. READ), which then reads from the selected channel
(which  gets  characters from an EMODE buffer).  After evaluating
the expression, the program then  PRINTs  to  an  output  channel
which  inserts  into  another EMODE buffer.  EMODE is then called
again by the read routine (indirectly, via MakeInputAvailable).


                            _______  __  ___  ______
     The fact  that  EMODE  returns  to  the  reader  means  that
different  buffers  cannot  use different readers.  This can be a
bit confusing when editing several buffers with  different  kinds
of  code.    Simply switching to a buffer with Lisp code does not
cause  the  system  to  return  to   READ   instead   of   XREAD.
Implementing this would require some sort of coroutine or process
mechanism--neither  of  which  are  currently  provided  in  PSL.
(However,  it  may  be  possible   to   provide   an   acceptable
approximation  by  having  M-E  normally invoke a READ/EVAL/PRINT
operation,  while  preserving  the  MakeInputAvailable  hook  for
exceptional situations.)



9. Customizing EMODE for New Terminals
9. Customizing EMODE for New Terminals
9. Customizing EMODE for New Terminals

     The    files    PE:AAA.SL,    PE:DM1520.SL,   PE:HP2648A.SL,
PE:TELERAY.SL, PE:VT52.SL, and PE:VT100.SL define  the  different
terminal  drivers  currently  available.  Terminal drivers define
some values and functions used to emit the appropriate  character
strings to position the cursor, erase the screen and clear to end
of  line.  To  define  a  new terminal, use one of the files as a
guide.  A listing of TELERAY.SL follows:


%
% TELERAY.SL - EMODE support for Teleray terminals
%
% Author:      William F. Galway
%              Symbolic Computation Group
%              Computer Science Dept.
%              University of Utah
% Date:        27 June 1982
% Copyright (c) 1982 University of Utah
%

% Screen starts at (0,0), and other corner is offset by (79,23)
% (total dimensions are 80 wide by 24 down).
(setf ScreenBase (Coords 0 0))
(setf ScreenDelta (Coords 79 23))

% Parity mask is used to clear "parity bit" for those terminals
% that don't have a meta key.  It should be 8#177 in that case.
% Should be 8#377 for terminals with a meta key.
Guide to EMODE                                                 17


(setf parity_mask 8#377)

(DE EraseScreen ()
  (progn
    (PBOUT (Char ESC))
    (PBOUT (Char (lower J)))))

(DE Ding ()
  (PBOUT (Char Bell)))

% Clear to end of line from current position (inclusive).
(DE TerminalClearEol ()
  (progn
    (PBOUT (Char ESC))
    (PBOUT (Char K))))

% Move physical cursor to Column,Row
(DE SetTerminalCursor (ColLoc RowLoc)
  (progn
    (PBOUT (char ESC))
    (PBOUT (char Y))
    (PBOUT (plus (char BLANK) RowLoc))
    (PBOUT (plus (char BLANK) ColLoc))))
Guide to EMODE                                                 18


10. Bibliography
10. Bibliography
10. Bibliography

[Armantrout 81]
               Armantrout, R.; Benson, E.; Galway, W.; and Griss,
               M. L.
               ____  _ _____ ______ ______ ______ _______ __
               EMID: A Multi-Window Screen Editor Written in
                  ________ ____
                  Standard LISP.
               Utah Symbolic Computation Group Opnote No. 54,
                  University of Utah, Department of Computer
                  Science, January, 1981.

[Carter 81]    Carter, T.; Galway, W.; Goates, G.; Griss, M. L.;
               and Haslam, R.
               _____  _ ____ _____ _____ ____ ____ ______ ___ ___
               SLATE: A Lisp Based EMACS Like Text Editor for SLA
                  ______
                  Design.
               Utah Symbolic Computation Group Opnote 55,
                  University of Utah, Department of Computer
                  Science, January, 1981.

[Carter 82]    T. M. Carter.
               ASSASSIN: An Assembly, Specification and Analysis
                  System for Speed-Independent Control-Unit
                  Design in Integrated Circuits Using PPL.
               Master's thesis, Department of Computer Science,
                  University of Utah, June, 1982.

[Finseth 80]   Finseth, C. A.
               ______ ___ ________ __ ____ _______
               Theory and Practice of Text Editors.
               MIT/LCS/TM-165, Massachusetts Institute of
                  Technology, Laboratory for Computer Science,
                  May, 1980.

[Griss 81]     Griss, M. L. and Morrison, B.
               ___ ________ ________ ____ _____ ______
               The Portable Standard LISP Users Manual.
               Utah Symbolic Computation Group Technical
                  Report TR-10, University of Utah, March, 1981.

[Stallman 81a] Stallman, R. M.
               EMACS The Extensible, Customizable Self-
                  Documenting Display Editor.
                  ___________ __ ___ ___ _______ _______
               In Proceedings of the ACM SIGPLAN Notices
                  _________ __ ____ ____________
                  Symposium on Text Manipulation, pages 147-156.
                  ACM, New York, New York, June, 1981.

[Stallman 81b] Stallman, R. M.
               _____ ______ ___ ______ _____
               EMACS Manual for TWENEX Users.
               AI Memo 555, Massachusetts Institute of
                  Technology, Artificial Intelligence Laboratory,
                  May, 1981.
Guide to EMODE                                                 19


APPENDIX A:  Default Keyboard Bindings for EMODE
APPENDIX A:  Default Keyboard Bindings for EMODE
APPENDIX A:  Default Keyboard Bindings for EMODE

     The   following   commands  are  notable  either  for  their
difference from EMACS, or for their importance to getting started
with EMODE:

   - To leave EMODE type C-X C-Z to "QUIT" to the  EXEC,  or
     C-Z C-Z to return to "normal" PSL input/output.

   - While  in  EMODE,  the  "M-?"    (meta-  question mark)
     character asks for a command character and  prints  the
     name of the routine attached to that character.

   - The  function  "PrintAllDispatch()"  will print out the
     current dispatch table.  You must call EMODE first,  to
     set this table up.

   - M-C-Y  inserts into the current buffer the text printed
     as a result of the last M-E.

   - M-X prompts for a one line string and then executes  it
     as  a  Lisp expression.  Of course, similar results can
     be achieved by using M-E in a buffer.


     A (fairly) complete table of keyboard bindings follows:

C-@             Runs the function SETMARK.
C-A             Runs the function !$BEGINNINGOFLINE.
C-B             Runs the function !$BACKWARDCHARACTER.
C-D             Runs the function !$DELETEFORWARDCHARACTER.
C-E             Runs the function !$ENDOFLINE.
C-F             Runs the function !$FORWARDCHARACTER.
Tab             In Lisp mode, runs the function LISP-TAB-COMMAND.
                Indents as appropriate for Lisp.
Linefeed        In text mode, runs the function !$CRLF  and  acts
                like a carriage return.
                In  Lisp  mode,  runs the function LISP-LINEFEED-
                COMMAND.    Inserts  a  newline  and  indents  as
                appropriate for Lisp.
C-K             Runs the function KILL_LINE.
C-L             Runs the function FULLREFRESH.
Return          Runs  the  function  $CRLF  (inserts  a  carriage
                return).
C-N             Runs the function !$FORWARDLINE.
C-O             Runs the function OPENLINE.
C-P             Runs the function !$BACKWARDLINE.
C-Q             Runs the function INSERTNEXTCHARACTER.  Acts like
                a "quote" for the next character typed.
C-R             Backward  search  for  string,  type  a  carriage
                return  to  terminate the search string.  Default
                (for a null string) is the last string previously
Guide to EMODE                                                 20


                searched for.
C-S             Forward search for string.
C-T             Transpose  the  last two characters typed (if the
                last  character  typed   was   self   inserting).
                Otherwise,  transpose  the characters to the left
                and right of point, or the two characters to  the
                left of point if at the end of a line.
C-U             Repeat a command.  Similar to EMACS's C-U.
C-V             Runs the function SCROLL-WINDOW-UP-PAGE-COMMAND.
C-W             Runs the function KILL_REGION.
C-X             As  in EMACS, control-X is a prefix for "fancier"
                commands.
C-Y             Runs the function INSERT_KILL_BUFFER.  Yanks back
                killed text.
C-Z             Runs the function DOCONTROLMETA.   As  in  EMACS,
                acts like "Control-Meta" (or "Meta-Control").
ESCAPE          Runs  the  function  ESCAPEASMETA.   As in EMACS,
                ESCAPE acts like the "Meta" key.
)               Inserts a "matching" right parenthesis.   Bounces
                back  to  the  corresponding left parenthesis, or
                beeps if no matching parenthesis is found.
RUBOUT          Runs the function !$DELETEBACKWARDCHARACTER.
M-C-@           Runs the function MARK-SEXP-COMMAND.   Sets  mark
                at the end of the s-expression following point.
M-C-A           In  Lisp  mode,  runs  the function BEGINNING-OF-
                DEFUN-COMMAND.  Moves backward to  the  beginning
                of  the  current  or previous) DEFUN.  A DEFUN is
                heuristically defined to be a  line  whose  first
                character is a left parenthesis.
M-C-B           Runs the function BACKWARD_SEXPR.
M-C-D           Runs the function DOWN-LIST.  Moves "deeper" into
                the next contained list.
M-C-E           In  Lisp  mode,  runs  the function END-OF-DEFUN-
                COMMAND.  Moves forward to the beginning  of  the
                next line following the end of a DEFUN.
M-C-F           Runs the function FORWARD_SEXPR.
M-Backspace     In  Lisp  mode,  runs  the  function  MARK-DEFUN-
                COMMAND.
M-Tab           In Lisp mode, runs the function LISP-TAB-COMMAND.
M-C-K           Runs the function KILL_FORWARD_SEXPR.
M-Return        Runs  the  function  BACK-TO-INDENTATION-COMMAND.
                Similar  to  C-A,  but  skips  past  any  leading
                blanks.
M-C-N           Runs the function MOVE-PAST-NEXT-LIST.  Moves  to
                                 _______
                the right of the current or next list.
M-C-O           Runs  the function FORWARD-UP-LIST.  Moves to the
                             _______
                right of the current list.
M-C-P           Runs the function MOVE-PAST-PREVIOUS-LIST.  Moves
                to the beginning of the current or previous list.
M-C-Q           Runs  the  function  LISP-INDENT-SEXPR.     "Lisp
                indents" each line in the next s-expr.
M-C-U           Runs  the  function  BACKWARD-UP-LIST.   Does the
Guide to EMODE                                                 21


                "opposite" of FORWARD-UP-LIST.
M-C-Y           In   Lisp   and  Rlisp  mode  runs  the  function
                INSERT_LAST_EXPRESSION.  Inserts the last body of
                text typed as the result of a M-E.
M-C-Z           Runs the function OLDFACE.   Leaves  EMODE,  goes
                back to "regular" PSL input/output.
M-Escape        In  Lisp  mode,  runs  the function BEGINNING-OF-
                DEFUN-COMMAND.  (See M-C-A.)
M-C-]           In Lisp mode,  runs  the  function  END-OF-DEFUN-
                COMMAND.  (See M-C-E.)
M-C-RUBOUT      Runs the function KILL_BACKWARD_SEXPR.
M-%             Runs the function QUERY-REPLACE-COMMAND.  Similar
                to EMACS's query replace.
M-(             Runs  the  function  INSERT-PARENS.    Inserts  a
                matching  pair  of  parenthesis,  leaving   point
                between them.
M-)             Runs  the function MOVE-OVER-PAREN.  Moves over a
                ")"  updating  indentation  (as  appropriate  for
                Lisp).
M-/             Runs   the   function   !$HELPDISPATCH,  see  the
                description of M-? below.
M-;             In  Lisp  and  Rlisp  mode  runs   the   function
                INSERTCOMMENT.
M-<             Runs  the  function !$BEGINNINGOFBUFFER.  Move to
                beginning of buffer.
M->             Runs the function !$ENDOFBUFFER.  Move to end  of
                buffer.
M-?             Runs  the  function  !$HELPDISPATCH.   Asks for a
                character and prints  the  name  of  the  routine
                attached to that character.
M-@             Runs the function MARK-WORD-COMMAND.
M-B             Runs the function BACKWARD_WORD.  Backs up over a
                word.
M-D             Runs the function KILL_FORWARD_WORD.
M-E             In  Lisp and RLISP modes evaluates the expression
                starting at the beginning of the current line.
M-F             Runs the function FORWARD_WORD.    Moves  forward
                over a word.
M-M             Runs  the  function  BACK-TO-INDENTATION-COMMAND.
                (See M-Return for more description.)
M-V             Runs   the   function    SCROLL-WINDOW-DOWN-PAGE-
                COMMAND.  Moves up a window.
M-W             Runs  the function COPY_REGION.  Like C-W only it
                doesn't kill the region.
M-X             Runs the function EXECUTE_COMMAND.  Prompts for a
                string and then converts it  to  Lisp  expression
                and evaluates it.
M-Y             Runs the function UNKILL_PREVIOUS.  Used to cycle
                through the kill buffer.  Deletes the last yanked
                back  text  and  then  proceeds  to yank back the
                previous piece of text in the kill buffer.
M-\             Runs   the   function    DELETE-HORIZONTAL-SPACE-
Guide to EMODE                                                 22


                COMMAND.    Deletes  all blanks (and tabs) around
                point.
M-^             Runs  the  function   DELETE-INDENTATION-COMMAND.
                Deletes  CRLF  and  indentation at front of line,
                leaves one space in place of them.
M-RUBOUT        Runs the function KILL_BACKWARD_WORD.
C-X C-B         Runs the function  PRINTBUFFERNAMES.    Prints  a
                list of all the buffers present.
C-X C-F         Runs the function FIND_FILE.  Asks for a filename
                and  then  selects  the  buffer  that  that  file
                resides in, or creates a new buffer and reads the
                file into it.
C-X C-O         Runs  the  function   DELETE-BLANK-LINES-COMMAND.
                Deletes  blank  lines  around  point (leaving one
                left).
C-X C-P         Runs the  function  WRITESCREENPHOTO.    Write  a
                "photograph" of the screen to a file.
C-X C-R         Runs  the  function CNTRLXREAD.  Read a file into
                the buffer.
C-X C-S         Runs the function SAVE_FILE.  Writes  the  buffer
                to the file associated with that buffer, asks for
                an associated file if none defined.
C-X C-W         Runs  the function CNTRLXWRITE.  Write the buffer
                out to a file.
C-X C-X         Runs the function EXCHANGEPOINTANDMARK
C-X C-Z         As in EMACS, exits to the EXEC.
C-X 1           Goes into one window mode.
C-X 2           Goes into two window mode.
C-X B           Runs the function CHOOSEBUFFER.  EMODE asks for a
                buffer name, and then selects (or  creates)  that
                buffer for editing.
C-X H           Runs the function MARK-WHOLE-BUFFER-COMMAND.
C-X N           Runs  the  function  NEXT_WINDOW.    Selects  the
                "next" window in  the  list  of  active  windows.
                Note  that  some active windows may be covered by
                other screens, so they will  be  invisible  until
                C-X  N  reaches them and "pops" them to the "top"
                of the screen.
C-X O           An alternate way to invoke NEXT_WINDOW.
C-X P           Runs the function PREVIOUS_WINDOW.   Selects  the
                "previous" window in the list of active windows.
Guide to EMODE                                                 23


APPENDIX B:  Some Important Fluid Variables
APPENDIX B:  Some Important Fluid Variables
APPENDIX B:  Some Important Fluid Variables

     Here is an incomplete list of the fluid ("global") variables
in EMODE.

*outwindow      A flag for PSL's ON/OFF mechanism.  When T, means
                that  the  "output" (or OUT_WINDOW) window should
                be "popped up" when output occurs.
*EMODE          T when EMODE is running.  (Not quite the same  as
                "runflag"  described below.  For example, runflag
                will be  set  NIL  to  cause  EMODE  to  leave  a
                "recursive edit", but *EMODE stays T.)
*RAWIO          T when "raw I/O" is in effect.
BasicDispatchList
                The "key list" for "basic" operations.
BreakWindow     The view for the "popup" break window.
BufferNames     An       association       list       of      the
                (name . buffer-environment)  pairs  for  all  the
                buffers.
CurrentBufferName
                The name of the currently selected buffer.
CurrentBufferSize
                A  per-buffer  variable  for  text buffers, gives
                number of lines actually within buffer.
CurrentBufferText
                A per-buffer variable for text buffers.  A vector
                of lines making up the buffer.
CurrentLine     A per-buffer variable  for  text  buffers.    The
                contents (text) of current line--as a linked list
                of  character  codes.    (Takes  precedence  over
                whatever is contained in the text vector.)
CurrentLineIndex
                A per-buffer variable for text buffers.  Index of
                the "current line" within buffer.
CurrentVirtualScreen
                Per-view variable for text windows (views), holds
                the virtual screen used by the view.
CurrentWindowDelta
                Per-view variable for text windows, gives  window
                dimensions as (delta x . delta y).
CurrentWindowDescriptor
                The currently selected window environment.
declared_data_modes
                List  of  (mode-name  . buffer-creator) pairs for
                all the declared modes.
declared_file_extensions
                List of (file-extension .  buffer-creator)  pairs
                for all modes with declared file extensions.
Guide to EMODE                                                 24


EmodeBufferChannel
                Channel  used for EMODE I/O.  Perhaps this should
                be  expanded  to  allow  different  channels  for
                different  purposes (break loops, error messages,
                etc.)  (Or, perhaps the whole  model  needs  more
                thought! )
FirstCall       NIL means re-entering EMODE, T means first time.
FundamentalTextMode
                Mode  list (list of expressions) for establishing
                "fundamental" text mode.
kill_buffer_ring
                Vector  of  vectors  of  strings--holds  recently
                deleted text.
kill_opers      list  of  (names  of)  handler routines that kill
                text.  NEEDS MORE DOCUMENTATION!
kill_ring_index Pointer to the most recent "kill buffer".
last_buffername Name (a string) of the last buffer visited.
last_operation  The "last"  routine  dispatched  to  (before  the
                "current operation").
last_search_string
                The   last   string  searched  for  by  a  search
                command--used as default for next search command.
last_yank_point Vector  of  [buffer  lineindex   point],   giving
                location where last "yank" occured.
LispDispatchList
                The "key list" for Lisp mode.
LispMode        The mode list for Lisp mode.
MainDispatch    Dispatch table (vector), an entry for each key.
minor_window_list
                List   of   windows   to   be   ignored   by  the
                "next_window" routine.
ModeEstablishExpressions
                List  of  expressions  to  be  evaluated.    Each
                expression  is  expected  to modify (add to?) the
                dispatch table.
OldErrOut       The error output channel in effect  before  EMODE
                was started.
OldStdIn        The standard input channel in effect before EMODE
                was started.
OldStdOut       The  standard  output  channel  in  effect before
                EMODE was started.
point           A per-buffer variable for text buffers.    Number
                of chars to the left of point within CurrentLine.
PrefixAssociationLists
                Additional   dispatch  information  for  prefixed
                characters.
PrefixCharacterList
                A list of the declared prefix characters.
Guide to EMODE                                                 25


pushed_back_characters
                A  list  of  characters  pushed  back for EMODE's
                command reader.  This may be used when a  command
                isn't  recognized  by  one  dispatcher, so it can
                push the characters  back  and  pass  control  to
                another dispatcher.
reading_from_output
                Kludge  flag,  T  when input buffer is OUT_WINDOW
                buffer (for M-E).
RlispDispatchList
                The "key list" for RLISP mode.
RlispMode       The mode list for RLISP mode.
runflag         EMODE continues its READ/DISPATCH/REDISPLAY until
                this flag is NIL.
SelfInsertCharacter
                Character being dispatched upon.    (Usually  the
                last character typed.)
ShiftDisplayColumn
                Amount  to  shift  things  to  the left by before
                (re)displaying lines in a text view.
TextDispatchList
                The "key list" for fundamental text mode.
Two_window_midpoint
                Gives location (roughly) of dividing line for two
                window mode.
WindowList      List of active windows (views).
WindowsBufferName
                Required per-view variable giving the name of the
                buffer being viewed.
Windows_Refresher
                Required per-view  variable  giving  the  refresh
                algorithm to be APPLYed for this view.
Window_Image    Per-view   variable   for   text  views,  holding
                information for speeding up refresh.
Guide to EMODE                                                  i


                        Table of Contents
                        Table of Contents
                        Table of Contents

1. Introduction and Acknowledgments                             1
2. Running EMODE                                                1
3. A Guide to the Sources and Rebuilding                        6
4. Terminology:  Buffers, Views/Windows, and Virtual Screens    7
5. Modes and Key bindings in EMODE                              9
6. Creating New Modes                                          12
7. Manipulating Text Buffers                                   14
8. Evaluating Expressions in EMODE Buffers                     15
9. Customizing EMODE for New Terminals                         16
10. Bibliography                                               18
APPENDIX A:  Default Keyboard Bindings for EMODE               19
APPENDIX B:  Some Important Fluid Variables                    23
Guide to EMODE                                                 ii


                         List of Figures
                         List of Figures
                         List of Figures

Figure 2-1:
Figure 2-1:
Figure 2-1:   Two window mode                                   3
Figure 2-2:
Figure 2-2:
Figure 2-2:   One window mode                                   4
Figure 2-3:
Figure 2-3:
Figure 2-3:   A break window (doctored from the original)       5
