








		       Notes on the Xvi Source Code


			       Chris Downey
				John Downey



	       Xvi (pronounced _e_c_k_s-_v_e_e-_e_y_e) is a free, portable,
	  multi-window implementation of the popular UNIX|- editor
	  vi.

	  This document contains information on how to  port  xvi
	  to  systems  not currently supported.  It also explains
	  how the xvi source code is arranged into  modules,  and
	  explains some of the data structures which are used, so
	  that modifications may be made if and when necessary to
	  the editor itself.



     _1.  _I_N_T_R_O_D_U_C_T_I_O_N

     Xvi is intended to be portable to just about any system.  This is
     one of the central reasons for its existence; the authors wish to
     be able to use the same editor everywhere.

     The main body of  the  editor  is  (supposedly)  fully  portable,
     relying  only  on  standard facilities defined by the White Book,
     and on a set of _p_r_i_m_i_t_i_v_e_s which are provided by a set of one  or
     more  modules for each operating system.  If ___S_T_D_C__ is defined,
     certain ANSI C facilities will  be  used,  but  the  editor  will
     compile with non-ANSI compilers.

     Therefore, in order to port xvi to a  new  system,  all  that  is
     necessary  is  to provide the defined set of _p_r_i_m_i_t_i_v_e_s, and then
     build the editor.  Or at least, that's the idea; we have  refined
     the  set of primitives as we port the editor to new environments,
     and it's getting pretty easy now.

     The rest of this document is divided into sections as follows:

     _S_e_c_t_i_o_n _2: _S_y_s_t_e_m-_S_p_e_c_i_f_i_c _M_o_d_u_l_e_s
	  This section deals with  the  layout  of  source  files  and
	  makefiles which you will have to deal with when porting xvi.

     _S_e_c_t_i_o_n _3: _P_r_i_m_i_t_i_v_e_s _P_r_o_v_i_d_e_d _b_y _x_v_i
	  Discusses what primitives are provided by the main  body  of
	  the editor source code for use by the system interface code.
     _________________________
     |- UNIX is a trademark of Bell Laboratories.



     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _1





     _2                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     _S_e_c_t_i_o_n _4: _S_y_s_t_e_m _I_n_t_e_r_f_a_c_e
	  Explains the primitives which need to be provided  in  order
	  to make xvi work.

     _S_e_c_t_i_o_n _5: _D_a_t_a _S_t_r_u_c_t_u_r_e_s
	  Details the internal data types used in the editor, and  any
	  functions available for operating on those types.

     _S_e_c_t_i_o_n _6: _S_o_u_r_c_e _F_i_l_e_s
	  Lists the source files comprising the editor,  and  explains
	  what functionality is provided by each one.



     _2.  _S_Y_S_T_E_M-_S_P_E_C_I_F_I_C _M_O_D_U_L_E_S

     The system-specific code normally consists  of  three  (or  more)
     files; a ".c" file, a ".h" file, and a makefile.  For example:

	     _q_n_x._c
	     _q_n_x._h
	     _m_a_k_e_f_i_l_e._q_n_x

     comprise the system-specific module for the QNX operating system.

     In most cases, the system-specific code is divided  into  two  or
     more  modules,  where one (called the _s_y_s_t_e_m _i_n_t_e_r_f_a_c_e _m_o_d_u_l_e) is
     concerned with general interactions with the operating system and
     the  other (called the _t_e_r_m_i_n_a_l _i_n_t_e_r_f_a_c_e _m_o_d_u_l_e) is designed for
     a specific interface to a display and keyboard (and  possibly,  a
     mouse).

     For example, the  generic  UNIX  implementation  has  _u_n_i_x._c  and
     _u_n_i_x._h  for  the  system  interface  module,  and  _t_e_r_m_c_a_p._c  and
     _t_e_r_m_c_a_p._h for the terminal interface  module;  this  should  work
     reasonably with any full-duplex terminal that can be described in
     the _t_e_r_m_c_a_p database.  On consoles with  memory-mapped  displays,
     or  systems  with  graphic  user  interfaces,  however, it may be
     possible to achieve faster display updating,  and  perhaps  other
     benefits,  by  replacing the _t_e_r_m_c_a_p module with another one that
     makes better use  of  whatever  facilities  are  available.   For
     instance,  there  is  an  experimental version for SunView, which
     allows mouse input on Sun workstations running the SunView window
     system.

     On  the  other  hand,   the   _t_e_r_m_c_a_p-specific   routines   might
     conceivably  be  useful  on some other operating systems (such as
     VMS), so in general it seemed a good idea to  make  the  _t_e_r_m_c_a_p-
     specific routines a separate module.

     The  current  MS-DOS  implementation  has  a  separate   terminal
     interface  module,  which  is  designed  specifically  for IBM PC
     compatible computers.  This is in the files




     _P_a_g_e _2                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _3



	     _i_b_m_p_c__a._a_s_m
	     _i_b_m_p_c__c._c
	     _i_b_m_p_c._h

     The first of these is written in assembly language because  there
     are  not enough routines common to the various MS-DOS C compilers
     which reliably access the display and keyboard at  a  low  enough
     level.

     The hardware-independent system interface module for MS-DOS is in

	     _m_s_d_o_s__a._a_s_m
	     _m_s_d_o_s__c._c
	     _m_s_d_o_s._h

     The first of these is written in assembly language for  the  same
     reason as is _i_b_m_p_c__a._a_s_m.

     Theoretically, different  terminal  interface  modules  could  be
     written  for MS-DOS systems running on hardware which is not IBM-
     compatible but, unfortunately, such systems seem to be  virtually
     extinct nowadays.

     Sometimes more than one makefile is provided, as in the  case  of
     UNIX, where different versions work in slightly different ways.

     It is, of couse, not necessary to provide all - or any - of these
     files for a particular implementation; this is just a convention.
     The makefile(s) for each system determine what files are used  in
     the compilation of the editor.

     The following porting modules are available at present:
























     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _3





     _4                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s

     ________________________________________________________________
    |         System        |    Makefile  |       Source Files     |
    |________________________|_______________|_________________________|
    | UNIX                  |              |                        |
    |   BSD                 |  makefile.bsd|  unix.[ch] termcap.[ch]|
    |   System V |-          |  makefile.usg|  unix.[ch] termcap.[ch]|
    |   AIX                 |  makefile.aix|  unix.[ch] termcap.[ch]|
    |   ULTRIX              |  makefile.ult|  unix.[ch] termcap.[ch]|
    |   Xenix |-             |  makefile.xen|  unix.[ch] termcap.[ch]|
    |   POSIX (e.g. BSDI)   |  makefile.pos|  unix.[ch] termcap.[ch]|
    |   SunOS               |  makefile.sun|  unix.[ch] termcap.[ch]|
    |   SunView             |  makefile.sv |  unix.[ch] sunview.h   |
    |                       |              |  sunfront.c sunback.c  |
    |                       |              |  xvi.icn               |
    |________________________|_______________|_________________________|
    |                       |              |                        |
    | MS-DOS                |              |  msdos_c.c msdos.h     |
    |                       |              |  ibmpc_c.c ibmpc.h     |
    |   Microsoft C 5.*     |  makefile.msc|  8086mm.inc ibmpc_a.asm|
    |   & MASM 5.*          |              |  msdos_a.asm           |
    |                       |              |                        |
    |   Microsoft Quick C   |  makefile.qc |  8086mm.inc ibmpc_a.asm|
    |   & MASM 5.*          |              |  msdos_a.asm           |
    |   Zortech C++ 2.*     |  makefile.zc2|  8086mm.inc ibmpc_a.asm|
    |   & MASM 5.*          |              |  msdos_a.asm           |
    |                       |              |                        |
    |   Zortech C++ 3.*     |  makefile.zc3|  8086mm.inc ibmpc_a.asm|
    |   & MASM 5.*          |              |  msdos_a.asm           |
    |   Zortech C++ 3.*     |              |                        |
    |   386 protected mode  |  makefile.386|  pc386.[ch]            |
    |________________________|_______________|_________________________|
    |                       |              |                        |
    | OS/2 |-                |              |                        |
    |   Version 1, text mode|              |                        |
    |   Microsoft C 5.1     |  makefile.os2|  os2vio.[ch]           |
    |   & MASM 5.1          |              |  i286.asm              |
    |________________________|_______________|_________________________|
    | QNX                   |              |                        |
    |   Version 2/3 (CII)   |  makefile.qnx|  qnx.[ch]              |
    |   Version 4 (Watcom C)|  makefile.qn4|  unix.[ch] termcap.[ch]|
    |________________________|_______________|_________________________|
    |                       |              |                        |
    | TOS |-                 |              |                        |
    |   Lattice C           |  makefile.tos|  tos.[ch] tos.lnk      |
    |________________________|_______________|_________________________|


     |- Versions marked with |- probably do not work,  as  systems  have
       not been recently available to the authors for testing.









     _P_a_g_e _4                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _5


     _3.  _P_R_I_M_I_T_I_V_E_S _P_R_O_V_I_D_E_D _B_Y _X_V_I

     _3._1.  _G_e_n_e_r_a_l _D_e_f_i_n_i_t_i_o_n_s

     The file _x_v_i._h should be included by all system-specific modules;
     this  file should also be edited so that a system-specific header
     file (or files), as determined by a predefined keyword,  will  be
     included.

     For instance, under UNIX, the word _U_N_I_X is defined by passing the
     -_D_U_N_I_X  flag  to  the  C  compiler  from  the makefile, and _x_v_i._h
     contains the following lines:

	     #_i_f_d_e_f _U_N_I_X
	     #   _i_n_c_l_u_d_e "_u_n_i_x._h"
	     #_e_n_d_i_f

     in order to obtain the UNIX-related definitions from that  header
     file.

     Among the definitions in _x_v_i._h are the following:

     bool_t
	  A Boolean type having values _T_R_U_E or _F_A_L_S_E.

     const
     volatile
	  These are defined out when ___S_T_D_C__ is not defined, so  that
	  it is always safe to use them.

     _x_v_i._h also includes various other header files which are  needed.
     The following system header files are always included:

	     _s_t_d_i_o._h
	     _c_t_y_p_e._h
	     _s_i_g_n_a_l._h
	     _s_t_r_i_n_g._h

     These files are included if ___S_T_D_C__ is defined:

	     _s_t_d_d_e_f._h
	     _s_t_d_l_i_b._h
	     _l_i_m_i_t_s._h

     and if ___S_T_D_C__ is  not  defined,  _x_v_i._h  will  provide  its  own
     definitions for the following:

	     _I_N_T__M_A_X
	     _I_N_T__M_I_N
	     _U_L_O_N_G__M_A_X

	     _F_I_L_E    *_f_o_p_e_n();
	     _c_h_a_r    *_m_a_l_l_o_c();
	     _c_h_a_r    *_g_e_t_e_n_v();



     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _5





     _6                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     Finally, one of the following header files will be included:

	     _s_t_d_a_r_g._h
	     _v_a_r_a_r_g_s._h

     depending on whether ___S_T_D_C__ is defined or  not.   In  order  to
     make  coding  of  _v_a_r_a_r_g_s functions easier, a macro _V_A__S_T_A_R_T() is
     defined,  which  takes  the  same  arguments  as  the  ANSI-style
     _v_a__s_t_a_r_t(),  but which is also available in non-ANSI environments
     (e.g. BSD).

     In order to make it possible to  use  ANSI-style  prototypes  for
     function declarations, but still allow compilation under non-ANSI
     environments, the following macro is provided:

	     #_i_f_d_e_f ___S_T_D_C__
	     #   _d_e_f_i_n_e  _P(_a_r_g_s) _a_r_g_s
	     #_e_l_s_e
	     #   _d_e_f_i_n_e  _P()     ()
	     #_e_n_d_i_f

     so that function declarations may be specified thus:

	     _e_x_t_e_r_n _F_I_L_E *_f_o_p_e_n _P((_c_o_n_s_t _c_h_a_r *, _c_o_n_s_t _c_h_a_r *));

     Please use this facility when you provide declarations  for  your
     system  primitives,  unless  your  system  always  uses  an  ANSI
     compiler.

     _3._2.  _P_a_r_a_m_e_t_e_r_s

     An important facility provided for use by system-specific modules
     is  access  to the editor's parameter table.  This is achieved by
     means of some apparent functions, and a  set  of  #_d_e_f_i_n_ed  token
     values.  The functions are:

     void set_param(int n, val)
	  This function sets the indicated  parameter  to  the  passed
	  value,  which  must  be  of  an appropriate type.  Parameter
	  values may be obtained by means of the  following  functions
	  (actually macros):

     char *Ps(int n)
	  return value of string parameter

     int Pn(int n)
	  return value of numeric parameter

     bool_t Pb(int n)
	  return value of boolean parameter

     char **Pl(int n)
	  return value of list parameter (a NULL-terminated  array  of
	  character pointers)



     _P_a_g_e _6                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _7


     int Pen(int n)
	  return numeric value (index) of enumerated parameter

     char **Pes(int n)
	  return string value of enumerated parameter

     In all cases, the int n argument is the index of the parameter in
     the table; a set of #_d_e_f_i_n_es is provided, of the form:

	     _P__n_a_m_e

     which map the parameter names into integral  values.   Thus,  for
     example, we might obtain the value of the _c_o_l_o_u_r parameter:

	     _c_o_l_o_u_r = _P_n(_P__c_o_l_o_u_r);

     or set the value of the _h_e_l_p_f_i_l_e parameter:

	     _s_e_t__p_a_r_a_m(_P__h_e_l_p_f_i_l_e, "/_u_s_r/_l_i_b/_x_v_i/_h_e_l_p");




     _4.  _S_Y_S_T_E_M _I_N_T_E_R_F_A_C_E

     _4._1.  _I_n_t_r_o_d_u_c_t_i_o_n

     There follows a list of the primitives  which  must  be  provided
     either  by  the  system interface module or by the underlying OS.
     Note that it is perfectly acceptable to  implement  functions  or
     external  variables  as macros so long as they "look the same" as
     the definitions below.  As a guideline, anything which is (a)  in
     capitals,  or  (b)  is a const variable, will be implemented as a
     #_d_e_f_i_n_e for most systems.

     When you want to actually do the port, it is  highly  recommended
     that  you  copy  the  system-specific  files for the system which
     seems closest to your own, and modify those  files,  rather  than
     starting from scratch.

     All the  following  symbols  should  be  defined  in  the  system
     interface module, or by standard header files already included by
     _x_v_i._h, or by  other  header  files  explicitly  included  by  the
     system-specific header file:

     const unsigned int MAXPATHLEN
	  The maximum number of characters in a pathname.

     const unsigned int MAXNAMLEN
	  The maximum number of characters in a filename.

     int remove(char *filename)
	  Remove the named file as per ANSI.




     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _7





     _8                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     int rename(char *old, char *new)
	  Rename the file old to new as per ANSI.

     void sleep(unsigned int seconds)
	  Put the process to sleep for the given number of seconds.

     const char * const DIRSEPS
	  The pathname separators supported  for  system  calls  (e.g.
	  "\\/" for MS-DOS).

     FILE *fopenrb(char *file)
     FILE *fopenwb(char *file)
	  Like the standard _f_o_p_e_n() library call, but they  both  open
	  files  in "binary" mode (i.e. no conversion of cr/lf/crlf is
	  done), for reading and writing respectively.

     bool_t exists(char *filename)
	  Returns _T_R_U_E if the named file exists.

     bool_t can_write(char *filename)
	  Returns _T_R_U_E if the named file can be  written,  i.e.  if  a
	  fopenwb(filename) will succeed.

     char *fexpand(char *filename)
	  Returns a filename-expanded version of the passed filename.

     #define SETVBUF_AVAIL

     const unsigned int READBUFSIZ
     const unsigned int WRTBUFSIZ
	  If _S_E_T_V_B_U_F__A_V_A_I_L (or ___S_T_D_C__) is  defined,  these  constant
	  values are used to set I/O buffer sizes (using the setvbuf()
	  function) for reading  and  writing  files.   Note  that  if
	  buffers  of  these  sizes  are  unavailable  at runtime, the
	  editor will try to allocate smaller buffers  by  iteratively
	  halving  the  buffer size until the allocation succeeds.  It
	  is therefore acceptable for these values to be quite large.

     char *tempfname(const char *filename)
	  Create a unique name for a temporary  file,  possibly  using
	  filename  as  a  base (this will be used by _d_o__p_r_e_s_e_r_v_e() to
	  create a backup file for the file named by  _f_i_l_e_n_a_m_e).   The
	  string  returned  must  have  been allocated using _m_a_l_l_o_c();
	  _N_U_L_L can be returned if there is no more memory available.

     int call_system(char *command)
	  Invoke the given command in a subshell.  This  is  used  for
	  shell  escapes  from  xvi.   The  command string may contain
	  metacharacters which  are  expected  to  be  expanded  by  a
	  command interpreter, e.g.  UNIX /_b_i_n/_s_h, MS-DOS _c_o_m_m_a_n_d._c_o_m.
	  Return value is 0 for success.  In many  environments,  this
	  call may safely be #_d_e_f_i_n_ed as _s_y_s_t_e_m(_c_o_m_m_a_n_d).





     _P_a_g_e _8                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _9


     int call_shell(char *shell)
	  Invoke the  named  shell.   This  is  used  for  the  :_s_h_e_l_l
	  command.   It  may  be  mapped  into  _c_a_l_l__s_y_s_t_e_m(),  but is
	  separate on some systems for efficiency  reasons  (i.e.  not
	  invoking  two  shells  to  get  one).  Return value is 0 for
	  success.

     bool_t
     sys_pipe(char *cmd, int (*wf)(FILE *), long (*rf)(FILE *))
	  Used for the !  command.  The first parameter is the command
	  to  invoke,  while  the second and third are functions which
	  should be called with an open file pointer in order to write
	  out  old, or read in new lines (respectively).  Note that if
	  "real"  pipes  are  not  available,  it  is  acceptable   to
	  implement  this  function  using temporary files, but the wf
	  function must obviously be called before rf.

     void sys_exit(int code)
	  Exit with given exit status.  This routine must not  return.
	  The editor is considered "dead" once it has been called, and
	  no further calls to editor functions should be made.

     void delay(void)
	  Delay for a short time, about a fifth of a second.  This  is
	  used  for  showing  matching brackets when showmatch is set.
	  It is acceptable to just return if implementing this is  not
	  easy.

     _4._2.  _S_c_r_e_e_n _C_o_n_t_r_o_l

     An instance of the following structure must be defined  in  order
     to allow screen output to take place:

























     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _9





     _1_0                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s



       _t_y_p_e_d_e_f _s_t_r_u_c_t _v_i_r_t_s_c_r {
	 _g_e_n_p_t_r   *_p_v__w_i_n_d_o_w;
	 _i_n_t      _p_v__r_o_w_s;
	 _i_n_t      _p_v__c_o_l_s;
     /* _p_u_b_l_i_c: */
	 _V_i_r_t_S_c_r  *(*_v__n_e_w)(_V_i_r_t_S_c_r *);
	 _v_o_i_d     (*_v__c_l_o_s_e)(_V_i_r_t_S_c_r *);

	 _i_n_t      (*_v__r_o_w_s)(_V_i_r_t_S_c_r *);
	 _i_n_t      (*_v__c_o_l_s)(_V_i_r_t_S_c_r *);

	 _v_o_i_d     (*_v__c_l_e_a_r__a_l_l)(_V_i_r_t_S_c_r *);
	 _v_o_i_d     (*_v__c_l_e_a_r__l_i_n_e)(_V_i_r_t_S_c_r *);

	 _v_o_i_d     (*_v__g_o_t_o)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l);
	 _v_o_i_d     (*_v__a_d_v_i_s_e)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l,
				   _i_n_t _i_n_d_e_x, _c_h_a_r *_s_t_r);

	 _v_o_i_d     (*_v__w_r_i_t_e)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l, _c_h_a_r *_s_t_r);
	 _v_o_i_d     (*_v__p_u_t_c)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l, _i_n_t _c_h);

	 _v_o_i_d     (*_v__s_e_t__c_o_l_o_u_r)(_V_i_r_t_S_c_r *, _i_n_t _c_o_l_o_u_r);
	 _i_n_t      (*_v__c_o_l_o_u_r__c_o_s_t)(_V_i_r_t_S_c_r *);

	 _v_o_i_d     (*_v__f_l_u_s_h)(_V_i_r_t_S_c_r *);

	 _v_o_i_d     (*_v__b_e_e_p)(_V_i_r_t_S_c_r *);

     /* _o_p_t_i_o_n_a_l: _n_o_t _u_s_e_d _i_f _N_U_L_L */
	 _v_o_i_d     (*_v__i_n_s_e_r_t)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l, _c_h_a_r *_s_t_r);

	 _i_n_t      (*_v__s_c_r_o_l_l)(_V_i_r_t_S_c_r *, _i_n_t _s_t_a_r_t, _i_n_t _e_n_d, _i_n_t _n_l_i_n_e_s);
       } _V_i_r_t_S_c_r;


     The first three fields in this structure are "private",  for  use
     only  within  the  implementation of the "public" functions.  The
     remaining fields are all function  pointers,  and  are  described
     below.   Note  that  all  functions  have at least one parameter,
     which is a pointer to the instance of the  VirtScr  in  question.
     This  is always referred to as vs below.  Note also that the top-
     left-hand corner of the window is taken to be (0,0).

     v_new(vs)
	  Obtain a new VirtScr, and return a pointer to it.   This  is
	  not used at present, and should return _N_U_L_L.

     v_close(vs)
	  Close the window to which vs refers.

     v_rows(vs)
	  Return the number of rows in vs.




     _P_a_g_e _1_0                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_1


     v_cols(vs)
	  Return the number of columns in vs.

     v_clear_all(vs)
	  Clear the window completely.

     v_clear_line(vs, int row, int col)
	  Clear the specified line, from the given column to the right
	  hand edge of the window, inclusive.

     v_goto(vs, int row, int col)
	  Move the cursor to the specified row and column.

     v_advise(vs, int row, int col, int index, char *str)
	  This function is called when the editor is about to  produce
	  some  output  on  the  same  line  as  the  last output, but
	  separate from it by one or more characters.  The destination
	  position  is the coordinate pair (row, col + index), and str
	  contains the string of characters which are  in  the  window
	  starting  at  position  (row,  col).   Where there is a cost
	  incurred by moving the cursor to a specific screen position,
	  the  terminal  interface  module  may  decide  to  write the
	  intervening characters to the screen  rather  than  using  a
	  specific  "move  cursor"  sequence, in order to minimise the
	  number of characters written to the terminal.

	  Note that for many environments, the cost of  re-positioning
	  the  cursor  is  nil,  and  under  these  circumstances this
	  function need not do anything.

     v_write(vs, int row, int col, char *str)
	  Write the specified string of characters  into  the  window,
	  starting  at  the  specified row and column.  The parameters
	  will be such that the string will always fit into  a  single
	  line  of  the  window,  i.e.  no line-wrapping is necessary;
	  however, it is quite possible for the string to end  on  the
	  last character of a line, and some implementations will need
	  to take special precautions to handle this correctly.

     v_putc(vs, int row, int col, int ch)
	  This is like v_write but for a single character.

     v_set_colour(vs, int colour)
	  Set the colour for all subsequent output (including clearing
	  of  lines or the whole window) to the specified colour.  The
	  meaning of the value is system-specific.

     v_colour_cost(vs)
	  Return the number of extra characters which are taken up  in
	  the window by a colour change.  This is almost always 0, but
	  there exist some terminals for which it is not (see the "sg"
	  _t_e_r_m_c_a_p capability).





     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_1





     _1_2                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     v_flush(vs)
	  Flush all screen output, and move the cursor on  the  screen
	  to  the  correct  position.  The screen need not actually be
	  updated  until  either   this   function   is   called,   or
	  xvi_handle_event() returns.

     v_beep(vs)
	  Beep.  It is acceptable to flash the screen or window if  no
	  audio facility is available.

     v_insert(vs, int row, int col, char *str)
	  This  function  inserts  the  given  string  at  the   given
	  position,  pushing  any  other characters on the same row to
	  the right.   If  such  a  facility  is  not  available,  the
	  function pointer should be set to _N_U_L_L.

     v_scroll(vs, int start, int end, int nlines)
	  This function scrolls the set of lines between start and end
	  (inclusive)  by nlines lines.  If nlines is positive, _n_o_r_m_a_l
	  scrolling should be done, i.e. the  lines  should  be  moved
	  upwards  with respect to the window.  If nlines is negative,
	  scrolling should be in the  reverse  direction.   The  lines
	  which  are  left  by  the  scrolling should be cleared.  The
	  function  should  return  non-zero  if  the  scrolling   was
	  successful, otherwise 0.

	  If scrolling is not available, the function  pointer  should
	  be set to _N_U_L_L.

     _4._3.  _P_a_r_a_m_e_t_e_r_s

     Default values should  be  #_d_e_f_i_n_ed  for  certain  parameters  as
     follows:
		__________________________________________
	       | Parameter Name|   Type  |  #define name |
	       |________________|__________|________________|
	       | syscolour     |  numeric|  DEF_SYSCOLOUR|
	       | colour        |  numeric|  DEF_COLOUR   |
	       | statuscolour  |  numeric|  DEF_STCOLOUR |
	       | roscolour     |  numeric|  DEF_ROSCOLOUR|
	       | helpfile      |  string |  HELPFILE     |
	       |_f_o_r_m_a_t__________|__s_t_r_i_n_g___|__D_E_F___T_F_F________|


     _4._4.  _F_i_l_e _F_o_r_m_a_t_s

     The functions in xvi which read and write text files are aware of
     several different newline conventions (for example, "\n" on UNIX,
     "\r\n" on MS-DOS, and so on), so that any version of  the  editor
     can  read  and  write any of the supported formats.  The value of
     the format parameter  (which  can  be  set  to  "unix",  "msdos",
     "macintosh",  etc.)  determines  which  format is currently being
     used.  If you  are  porting  xvi  to  a  system  with  a  newline
     convention  which isn't one of those currently supported (see the
     table called _t_f_t_a_b_l_e in _f_i_l_e_i_o._c) you may have to add a new entry


     _P_a_g_e _1_2                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_3


     to the table.

     Unfortunately, the current design is not as general as  it  ought
     to  be.  If you happen to be porting to VMS, or some other system
     which doesn't use either a single character or a consecutive pair
     of  characters  to represent a newline, you will have quite a lot
     of work to do if you want to retain the facility  for  converting
     between file formats within the editor.

     In any case, your system interface module should  define  _D_E_F__T_F_F
     to  be  the  index  of  the entry in tftable which represents the
     default  format  for  your  system.   This  is  the   value   for
     _P_e_n(_P__f_o_r_m_a_t) which will be compiled into the parameter table.

     _4._5.  _N_o_t_e_s _o_n _T_e_r_m_c_a_p _I_m_p_l_e_m_e_n_t_a_t_i_o_n

     There exists a termcap implementation of the terminal  interface,
     currently  only  used for the UNIX port.  This module could quite
     easily be re-used for other systems  if  desired;  the  following
     routines would need to be defined by the system module:

     void foutch(int c)
	  Output a single character to the  terminal.   This  must  be
	  implemented as a function, not a macro, because it is passed
	  as a parameter into the _t_e_r_m_c_a_p library.

     void moutch(int c)
	  Same as _f_o_u_t_c_h() except that it  can  be  implemented  as  a
	  macro.  This will be used by the _t_e_r_m_c_a_p interface module to
	  write characters to the screen.

     void oflush(void)
	  Flush buffered output to the terminal.

     _4._6.  _E_n_t_e_r_i_n_g/_L_e_a_v_i_n_g _V_i_s_u_a_l _M_o_d_e

     Some facility is commonly  necessary  for  the  system  interface
     module  to be able to tell the terminal interface module to enter
     or exit _v_i_s_u_a_l mode.  This might mean changing the terminal state
     between "raw" and "cooked" modes, or switching display pages.  No
     specific interface for this is  defined,  although  the  standard
     UNIX  and  MS-DOS implementations do use such a facility, and the
     interface functions for both systems are identically defined.

     _4._7.  _F_u_n_c_t_i_o_n _K_e_y_s/_M_o_u_s_e _H_a_n_d_l_i_n_g

     Function key values are coded into a set of #_d_e_f_i_n_ed constants in
     the file _a_s_c_i_i._h; e.g. the value _K__U_A_R_R_O_W might be given as input
     when the keyboard up-arrow key has been pressed.

     If the global variable _S_t_a_t_e is not equal to _N_O_R_M_A_L, all function
     keys except for a backspace key are invalid input.  If an invalid
     key is pressed, the safest strategy may be to beep and  wait  for
     another key to be pressed.  _N_O_R_M_A_L is defined in _x_v_i._h.



     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_3





     _1_4                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     Another facility which may be provided is handling mouse input on
     systems  where  it  is  available.  The strategy for interpreting
     mouse input  is  controlled  by  the  _m_o_u_s_e_c_l_i_c_k()  function  (in
     _m_o_u_s_e._c);  the  idea  is  to make the strategy independent of any
     specific device interface.  If a mouse button is pressed before a
     keyboard key is pressed, the following routine should be called:

	     _m_o_u_s_e_c_l_i_c_k(_i_n_t _r_o_w, _i_n_t _c_o_l_u_m_n);

     where row and column are the  current  co-ordinates,  counted  in
     character  positions,  of  the mouse pointer within the screen or
     editing window.  If the mouse is moved while  a  button  is  held
     down, the routine

	     _m_o_u_s_e_d_r_a_g(_i_n_t _s_t_a_r_t_r_o_w, _i_n_t _e_n_d_r_o_w, _i_n_t _s_t_a_r_t_c_o_l_u_m_n, _i_n_t _e_n_d_c_o_l_u_m_n);

     should be called with co-ordinates describing the  movement.   If
     the global variable _S_t_a_t_e is not equal to _N_O_R_M_A_L, mouse input can
     be ignored altogether.

     All this will be considerably tidied up at a later stage, when we
     have proper _x_v_E_v_e_n_t types for function keys and mouse actions.

     _4._8.  _M_a_i_n

     Finally, the  system  interface  module  must  provide  a  main()
     function.   This  function  must call xvi_startup(vs, argc, argv,
     env) at startup, with parameters as follows:

     VirstScr *vs;
	  This is a pointer to the VirtScr  structure  for  the  first
	  window, or for the terminal screen.

     int argc, char **argv;
	  These are as for a main() function.

     char *env;
	  This is an environment string,  normally  the  return  value
	  from   getenv("XVINIT").   If  the  concept  of  environment
	  variables  does  not   exist,   a   string   of   the   form
	  "source _f_i_l_e_n_a_m_e"  may  be  passed  instead,  so as to allow
	  users to localise their usage of the editor.

     The return value from xvi_startup() is a pointer, which  will  be
     used in future to identify the window for input events.  For now,
     it should be stored in the VirtScr's pv_window field.

     Having called xvi_startup(), input events may then be  passed  to
     the  editor  by  calling  xvi_handle_event  with  a pointer to an
     xvEvent structure  as  the  sole  argument.   This  structure  is
     defined as follows:






     _P_a_g_e _1_4                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_5



	     _t_y_p_e_d_e_f _s_t_r_u_c_t _e_v_e_n_t {
		 _e_n_u_m {
		     _E_v__c_h_a_r,
		     _E_v__t_i_m_e_o_u_t
		 }                   _e_v__t_y_p_e;
		 _u_n_i_o_n {
		     /* _E_v__c_h_a_r: */
		     _i_n_t _e_v_u__i_n_c_h_a_r;

		     /* _E_v__t_i_m_e_o_u_t: */
		 }                   _e_v__u;
	     } _x_v_E_v_e_n_t;

	     #_d_e_f_i_n_e _e_v__i_n_c_h_a_r       _e_v__u._e_v_u__i_n_c_h_a_r


     The ev_type field is a tag which identifies  the  type  of  event
     which  has  occurred.  At present, only two events are supported:
     an input character from the user, and a timeout.  The union which
     follows  contains data associated with each event type; currently
     only the type Ev_char requires data, as may be seen.  The #_d_e_f_i_n_e
     for ev_inchar is provided purely for convenience.

     The return value from xvi_handle_event() is a long integer  value
     which  is  the  time  in  milliseconds  for  which  the editor is
     prepared to wait for more input.  If no input arrives within that
     time,  the  function should be called again with an event of type
     Ev_timeout.  The timeout value returned  may  be  0L,  indicating
     that no timeout is necessary.  It is very important that timeouts
     should actually be implemented because they are  needed  for  the
     _p_r_e_s_e_r_v_e facility.

     Currently,    if    a    keyboard    interrupt    is    received,
     _x_v_i__h_a_n_d_l_e__e_v_e_n_t()  need  not  be called (it should, in any case,
     never be called from an asynchronous interrupt or signal handler)
     but  the  global  variable  _k_b_d_i_n_t_r  should  be set to a non-zero
     value.



     _5.  _D_A_T_A _S_T_R_U_C_T_U_R_E_S

     Structures used in xvi are all typedef'd, and all  begin  with  a
     capital  letter.   They are defined in _x_v_i._h.  The following data
     structures are defined:

     _5._1.  _L_i_n_e

     This structure is used to hold a single text line.   It  contains
     forward  and  backward  pointers  which are connected together to
     form a two-way linked list.  It also contains  a  pointer  to  an
     allocated  text  buffer, an integer recording the number of bytes
     allocated for the text, and the line number (an  unsigned  long).
     The  text  is null-terminated, and the space allocated for it may


     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_5





     _1_6                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     be grown but is never shrunk.  The maximum size of this space  is
     given by _M_A_X__L_I_N_E__L_E_N_G_T_H.

     The line number is used when showing line numbers on screen,  but
     this is secondary to its main purpose of providing an ordering on
     lines; the ordering of two lines in a list may be established  by
     simply  comparing  their  line  numbers (macros are available for
     this purpose; see later for details).

     _5._2.  _B_u_f_f_e_r

     This structure holds the internal representation of a  file.   It
     contains  pointers to the linked list of lines which comprise the
     actual text.  We always allocate an extra line at  the  beginning
     and  the end, with line numbers 0 and _M_A_X__L_I_N_E_N_O respectively, in
     order to make the code which deals with  this  structure  easier.
     The  line  numbers  of  Line  structures  in  a Buffer are always
     maintained by code in undo.c, which is the only module which ever
     changes the text of a Buffer.

     The Buffer structure also contains:

     o+    flags, including readonly and modified

     o+    current filename associated with the buffer

     o+    temporary filename for buffer preservation

     o+    space for the _m_a_r_k module to store information about  marked
	  lines

     o+    space for the _u_n_d_o module to  store  information  about  the
	  last change

     o+    number of windows associated with the buffer

     The following macros are used to  find  out  certain  information
     about Lines within Buffers:

     lineno(Buffer *b, Line *l)
	  Returns the line number of the specified Line, which belongs
	  to the specified Buffer.

     earlier(Line *l1, Line *l2)
	  Returns _T_R_U_E if l1 is earlier in the buffer than l2.

     later(Line *l1, Line *l2)
	  Returns _T_R_U_E if l1 is later in the buffer than l2.

     is_lastline(Line *l1)
	  Returns _T_R_U_E if l1 is the last line (i.e. the extra line  at
	  the end, not the last text line) of the buffer.





     _P_a_g_e _1_6                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_7


     is_line0(Line *l1)
	  Returns _T_R_U_E if l1 is the 0th line (i.e. the extra  line  at
	  the start, not the first text line) of the buffer.

     _5._3.  _P_o_s_n

     This structure is very simple; it contains a Line pointer and  an
     integer  index  into  the  line's  text,  and is used to record a
     position within a buffer, e.g. the current cursor position.

     These functions are available for operating on Posn structures:

     gchar(Posn *)
	  Returns the character which is at the given position.

     inc(Posn *)
	  Increments the given position, moving  past  end-of-line  to
	  the next line if necessary.  The following type is returned:

	    _e_n_u_m _m_v_t_y_p_e {
		_m_v__N_O_M_O_V_E,    /* _a_t _b_e_g_i_n_n_i_n_g _o_r _e_n_d _o_f _b_u_f_f_e_r */
		_m_v__S_A_M_E_L_I_N_E,  /* _s_t_i_l_l _w_i_t_h_i_n _s_a_m_e _l_i_n_e */
		_m_v__C_H_L_I_N_E,    /* _c_h_a_n_g_e_d _t_o _d_i_f_f_e_r_e_n_t _l_i_n_e */
		_m_v__E_O_L,       /* _a_t _t_e_r_m_i_n_a_t_i_n_g '_\_0' */
	    };


     dec(Posn *)
	  As for inc() but decrements the position.

     lt(Posn *p1, Posn *p2)
	  Returns _T_R_U_E if the position specified by p1 is  earlier  in
	  the buffer than that specified by p2.

     _5._4.  _X_v_i_w_i_n

     This structure maps a screen window onto a Buffer.  It contains:

     o+    a pointer to the Buffer structure which it is mapped onto

     o+    the  cursor's  _l_o_g_i_c_a_l  position  in  the  buffer  (a   Posn
	  structure)

     o+    the cursor's  _p_h_y_s_i_c_a_l  position  in  the  window  (row  and
	  column)

     o+    information about size and location of screen window

     o+    current text of status line

     o+    forward and backward pointers to other windows

     Note that there is at least one Xviwin for every Buffer.

     When the editor was modified  to  support  buffer  windows,  many


     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_7





     _1_8                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     global   variables   were   moved  into  the  Buffer  and  Xviwin
     structures; some were left as globals.  For  instance,  the  _u_n_d_o
     and  _m_a_r_k  facilities  are  obviously buffer-related, but _y_a_n_k is
     useful if it is global (actually static within its  own  module);
     it was decided that _s_e_a_r_c_h and _r_e_d_o should also be global.

     Some modules have their own internal static data structures;  for
     instance,  the  _s_e_a_r_c_h module remembers the last pattern searched
     for.   Also,  certain  modules  use  data  structures  which  are
     included in more global ones; e.g. each Buffer structure contains
     some data used  only  within  _u_n_d_o._c.   This  is  not  very  well
     structured,  but  in  practice it's quite clean because we simply
     ensure that references to such structures are kept local  to  the
     module which "owns" them.

     _5._5.  _M_a_r_k

     This data structure records a mark (defined by  the  m  command).
     It contains a Posn and a character field to hold the letter which
     defines the  mark.   Each  Buffer  contains  an  array  of  these
     structures  for  holding  alphabetic  marks,  plus  one  for  the
     previous context mark (as used by the '' and ``  commands).   The
     file _m_a_r_k._c deals with marks.

     _5._6.  _C_h_a_n_g_e

     This structure records a single change which has been made  to  a
     buffer.   It  also  contains  a pointer, so that it may be formed
     into a list.  See the discussion  of  _u_n_d_o._c  below  for  further
     details.

     _5._7.  _F_l_e_x_b_u_f

     This structure is used to store text strings for which the length
     is  unknown.  The following operations are defined for this type.
     All functions take a Flexbuf pointer as a parameter.

     flexnew(f)
	  Initialise a Flexbuf; not needed for static Flexbufs.

     flexclear(f)
	  Truncate a Flexbuf  to  zero  length,  but  don't  free  its
	  storage.

     flexdelete(f)
	  Free all storage belonging to a Flexbuf.

     flexempty(f)
	  Return _T_R_U_E if the Flexbuf is empty.

     flexlen(f)
	  Return the number of characters in the Flexbuf.





     _P_a_g_e _1_8                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_9


     flexrmchar(f)
	  Remove the last character from a Flexbuf.

     flexpopch(f)
	  Remove the first character from a Flexbuf and return it.

     flexgetstr(f)
	  Return a pointer to the string contained in the Flexbuf.

     flexaddch(f, c)
	  Add the character c to the end of the Flexbuf.

     lformat(f, fmt, ...)
	  A subset of sprintf() but for Flexbufs.

     vformat(f, fmt, va_list)
	  A subset of vsprintf() but for Flexbufs.

     The last two functions are especially useful,  since  they  avoid
     the usual problems with the lack of bounds-checking in sprintf().
     All code in the editor itself now  uses  Flexbufs  to  avoid  the
     possibility  of  buffer  overruns,  and to reduce the size of the
     executable.  Some OS-specific modules, however, may still use the
     printf()  family.   The  subset  of printf-like format specifiers
     implemented includes those for integers and strings, but not  for
     floating-point numbers.

     _5._8.  _b_o_o_l__t

     A simple Boolean type; has  values  _T_R_U_E  and  _F_A_L_S_E,  which  are
     defined  as  1  and  0  so  as to be compatible with C comparison
     operators.

     _5._9.  _x_v_E_v_e_n_t

     This type is defined in the previous section, since it forms part
     of the porting interface.

     _5._1_0.  _V_i_r_t_S_c_r

     This type represents a virtual screen, and is  constructed  in  a
     similar way to a _c_l_a_s_s.  It contains some function pointers which
     may be used to manipulate the screen in various  ways,  and  some
     private data which is used by the implementation of the class.

     The old terminal interface, which consisted of a set of disparate
     functions,  is being replaced by the VirtScr interface; the first
     step in this process has been accomplished by the provision of  a
     default VirtScr implementation using the old primitive functions.
     New, native, VirtScr implementations may now be coded, which will
     increase the efficiency of screen output.

     As the final stage, a windowing  implementation  of  the  VirtScr
     class   will   be   provided,   using   the   underlying  VirtScr
     implementations, and the window-handling code in the editor  will


     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_9





     _2_0                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


     be  modified  to that each occurrence of an Xviwin references its
     own VirtScr.  It will then be possible to build a version of  the
     editor  which operates in a true windowing environment by using a
     separate screen window for each buffer, instead  of  the  current
     vertical-split method.

     A full definition of the  VirtScr  type  will  be  found  in  the
     previous section.

     _5._1_1.  _G_l_o_b_a_l _V_a_r_i_a_b_l_e_s

     There are only a few global variables in the editor.   These  are
     the important ones:

     curbuf
	    pointer to the current Buffer

     curwin
	    pointer to the current Xviwin

     State   the current _s_t_a_t_e of the editor; controls what we do with
	    input characters.  The value is one of the following:

	    NORMAL    The  default  state;  vi-mode  commands  may  be
		      executed

	    INSERT    Insert mode, i.e. characters typed get  inserted
		      into the current buffer

	    REPLACE   Replace  mode,  characters  in  the  buffer  get
		      overwritten by what is typed

	    CMDLINE   Reading a colon-command, regular  expression  or
		      pipe command

	    DISPLAY   Displaying text, i.e. :p  command,  or  :set  or
		      :map with no argument

     echo   This  variable   controls   what   output   is   currently
	    displayable.   It  is  used  at  various points within the
	    editor to stop certain output which is either  undesirable
	    or  sub-optimal.   It  must  always  be  restored  to  its
	    previous  value  after  the  code  which  changed  it  has
	    finished what it is doing.

     kbdintr
	    This can be set to a non-zero value to  indicate  that  an
	    asynchronous  user-generated interrupt (such as a keyboard
	    interrupt) has occurred.   See  the  discussion  of  event
	    handling in the previous section.







     _P_a_g_e _2_0                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _2_1


     _6.  _S_O_U_R_C_E _F_I_L_E_S

     The header file _x_v_i._h contains  all  the  type  definitions  used
     within the editor, as well as function declarations etc.

     The following source files form  the  primary  interface  to  the
     editor:

     startup.c
	       Entry point for the editor.  Deals  with  argument  and
	       option   parsing  and  initial  setup,  calling  module
	       initialisation functions as necessary.

     events.c   Contains the routine xvi_handle_event(), which is  the
	       entry  point for handling input to the editor; input is
	       passed to different routines  according  to  the  State
	       variable.   Timeouts on input are also handled here, by
	       calling appropriate routines in map.c or preserve.c.

     edit.c    Deals with insert and replace modes.

     normal.c   Handles normal-mode commands.

     map.c     This file is responsible for all  input  mapping  (both
	       set   up   by  the  :map  command  and  internally  for
	       function-key mappings;  it  also  implements  a  stuff-
	       characters-into-the-input-stream   function   for   use
	       within the editor.   This  is  used,  for  example,  to
	       implement command redo (but _n_o_t to implement "undo" and
	       "put" as in STEVIE).


     Colon (ex-type) commands are handled by this group:

     cmdline.c
	       Decodes and executes colon commands.

     ex_cmds1.c
	       File-, Buffer- and Xviwin-related colon commands.

     ex_cmds2.c
	       Other colon commands (e.g. shell escape).


     Screen updating is done within the following files:

     screen.c   Screen updating code, including handling of line-based
	       entry  (for  colon  commands, searches etc) as they are
	       typed  in,  and  display-mode  stuff   (for   parameter
	       displaying, :_g/_r_e/_p etc).

     cursor.c   This file contains the single  function  cursupdate(),
	       which  is  responsible  for deciding where the physical
	       screen cursor should be, according to the  position  of
	       the  logical  cursor  in the buffer and the position of


     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _2_1





     _2_2                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s


	       the window onto that buffer.  This routine is not  very
	       optimal, and will probably disappear in due course.

     defscr.c   This file contains the default implementation  of  the
	       VirtScr  class,  on  top  of  the  old  terminal/system
	       interface.

     status.c   Functions to update the status line of a window; there
	       are  different  functions  to  display file information
	       (name, position etc.) and error/information messages.


     These files deal with specific areas of functionality:

     find.c    Search functions:  all  kinds  of  searches,  including
	       character-based   and  word-based  commands,  sections,
	       paragraphs,  and  the  interface  to  "real"  searching
	       (which is actually done in _s_e_a_r_c_h._c).

     mark.c    Provides primitives to record marks  within  a  Buffer,
	       and to find the marks again.

     mouse.c   Code to  handle  mice  moving  the  cursor  around  and
	       resizing windows.

     param.[ch]
	       Code to handle setting of, and access  to,  parameters.
	       (These are things like tabstops, autoindent, etc.)

     pipe.c    Handles piping through system commands.

     preserve.c
	       File preservation routines.

     search.c   Code  for  pattern-searching  in  a  buffer,  and  for
	       substitutions  and  global execution.  Uses regexp.[ch]
	       for the actual regular expression stuff.

     tags.c    Routines to handle tags - for :tag, -t and ^].

     undo.c    Code to deal with doing and undoing;  i.e.  making  and
	       unmaking  changes to a buffer.  This is one of the more
	       complex and delicate files.

     yankput.c
	       Code to deal with yanking and putting  text,  including
	       named buffers.


     while these files provide lower-level functions:

     alloc.c   Memory allocation routines.





     _P_a_g_e _2_2                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2





     _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _2_3


     ascii.[ch]
	       Deals  with  the  visual  representation   of   special
	       characters on the display (e.g. tabs, control chars).

     buffers.c
	       Routines dealing with the  allocation  and  freeing  of
	       Buffers.

     fileio.c   File I/O routines; reading, writing, re-editing files.
	       Also handling of the format parameter.

     flexbuf.c
	       Flexible-length character-buffer routines.

     misccmds.c
	       Miscellaneous functions.

     movement.c
	       Code to deal with  moving  the  cursor  around  in  the
	       buffer, and scrolling the screen etc.

     ptrfunc.[ch]
	       Primitives to handle Posn structures; including various
	       operators to compare positions in a text buffer.

     regexp.[ch], regmagic.h
	       Regular-expression stuff, originally written  by  Henry
	       Spencer  (thanks  Henry)  and  slightly  hacked for use
	       within xvi.

     signal.c   Handling of  terminal-generated  signals  in  an  ANSI
	       environment.

     virtscr.h
	       Virtual Screen interface definition.   This  is  a  new
	       part  of  xvi, and is not yet fully completed.  When it
	       is finished, it will provide the ability  to  implement
	       "native"   versions  of  xvi  under  various  windowing
	       systems, in a clean and wholesome way.  Currently there
	       is  a  single  instance  of the VirtScr class, which is
	       defined on top of the old system/terminal interface.

     windows.c
	       Code to deal with creating, deleting, resizing windows.

     version.c
	       Contains only the version string.










     _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _2_3


