CONTENTS
  • 1. ABOUT THIS FILE
  • 2. NEW FEATURES
  • 2.1 Multiple edit buffers
  • 2.2 Multiple user interfaces
  • 2.3 Multiple windows (if the user interface supports them)
  • 2.4 A variety of display modes
  • 2.5 Hardcopy from within elvis
  • 2.6 C-like expression evaluator
  • 2.7 Extremely customizable
  • 2.8 Online help
  • 3. CHANGED FEATURES
  • 3.1 Ex command syntax
  • 3.2 Crash recovery
  • 3.3 Options
  • 3.4 File initialization
  • 3.5 The :if command
  • 4. FUTURE PLANS
  • 5. LINKS TO RELATED FILES

  • 1. ABOUT THIS FILE

    This file is written in the HTML markup language. You can view it with any WWW viewer, such as Mosaic or Netscape. You can also use elvis 2.0 to view it; this version of elvis has the ability to view HTML documents, and print them.

    This file has many hypertext links. Use them! If you're using elvis 2.0 to browse this file, then hypertextual references will appear as underlined text. (Except on color PCs; since color video cards don't support underlining, hypertextual references will be colored -- white on red, by default.) To follow the hypertext link, move the cursor onto the underlined text and press (Enter). To go back, press (Control-T). The (Tab) key moves the cursor forward to the next hypertext reference.

    If elvis 2.0 doesn't automatically start up in HTML mode when you view this file, then you'll need to force it into HTML mode by giving the command ":display html".

    2. NEW FEATURES (Relative to elvis 1.8pl4)

    There are a lot of new features. The major ones are:

    2.1 Multiple edit buffers

    You can be editing many files concurrently. Also, elvis uses some buffers internally, in addition to the buffers that are created for holding your files. The command ":bu" lists the buffers that hold your files, and ":bu!" (with a !) lists all buffers.

    The command ":all command" applies an ex command to all user buffers, and ":all! command" applies an ex command to all buffers including internal ones. An example of this would be ":all set filename? readonly?" which tells you the status of each buffer's "readonly" option.

    Any ex command can be preceded by a buffer name in parentheses. This indicates that the command should be applied to that buffer instead of the default buffer. For example, ":(foo)set noreadonly" turns off the readonly option for the buffer "foo" even if we're editing some other buffer.

    To switch from one buffer to another, enter an ex command line which contains only the name of the desired buffer in parentheses. For example, the command ":(foo)" would cause elvis to switch to the buffer "foo". (This is intended to be analogous to giving just a line number when you want to move the cursor to a given line, as in ":10" to move to line 10.)

    2.2 Multiple user interfaces

    A single elvis executable can contain several user interfaces. Each time elvis starts up it will choose one and use that interface until elvis exits. The usage message lists the available user interfaces; to see this message, give the shell command "elvis -?".

    Currently, the most important interfaces are named "x11" and "termcap". By default, elvis will use the x11 interface under UNIX if the DISPLAY environment variable is set, and the termcap interface otherwise. Currently both of these are very basic, but I expect them to become more elaborate over time.

    The "x11" interface allows you to use the mouse to move the cursor or select text. Dragging the mouse with the left button pressed selects characters; the middle button selects a rectangular region of text; and the right button selects whole lines. Clicking the left button (without dragging) cancels any pending selection and moves the cursor; the middle button simulates keystrokes like xterm; the right button moves the cursor like the left button, except that the right button doesn't cancel any pending selection. Double-clicking the left button will simulate a ^] command, which performs tag lookup. Double-clicking the right button will simulate a ^T command, which returns to the previous position via the tag stack. When using the "x11" interface, elvis recognizes some additional command-line flags, including -fn font to set the normal font, -fb font to set the bold font, -fi font to set the italic font, and -courier pointsize to set all three fonts to appropriate Courier fonts.

    Code is also provided for a "curses" interface, but I don't recommend it. I wrote this interface mostly to prove that it could be done.

    2.3 Multiple windows (if the user interface supports them)

    Both the x11 and termcap interfaces support multiple windows. (The x11 interface creates a new top-level application window for each editing window, and the termcap interface subdivides the screen.) Each window can show a different edit buffer, or different windows can show the same buffer. In the latter case, any changes made in one window are immediately reflected in all windows that show that buffer.

    Elvis supports most of the same window commands as nvi and vim. This includes commands such as ":split" to create a new window, and ^W ^W to switch to a different window.

    2.4 A variety of display modes

    Display modes determine how a text is displayed. Elvis supports display modes named "normal", "syntax", "hex", "html", and "man".

    Each window can be in a different display mode. You set the display mode via the ":dis mode" command. The command ":dis" (with no mode) lists all available modes, with an asterisk next to the one that this window is currently using. There is also a ":no" command which is short for ":dis normal".

    Each buffer has a "bufdisplay" option. Each time a window starts to display a buffer, the window's display mode is set according to the buffer's bufdisplay option. The default "elvis.arf" file automatically sets bufdisplay to a reasonable value.

    In visual command mode, ^W d toggles between "normal" mode and the buffer's bufdisplay mode. If the buffer's bufdisplay option is also "normal", then ^W d toggles between "normal" and "hex" modes.

    2.5 Hardcopy from within elvis

    Elvis uses its display modes when sending text to the printer, just as it does when updating the window. Consequently elvis can be used to print hex dumps, pretty-printed C code, or formatted HTML documents or "man" pages.

    Throughout the life of elvis 1.x, I was always concerned about how to distribute elvis' documentation. Many users don't have access to troff; they prefer plain text documentation. But people who do have troff would prefer to use it when printing the documentation, because the resulting output is prettier than a plain-text file. For elvis 2.0, this won't be an issue because I'll distribute the documentation in the form of HTML documents, and people who have Netscape or another fancy HTML reader can use it to print the documentation. People who have no fancy HTML readers can still print the documentation using elvis itself.

    The command for printing a buffer is ":lpr" (which can be abbreviated to ":lp"). But before you do that, you'll need to set some options...

    .-----------.------------------------------------.
    | OPTION    | MEANING                            |
    |-----------|------------------------------------|
    | lpcolumns | Width of the printer, in columns   |
    | lpconvert | Convert Latin-1 chars to PC-8?     |
    | lpcrlf    | Convert newlines to CR-LF pairs?   |
    | lpformfeed| Output a ^L after the last page?   |
    | lplines   | Length of the page, in lines       |
    | lpout     | Print spooler program, or filename |
    | lppaper   | Paper size (for PostScript only)   |
    | lptype    | Printer type (see below)           |
    | lpwrap    | Wrap long lines? (else clip them)  |
    ^-----------^------------------------------------^
    
    The most important option is "lptype", since it controls what type of escape codes (or whatever) elvis will use to perform font changes. The compiled-in default value is "lptype=dumb" which is the most conservative value -- it doesn't attempt to perform any font changes. The complete list of acceptable values is:
    .-------.----------------------------------------------.
    | VALUE | PRINTER DESCRIPTION                          |
    |-------|----------------------------------------------|
    | ps    | PostScript, one logical page per sheet       |
    | ps2   | PostScript, two logical pages per sheet      |
    | epson | Most dot-matrix printers, no graphic chars   |
    | pana  | Panasonic dot-matrix printers                |
    | ibm   | Dot-matrix printers with IBM graphic chars   |
    | hp    | HP printers, and most non-PostScript lasers  |
    | cr    | Line printers, overtypes via carriage-return |
    | bs    | Overtypes via backspace, like nroff          |
    | dumb  | Plain ASCII, no font control                 |
    ^-------^----------------------------------------------^
    

    2.6 C-like expression evaluator

    Elvis has a built-in calculator which uses a syntax resembling C expressions. The names of options can be used in place of variables, and you can also use "$NAME" to access the value of an environment variable.

    Strings are supported. Any two strings (or expressions which evaulate to strings) placed side-by-side with no operator between them will have their values concatenated. You can truncate strings using "string<<length" or "string>>length".

    There are several built-in functions. When you call one of these functions, there must not be any whitespace between the function name and the following parenthesis. The built-in functions are:

    .------------------.--------------------------------------------.
    | FUNCTION(ARG)    | RETURN VALUE                               |
    |------------------|--------------------------------------------|
    | strlen(string)   | number of characters in the string         |
    | toupper(string)  | uppercase version of string                |
    | tolower(string)  | lowercase version of string                |
    | isnumber(string) | "true" iff string is a decimal number      |
    | hex(number)      | string of hex digits representing number   |
    | octal(number)    | string of octal digits representing number |
    | char(number)     | convert number to 1 ASCII char, as a string|
    | exists(path)     | "true" iff file exists                     |
    | dirperm(path)    | string indicating file attributes          |
    | dirfile(path)    | filename.ext part of a path                |
    | dirname(path)    | directory part of a pathname               |
    | dirdir(path)     | directory, like dirname(file)              |
    | dirext(path)     | extension (including the . )               |
    | basename(path)   | filename without extension                 |
    | elvispath(file)  | locate a file in elvis' configuration path |
    | knownsyntax(path)| "true" iff file type is listed in elvis.syn|
    | buffer(bufname)  | "true" iff buffer exist                    |
    | current(name)    | value of an internal variable (limited)    |
    | feature(name)    | "true" iff a given feature is supported    |
    ^------------------^--------------------------------------------^
    

    Expressions are used by several commands, including the ":if expression" command. The ":and" and ":or" commands of elvis 1.8 have been removed since ":if" can easily achieve the same effect simply by using the && or || operators.

    There is also a ":let option=expression" command, which evaluates the expression and sets the option to the resulting value. Note that unlike :set, :let can only assign a value to a single option at a time.

    There is also a ":calc expression" command which simply displays the result of the expression. Also, if you visibly select some characters (using the v command) and then apply the = operator to those characters, elvis will evaluate the selected text and replace it with the result. When = is applied to lines, it still runs an external filter program just as it did in version 1.8.

    A slightly different expression syntax is used by the ":eval expression" command. The expression is mostly left unchanged, except that text inside parentheses is evaluated in the normal syntax. Outside of parentheses the only characters that have special meaning are \ and $NAME. The :eval command is used to calculate commands and then execute them. For example, during initialization elvis performs a ":eval $EXINIT" to execute the value of the EXINIT environment variable.

    2.7 Extremely customizable

    NOTE: In the following paragraphs, when I say elvis "looks for" a file, I mean that it searches through any directories named in the value of the "elvispath" option.

    When elvis starts up, it looks for a file named "elvis.ini". If this file is found, its contents are executed as a series of ex commands. The default "elvis.ini" file performs the traditional vi initialization such as ":source $HOME/.exrc". By changing this file, you can completely change the way elvis initializes itself. As a mild example, you could make it read .elvisrc instead of .exrc.

    After interpretting "elvis.ini", elvis looks for a few more files right away. If it finds them, it loads them into internal edit buffers right away but doesn't interpret them yet. The most interesting ones are "elvis.arf" and "elvis.bwf".

    The "elvis.brf" file is interpretted Before Reading a File into an edit buffer. Typically, this will set the buffer's "binary" option, depending on its file name extension.

    The "elvis.arf" file is interpretted After Reading a File into an edit buffer. Typically, this will set the buffer's "bufdisplay" option, depending on its file name extension.

    The "elvis.bwf" files is interpretted Before Writing the File back out again. It will typically be used to copy the original file to "filename.bak" or something like that.

    Elvis also supports an "elvis.awf" files, but I haven't found much use for it yet. Perhaps it could tie-in to a revision control system?

    You can use an "elvis.msg" file to translate the normal terse messages into verbose messages. This is meant to allow elvis to issue messages in a local language. Each time elvis issues a message, it attempts to look for a line that looks like "terse message: verbose message" and if found it will substitute the verbose message for the terse one. Messages are then subjected to the same sort of evaluation as for the ":eval expression" command, with $1 through $9 used to represent any arguments of the message.

    2.8 Online help

    The command ":help" reads the file elvis.html (which is an HTML document) and displays it in a separate window. When ":help" is run with no arguments, it lists the Table of Contents which has hypertext links to all the rest of the documentation. You can also supply the name of an ex command, option, or vi command as an argument to jump directly to the relevent part of the documentation. For example, I suggest you try ":help :help" to get a description of the help command itself.

    3. CHANGED FEATURES

    A few features of elvis 1.8 have changed significantly in 2.0. They are:
  • 3.1 Ex command syntax
  • 3.2 Crash recovery
  • 3.3 Options
  • 3.4 File initialization
  • 3.5 The :if command
  • 3.1 Ex command syntax

    The ex command interpretter in elvis 2.0 is intended to meet POSIX specifications, with extensions to support multiple buffers.

    POSIX requires most commands to support print flags. This is a 'p', 'l', or '#' appended to the end of the command line, which causes the current line to be printed when the command is complete. For example, ":dp" deletes the current line and then prints the line that the cursor is left on.

    POSIX also indicates that certain commands can take a "count" argument to indicate how many lines are affected. For example, ":10d5" is equivelent to ":10,14d".

    To support multiple buffers, elvis allows you to precede a line address with the name of an edit buffer, in parentheses. The line address will then be interpretted as referring to lines in that buffer, rather than the window's current buffer. For example, "(foo)%t(bar)$" copies all lines of the "foo" buffer onto the end of the "bar" buffer. This notation is used during crash recovery, so you had better know it!

    3.2 Crash recovery

    In elvis 1.8, if a crash occured while you were editing text, your changes could be preserved (moved to the /usr/preserve directory) by a program named elvprsv, and then recovered (moved from /usr/preserve to your working directory) by another program named elvrec.

    elvis 2.0 uses a different method. The change was made mostly with the idea of having elvis eventualy support COSE desktop standards on X-windows systems, which call for all applications to be restartable. To do this, elvis stores all aspects of the edit session in a single file, and a later elvis process can be told to reload the same session file. (Note: elvis doesn't meet COSE specs yet, but this is a big step in that direction.)

    The session file also offers a simple way to recover after a crash: simply start a new elvis process on the old session file, write your text using a ":w" command, and then exit elvis and delete the old session file. A more detailed description follows.

    Begin by invoking "elvis -r". The "-r" tells elvis to look for an old session file, to disregard the "in use" flag, and to perform extra integrity checks when reloading that session file. If you aren't using the default session file, you'll probably need to add a "-f sessionfile" argument to the command line, so elvis knows which session you wish to recover. Don't give the name of your text file on the command line!

    When elvis starts up, you will see an empty buffer. DON'T PANIC! Remember, elvis supports multiple edit buffers. It simply created a new, empty edit buffer and is showing that; your old edit buffer is still in there somewhere. You can use the command ":buf" to list the buffers.

    Write your old buffer out to a new file. The command for writing the buffer is ":(buffer)w file", where buffer is the name of the buffer (usually the same as the name of the original file) and file is the name of a new file. (For safety's sake, you shouldn't overwrite your old text file yet.) Note the parentheses around the buffer name! They're important!

    You should then exit elvis. Although I've tried to make elvis ensure that the recovered session file is intact, there will always be some doubt. This makes it dangerous to perform any actual editing using that session file.

    Inspect the new file and if it looks okay, replace the old file with it. If it doesn't look okay, then there's still hope. Restart elvis on that session file again, and try to find an "undo" version of that buffer, by giving the command ":(buffer)u" where buffer is the buffer name, and then write it out to a new file via the ":(buffer)w file" command again. Hopefully the "undo" version will be in better shape.

    After recovering the text files from the session file, you should delete the session file. The simplest way to find the name of the session file is to invoke elvis as "elvis -r -Gquit". Normally elvis deletes session files automatically when it exits, when in recovery mode it becomes more conservative.

    (See? Isn't that simpler?)

    3.2 Options

    The syntax of the ":set" command has changed; I suggest you look it up in the online manual by starting elvis and giving the command ":help :set". In short, the changes are intended to make elvis more compatible with the real vi, and to handle the huge number of options that elvis 2.0 supports.

    Not all options are global. Some are associated with buffers, and different buffers may have different values. When you switch buffers, the value of the option will appear to change. Simiarly, some are associated with windows and will vary when you switch from one window to another. Some options are associated with a particular display mode or or user interface, and will not exist if you switch to a different display mode or user interface.

    The "flipcase" option has gone away. Elvis 2.0 determines which non-ascii characters are uppercase or lowercase letters by examining the digraph table.

    The "charattr" and "hideformat" options have gone away. Elvis 2.0 has a "man" display mode which does a much nicer job of previewing man pages.

    The "inputmode" option has been replaced by the new "initialstate" option, which is more versatile.

    3.3 File initialization

    The ~/.exfilerc file is no longer executed after loading a file. Instead, the lib/elvis.arf file is executed. For a description of this, see section 10 (Initialization and sessions) of the online manual. A shorted description of this appears in the "Extremely customizable" subtopic earlier in this file.

    3.4 The :if command

    The syntax of the ":if" command has changed. It now uses a C-like expression syntax.

    The ":and" and ":or" commands have gone away. They are no longer needed, because the ":if" command can easily achieve the same effect using the && and || operators.

    3. FUTURE

    I haven't added any major new features for the last several months, because that would have interfered with the beta-testing of 2.0. Now that 2.0 has been released, I'm able to add features again.

    The first feature to be added will be a graphical Win32 interface, for Windows95 and WindowsNT. Serge Pirotte has been working on this for months, and it is nearly ready for testing. There has been a lot of interest in this, so I want to make it available as soon as possible. I expect to have an alpha-test version of it available around the end of October.

    Lee Johnson is working on a graphical port to OS/2, but it will probably take longer. I can't make any estimates on when it will be available.

    To date, nobody has volunteered to port elvis to the Mac. (Nudge nudge wink wink)

    The first thing I plan to do myself is add some extra smarts to the tags, so they can handle overloaded names better. I intend to make elvis use some heuristics to rank all matching tags according to the likelyhood that they're the tag you're trying to load. The most likely one will then be loaded. If you immediately look up the exact same tag name again, then it'll move to the second match, and so on.

    I also intend to rewrite the ctags program so that it will be able to parse C++ code, and (optionally) place extra hints in the tags file so that elvis' heuristics can do a better job. I'm also toying with the idea of a statistical tags generator, but that's still pretty nebulous at this point.

    I intend to add a true extension language to elvis someday, but I'm not sure it'll be in 2.1. Currently I'm leaning towards using Perl as the extension language.

    4. LINKS TO RELATED FILES

    Most of the following are binary files, not text or HTML files, so you can't view then with your Web browser. But you can use your browser to download the files.
    untar.c
    This is the complete source code for "untar", a little program which extracts files from a gzipped tar archive. Comments near the top of "untar.c" describe how to compile and use it. If you already have the gzip and tar utilities, then you don't need this.
    untardos.exe
    This is an MS-DOS executable, produced from the above "untar.c" file. It can also be run under Windows 3.1, in a Dos-prompt window. For brief instructions on how to use untardos, run it with no arguments.
    untarw32.exe
    This is a Win32 executable, produced from the above "untar.c" file. It runs under WindowsNT, and (I believe) Windows95. It runs somewhat faster than the MS-DOS version. It also supports long file names, but that doesn't matter for the files in the following archives because all of the files in those archives have short names. For brief instructions on how to use untarw32, run it with no arguments.
    elvis-2.0.tgz
    This is a gzipped tar archive of the source code and documentation for Elvis and its related programs.
    msdosexe.tgz
    This archive contains the documentation and MS-DOS executables for Elvis 2.0.
    win32exe.tgz
    This archive contains the documentation and Win32 executables for Elvis 2.0. These were compiled and tested under WindowsNT, but should work under Windows95 as well.