THIS VERSION ISN'T READY FOR RELEASE YET. It isn't even close; many
vi commands are missing, and the only ex commands supported are ":q"
and ":set". The most current RELEASE of elvis is still 1.8pl4. I am
making this pre-alpha version of 2.0 available so that interested
people can examine it, and decide whether they want port it to their
own operating system and user interface. If you don't have any free
time to spend on elvis, then you don't want this version.
The remainder of this article describes the features of elvis 2.0,
and the task of porting it, so you can decide whether it is even
worth the effort for you to download it now.
Elvis 2.0 is a major rewrite. All of the low-level buffer manipulation
functions have been recoded. The screen update code and keystroke
processing code is also completely new. I hope to be able to salvage
most of the ex command processing functions, and many of the vi command
processing functions, but I haven't gotten that far yet. Currently,
only about 10% of elvis 2.0's source code is derived from 1.x code.
Since elvis 1.0 was released, I've received many suggestions for
enhancements. With very few exceptions, each enhancement fell into
one of two categories: either it could be added to 1.x cleanly, or
it would require a major rewrite of elvis' low-level code.
The enhancements that could be added to 1.x cleanly were added indeed
added to 1.x.
The remaining enhancements had to wait for 2.0. Since these new
features depend on characteristics of the low-level code, they had
to be designed & coded very early -- before even the most basic vi
functions. Consequently, even this pre-alpha version of 2.0 has
support for these features, even though it doesn't yet support the
The new features are:
* Multiple edit buffers. You don't need to write out one file before
loading another. Also, the cut buffers are implemented as regular
edit buffer, so you'll be able to use the ":p" command to display
the contents of cut buffers... as soon as I implement ":p".
* Multiple undo levels. This still isn't infinite undo; you need to
choose a finite number of undo levels to store for each buffer.
* Unlimited line length & number of lines. Each edit buffer is limited
to 2 gigabytes. That can be one long line, or 2 billion blank lines,
* Restartable edit sessions. Each session session's state is stored in a
single file. This state includes the names and contents of all edit
buffers. Each session can be suspended at any time (by exiting elvis)
and resumed later. This replaces the complex preserve/recover scheme
that the real vi and elvis 1.x use.
* "Open" edit mode. This allows vi commands to be used on a single text
line, displayed at the bottom of the screen. This works even if elvis
doesn't know what kind of terminal you're using because the only control
codes it uses are carriage-return, line-feed, and backspace.
* Ex history. This is implemented by using one edit buffer for command
entry, and "open" edit mode to enter commands into that buffer. You
can recall previous command lines just by entering a visual 'k' command.
All other vi commands are also available.
* Vi commands in input mode. Elvis 1.x allows some ex commands to be
entered while in input by preceding them with <Control-O>. Elvis 2.0
allows <Control-O> to be used with *ALL* visual commands except those
which don't make any sense in input mode.
* Cleaner support for different operating systems. The OS-dependent
functions now reside in separate modules. To add support for a new
operating system, you only need to rewrite those modules. I've tried
to design the module interfaces without a bias towards any particular
operating system. I have already implemented UNIX versions of these
* Support for different user interfaces. Internally, elvis 2.0 is event
driven; this is intended to make graphical user interfaces easier to
support. A single elvis executable can be built to support several
different GUIs, and select one of them at run time. Support for each
GUI resides in a separate module. I have implemented a fairly good
termcap-based interface, and a minimal X11 interface.
* Multiple windows. If the user interface supports multiple windows,
then the rest of elvis is, too. (Both the termcap and X11 interfaces
support multiple windows.) Each window can show a different buffer.
You can also have multiple windows showing the same buffer, in which
case any change made in one window will immediately be reflected in
* Vi-style wrapping of long lines. Elvis 2.0 still supports the side-
scrolling feature of elvis 1.x, but you can also have long lines wrap
onto multiple rows of your window, if you prefer.
* Multiple edit modes. Edit modes affect how text is displayed, the
behavior of certain commands, and (eventually) auto-indentation.
I have implemented edit modes for "normal", "hex", and "c". "normal"
is standard vi. "hex" is an interactive hex dump of the buffer.
"c" is exactly like "normal", except that it can display different
C tokens in different fonts. By default, "c" mode displays C reserved
words and macros in boldface, and comments in italics. Eventually,
I intend to add an "nroff" mode which will perform on-screen formatting.
Different windows can be in different edit modes at the same time,
even if they're showing the same buffer.
* Printer support. Elvis 2.0 can print a buffer's contents, using the
same drawing code as the current edit mode. If you're in "hex" mode,
you get a hex printout; if you're in "c" mode, you get pretty-printed
C code. Currently, elvis 2.0 can use Epson escape code, HP escape codes,
or generic overtyping. I intend to add PostScript support before elvis
2.0 is officially released.
* Hex input. In input mode, or the visual <Shift-R> command, you can
enter a character in hexadecimal by typing ^X and then two hex digits.
* Rectangular text selections. In addition to <v> for character selections,
and <Shift-V> for line selections, elvis 2.0 will allow <Control-V> to
be used for selecting rectangular areas. (In this pre-alpha version,
this code is still buggy, and the rectangular paste operation is still
THE TASK OF PORTING
To port elvis 2.0, you'll need to re-implement the OS-dependent modules,
and at least one GUI module. Also, although I have tried to avoid a
UNIX bias in my design, there's always the chance that I may have missed
something, so the OS module interfaces may need to be tweaked. I'm also
pretty sure I'll need to add support for more types of events, especially
when people start implementing GUIs with pull-down menus.
There are four OS-dependent modules. They implement block I/O (to the
session file), text I/O, directory I/O (for examining file permissions
and expanding wildcards), and program execution (including "filter"
programs). Of these, the directory I/O module is the most challenging,
so you should probably look at it first.
Each user interface is implemented as a separate module. This module
consists of a large number of functions which support various features
of a typical GUI, and data structure which is initialized to contain
pointers to these functions. Most of these functions are optional;
if you omit an optional function, elvis will work around it.
One function in the user interface implements the main event-reading
loop. When an event is received, this function will generally call
a function in elvis' portable "event" module. The "event" module
contains functions to support mouse clicks & draw-throughs, key presses,
window create/destroy/expose/resize, and a few other activities (such as
searching) which might be used to implement a menu item. I expect other
people to come up with menu items which aren't currently supported by
an "event" function yet, so the "event" module will probably grow.
The termcap interface is split into two parts: an OS-dependent part and
a (hopefully) portable part. If you want to support the termcap interface
on your system, then you'll need to re-implement the OS-dependent part
for your OS. This includes functions to switch the terminal into "raw"
mode and back again, to determine the terminal type and the size of the
screen, to write characters (which may include escape sequences) to the
screen, and to read characters from the keyboard with timeout.
characters to the screen,
I would prefer to avoid UNIX-emulation libraries. They may make porting
marginally easier, but they can make installation harder for everybody
who tries to use that port. Also, they often have stricter redistribution
agreements than I like.
Elvis 2.0 runs under UNIX, and termcap or X11 user interfaces. About
half of the visual commands have been implemented. None of the ex commands
have been implemented, although I've dummied up some support for ":q" and
":set" just to prove that my method for inputing ex commands lines works.
Buffer management is complete, except for copying data from one buffer to
another. This copy operation is used to implement both cut & paste. A
simple-minded version of copying has been implemented, but I can make it
much more efficient. Also, elvis can't paste rectangular chunks of text
correctly yet. Buffer management is also responsible for storing "undo"
versions of a buffer, and restoring them. Currently, "undo" may leave
the cursor in a weird place.
Marks are fully implemented. Marks refer to a specific offset into a
Keystroke handling is pretty complete. Each window is always in one of
three modes: vi command mode, input mode, or "hit <Enter> to continue"
mode. This is implemented as a stack of key processing states.
The outputting of error messages is *almost* complete. Currently, all of
the messages that elvis 2.0 outputs are terse. I intend to allow a buffer
to be used for translating the terse messages into verbose messages. This
will allow elvis to be customized at runtime to display error messages in
Display updating seems to work, but the transition from "open" mode to
"visual" could use a bit of optimization. Currently, if an ex command
produces a single output line, then elvis 2.0 will wait for you to hit
the <Enter> key before switching back to visual mode. Ideally, if there
is only one line output it should show that line at the bottom of the
visual screen without waiting for <Enter>.
Autoindent is not supported yet. To support autoindent, I'll need to
modify the interface to edit modes.
A general comment: Currently, less than 10% of elvis 2.0's source code is
derived from elvis 1.x's source code. This is because all I've done so
far is reimplement the low-level support functions. Now that I'm starting
to support the high-level commands, I hope I can start recycling more code
from 1.x. By the time 2.0 is finished, I expect about 30% of it to be
derived from elvis 1.x. Also, I hope to recycle parts of the 1.x ports
to implement the OS-dependent modules. This means that 2.0 should support
at least a termcap interface on all of the systems that 1.x currently
My free time is limited. I'd rather not be involved in all the details
of a particular port. If two or more people are going to be working on
the same port, please coordinate that among yourselves.
Question: Is the comp.editors newsgroup an appropriate place to discuss
news of pre-release versions of elvis? It would certainly be a convenient
way for me to announce new developments, and I suspect many netfolk will
be interested in the progress of 2.0, but don't have enough space time
to contribute to the development or porting projects. On the other hand,
EMACS users could be annoyed.
Steve Kirkendall kirk...@cs.pdx.edu Grad Student at Portland State U.
>A pre-alpha version of elvis 2.0 is available via anonymous FTP from
>Question: Is the comp.editors newsgroup an appropriate place to discuss
>news of pre-release versions of elvis? It would certainly be a convenient
>way for me to announce new developments, and I suspect many netfolk will
>be interested in the progress of 2.0, but don't have enough space time
>to contribute to the development or porting projects.
>On the other hand, EMACS users could be annoyed.
I'd be very happy with updates coming here.