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".
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.)
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.
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.
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.
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 | ^-------^----------------------------------------------^
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.
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.
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!
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?)
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.
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.
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.