4. EX COMMAND MODE

Ex is an editing mode in which elvis acts like a line editor. This means that you type in a command line, and when the line is complete elvis executes it on the current text buffer. I.e., in ex each line (or group of lines) is a command, as opposed to vi where each character (or group of characters) is a command.

Typically, ex commands are used to do perform complex actions such as global search & replace, or actions which require an argument such as writing the edit buffer out to a different file.

Ex is also used as the configuration language for elvis; configuration scripts such as elvis.ini, .exrc (or elvis.rc), and elvis.arf contain a series of ex commands.

You can switch freely between vi and ex. If you're in vi mode, you can enter a single ex command line via the visual : command, or more permanently switch via the visual Q command. If you're in ex mode, you can switch to vi mode via ex's :vi command.

Normally elvis will start in vi mode, but you can force it to start in ex mode by supplying a -e command line flag. On UNIX systems, you can link elvis to a name which ends with "x" to achieve the same effect.

The remainder of this section discusses how to enter lines, the general syntax of an ex command line, and the specific commands which elvis supports.

4.1 Entering lines

In elvis, when you're typing in an ex command line you're really inputing text into a buffer named "Elvis ex history". All of the usual input mode commands are available, including Backspace to erase the previous character, Control-W to erase the previous word, and so on.

Any previously entered lines will still be in the "Elvis ex history" buffer, and you can use the arrow keys to move back and edit earlier commands. You can even use the Control-O input-mode command with the ?regexp visual command, to search for an earlier command line.

When you hit the Enter key on a line in the "Elvis ex history" buffer, elvis sends that line to the ex command parser, which is described in the next section.

4.1.1 An example

Suppose you enter the command...
	:e ~/proj1/src/header.h
...and then realize that you really wanted "header2.h" instead of "header.h". You simplest way to get "header2.h" is to...
  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key, or ^O k to move back to the preceding command line (which was ":e ~/proj1/src/header.h"). ^O k works because ^O reads and executes one vi command, and the k vi command moves the cursor back one line. The Up arrow key works because it is mapped to "visual k", which does exactly the same thing as ^O k.
  3. Hit the Left arrow key twice, or ^O 2 h, to move the cursor back to the '.' character in "header.h".
  4. Hit 2 to insert a '2' before the '.' character. At this point, the line should look like ":e ~/proj1/src/header2.h".
  5. Hit Enter to submit the revised command line.

Or suppose you really wanted "footer2.h" instead of "header2.h". This is a little trickier because you want to delete characters in the middle of the command line, before inserting the correct text. The simplest way to do this is move the cursor to a point just after the last character that you want to delete, and then backspace over them. The steps are:

  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key or ^O k repeatedly to move back to the ":e ~/proj1/src/header2.h"command line.
  3. Hit the Left arrow key five times, or ^O 5 h, to move the cursor back to the last 'e' character in "header2.h".
  4. Hit the Backspace key four times to delete the word "head". It will still show on the screen, but elvis will know that it has been deleted. This is the same sort of behavior that elvis (and vi) exhibits when you backspace over newly entered text in input mode.
  5. Type f o o t to insert "foot" where "head" used to be. At this point, the line should look like ":e ~/proj1/src/footer2.h".
  6. Hit Enter to submit the revised command line.

4.1.2 The TAB key

The Tab key has a special function when you're inputing text into the "Elvis ex history" buffer. It is used for name completion. (Exception: Under MS-DOS, this feature is disabled in order to reduce the size of the program, so it will fit in the lower 640K.)

Name completion works like this: The preceding word is assumed to be a partial name for an ex command, an option, a tag, or a file. The type of name is determined by the context in which it appears -- commands appear at the start of an ex command line, and the others can only occur after certain, specific command names. Elvis searches for all matches of the appropriate type.

If there are multiple matches, then elvis fills in as many characters of the name as possible, and then stops; or, if no additional characters are implied by the matching names, then elvis lists all matching names and redisplays the command line. If there is a single match, then elvis completes the name and appends a tab character or some other appropriate character. If there are no matches, then elvis simply inserts a tab character.

Also, if while entering a :set command you hit the Tab key immediately after "option=" then elvis will insert the current value of the option. You can then edit that value before submitting the command line.

I tried to make elvis smart enough that the Tab key will only attempt file/command/option completion in contexts where it makes sense to do so, but that code might not be 100% correct. You can bypass the completion by typing a Control-V before the Tab key. You can also disable name completion altogether by setting the "Elvis ex history" buffer's inputtab option to "tab", via the following command:

	:(Elvis ex history)set inputtab=tab
or the abbreviated form:
	:("Eeh)se it=t

By default, elvis ignores binary files when performing filename completion. The completebinary option can be used to make elvis include binary files. That's a global option (unlike inputtab which is associated with a specific buffer), so you don't need to specify the buffer name; a simple :set completebinary will set it.

4.2 Syntax and Addressing

In general, ex command lines can begin with an optional window id. This may be followed by an optional buffer id, and then 0, 1, or 2 line addresses, followed by a command name, and perhaps some arguments after that (depending on the command name).

A window ID is typed in as a decimal number followed by a colon character. If you don't supply a window ID (and you almost never will) then it defaults to the window where you typed in the command line. The :buffer command lists the buffers, and shows which one is being edited in which window. Also, the windowid option indicates the ID of the current window.

A buffer ID is given by typing an opening parenthesis, the name of the buffer, and a closing parenthesis. For user buffers, the name of the buffer is usually identical to the name of the file that it corresponds to. For example, a file named ~/.Xdefaults would be loaded into a buffer which could be addressed as (~/.Xdefaults). Elvis also assigns numbers to user buffers, which may be more convenient to type since numbers are generally shorter than names. If ~/.Xdefaults is the first file you've edited since starting elvis, then its buffer could be addressed as (1). The :buffer command shows the number for each user buffer.

Elvis also has several internal buffers, all of which have names that start with "Elvis ", such as (Elvis cut buffer x) and (Elvis error list). The :buffer! command (with a ! suffix) will list them all. For the sake of brevity, elvis allows you to refer to cut buffers as ("x). Similarly, the other internal buffers can be referred to via a " character and the initial letter in each word of the full name, such as ("Eel) for (Elvis error list).

Commands which don't access the text, such as ":quit", don't allow any line addresses. Other commands, such as ":mark", only allow a single line address. Most commands, though, allow two line addresses; the command is applied to all lines between the two specified lines, inclusively. The tables below indicate how many line addresses each command allows.

Line addresses are always optional. The first line address of most commands usually defaults to the current line. The second line address usually defaults to be the same as the first line address. Exceptions are :write, :lpr, :global, and :vglobal, which act on all lines of the file by default, and :!, which acts on no lines by default.

If you use the visual V command to mark a range of lines, and then use the visual : command to execute a single ex command, then the default range affected by the ex command will be the visibly marked text.

Line addresses consist of an absolute part and a relative part. The absolute part of a line specifier may be either an explicit line number, a mark, a dot to denote the current line, a dollar sign to denote the last line of the file, or a forward or backward search. An explicit line number is simply a decimal number, expressed as a string of digits. A mark is typed in as an apostrophe followed by a letter. Marks must be set before they can be used. You can set a mark in visual command mode by typing "m" and a letter, or you can set it in ex command mode via the "mark" command. A forward search is typed in as a regular expression surrounded by slash characters; searching begins at the default line. A backward search is typed in as a regular expression surrounded by question marks; searching begins at the line before the default line.

If you omit the absolute part, then the default line is used.

The relative part of a line specifier is typed as a + or - character followed by a decimal number. The number is added to or subtracted from the absolute part of the line specifier to produce the final line number.

As a special case, the % character may be used to specify all lines of the file. It is roughly equivalent to saying 1,$. This can be a handy shortcut.

Here are some addressing examples, using the :p command:

   COMMAND      | ACTION
   -------------|-------------------------------------------
   :p           | print the current line
   :37p         | print line 37
   :'gp         | print the line which contains mark g
   :/foo/p      | print the next line that contains "foo"
   :$p          | print the last line of the buffer
   :20,30p      | print lines 20 through 30
   :1,$p        | print all lines of the buffer
   :%p          | print all lines of the buffer
   :(zot)%p     | print all lines of the "zot" buffer
   :/foo/-2,+4p | print 5 lines around the next "foo"

The optional addresses are followed by the command name. Command names may be abbreviated. In the sections that follow, the command's full name is given with the optional part enclosed in square brackets.

Some commands allow a '!' character to appear immediately after the command name. The significance of the '!' varies from one command to another, but typically it forces the command to do something dangerous that it would ordinarily refuse to do. For example, :w file refuses to overwrite an existing file, but :w! file will do it.

Many commands allow (or even require) additional arguments. The descriptions below list which arguments each command accepts with optional commands denoted by square brackets. The most common argument types are:

/regexp/
This is a regular expression. You can use any punctuation character to delimit it, but the '/' character is the most commonly used.
/regexp/newtext/
This is a regular expression followed by replacement text.
count
This is a number - a string of digits. Generally, it is used as the repeat count for certain commands.
cutbuf
This is the name of a cut buffer - a single letter. Elvis also allows (but does not require) a quote character before the letter.
excmds
This is another ex command, or list of ex commands. Traditionally, the whole list of commands had to appear on the same line, delimited by '|' characters. Elvis has the added versatility of allowing a '{' character on the first line, each command on a separate following line, and then '}' on a line by itself to mark the end of the ex command list.
lhs
This is string of characters. If whitespace characters are to be included in it, then they must be quoted by embedding a ^V character before them.
line
This is a line address, as described earlier.
+line
Some commands which cause a file to be loaded also allow you to specify some other command to be executed after the loading is complete. To use this feature, you mist give a "+" followed by the command, in between the command name and the file name. Here's an example that loads foo and then moves the cursor to line 40.
	:e +40 foo

Usually the command is just a line number, so this is denoted as "+line" in this documentation. Other commands are allowed though, such as "+/text" to search for text, or "+normal" to force it to use the normal display mode.

Traditionally, commands supplied in this manner weren't allowed to contain whitespace, because that makes parsing the command line harder. This is too limiting, though, so elvis allows you to embed spaces in the command by wrapping the entire deferred command in double-quotes, like this:

	:e +"set bufdisplay=man" filedb.8
mark
This is the name of a mark - a single lowercase letter. Elvis allows (but does not require) an apostrophe before the letter.
rhs
This is a string of characters. If it begins with a whitespace character, then that character must be quoted by embedding a ^V character in the command line before it. Other whitespace characters in the string do not need to be quoted.
expr
This is an arithmetic expression using the normal syntax.
shellcmd
This is a command line which is passed to the system's command interpreter. Within the command line, the following character substitutions take place, unless preceded by a backslash:
	.-----------.----------------------------.
	| CHARACTER | REPLACED BY                |
	|-----------|----------------------------|
	|     %     | Name of current file       |
	|     #     | Name of alternate file     |
	|     #n    | Name of file whose bufid=n |
	|     !     | Previous command line      |
	|     \@    | Word at cursor location    |
	^-----------^----------------------------^
Note that the \@ substitution requires a backslash. This quirk exists for the sake of backward compatibility - the real vi doesn't perform any substitutions for just plain @.
file or files
This is one or more file name, or a "wildcard" pattern which matches the names of zero or more files. File names are subjected to three levels of processing. First, leading ~ characters and certain other characters are replaced with text, as follows:
    .-----------.------------------------------------------------.
    | SYMBOL    | REPLACED BY                                    |
    |-----------|------------------------------------------------|
    | ~user     | (Unix only) Replaced by home directory of user |
    | ~+        | Replaced by current working directory          |
    | ~-        | Replaced by previous directory (previousdir)   |
    | ~         | Replaced by home directory (home)              |
    | %         | Replaced by the name of the current file       |
    | #         | Replaced by the name of the alternate file     |
    | #n        | Replaced by the filename of buffer with bufid=n|
    | (space)   | Delimits one file name from another            |
    | `program` | Run program, interpret its output as filenames |
    ^-----------^------------------------------------------------^
The second stage of processing evaluates each name using the simpler expression syntax. This basically means that expressions of the form $NAME will be replaced with the value of the environment variable named NAME. Also, you can use parentheses around option names or more complex expressions. For example, if the user option f contains the name of a file, then you could say ":e (f)" to edit that file.

In either of the fiand -mode command with the ?regexp visual command, to search for an earlier command line.

When you hit the Enter key on a line in the "Elvis ex history" buffer, elvis sends that line to the ex command parser, which is described in the next section.

4.1.1 An example

Suppose you enter the command...
	:e ~/proj1/src/header.h
...and then realize that you really wanted "header2.h" instead of "header.h". You simplest way to get "header2.h" is to...
  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key, or ^O k to move back to the preceding command line (which was ":e ~/proj1/src/header.h"). ^O k works because ^O reads and executes one vi command, and the k vi command moves the cursor back one line. The Up arrow key works because it is mapped to "visual k", which does exactly the same thing as ^O k.
  3. Hit the Left arrow key twice, or ^O 2 h, to move the cursor back to the '.' character in "header.h".
  4. Hit 2 to insert a '2' before the '.' character. At this point, the line should look like ":e ~/proj1/src/header2.h".
  5. Hit Enter to submit the revised command line.

Or suppose you really wanted "footer2.h" instead of "header2.h". This is a little trickier because you want to delete characters in the middle of the command line, before inserting the correct text. The simplest way to do this is move the cursor to a point just after the last character that you want to delete, and then backspace over them. The steps are:

  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key or ^O k repeatedly to move back to the ":e ~/proj1/src/header2.h"command line.
  3. Hit the Left arrow key five times, or ^O 5 h, to move the cursor back to the last 'e' character in "header2.h".
  4. Hit the Backspace key four times to delete the word "head". It will still show on the screen, but elvis will know that it has been deleted. This is the same sort of behavior that elvis (and vi) exhibits when you backspace over newly entered text in input mode.
  5. Type f o o t to insert "foot" where "head" used to be. At this point, the line should look like ":e ~/proj1/src/footer2.h".
  6. Hit Enter to submit the revised command line.

4.1.2 The TAB key

The Tab key has a special function when you're inputing text into the "Elvis ex history" buffer. It is used for name completion. (Exception: Under MS-DOS, this feature is disabled in order to reduce the size of the program, so it will fit in the lower 640K.)

Name completion works like this: The preceding word is assumed to be a partial name for an ex command, an option, a tag, or a file. The type of name is determined by the context in which it appears -- commands appear at the start of an ex command line, and the others can only occur after certain, specific command names. Elvis searches for all matches of the appropriate type.

If there are multiple matches, then elvis fills in as many characters of the name as possible, and then stops; or, if no additional characters are implied by the matching names, then elvis lists all matching names and redisplays the command line. If there is a single match, then elvis completes the name and appends a tab character or some other appropriate character. If there are no matches, then elvis simply inserts a tab character.

Also, if while entering a :set command you hit the Tab key immediately after "option=" then elvis will insert the current value of the option. You can then edit that value before submitting the command line.

I tried to make elvis smart enough that the Tab key will only attempt file/command/option completion in contexts where it makes sense to do so, but that code might not be 100% correct. You can bypass the completion by typing a Control-V before the Tab key. You can also disable name completion altogether by setting the "Elvis ex history" buffer's inputtab option to "tab", via the following command:

	:(Elvis ex history)set inputtab=tab
or the abbreviated form:
	:("Eeh)se it=t

By default, elvis ignores binary files when performing filename completion. The completebinary option can be used to make elvis include binary files. That's a global option (unlike inputtab which is associated with a specific buffer), so you don't need to specify the buffer name; a simple :set completebinary will set it.

4.2 Syntax and Addressing

In general, ex command lines can begin with an optional window id. This may be followed by an optional buffer id, and then 0, 1, or 2 line addresses, followed by a command name, and perhaps some arguments after that (depending on the command name).

A window ID is typed in as a decimal number followed by a colon character. If you don't supply a window ID (and you almost never will) then it defaults to the window where you typed in the command line. The :buffer command lists the buffers, and shows which one is being edited in which window. Also, the windowid option indicates the ID of the current window.

A buffer ID is given by typing an opening parenthesis, the name of the buffer, and a closing parenthesis. For user buffers, the name of the buffer is usually identical to the name of the file that it corresponds to. For example, a file named ~/.Xdefaults would be loaded into a buffer which could be addressed as (~/.Xdefaults). Elvis also assigns numbers to user buffers, which may be more convenient to type since numbers are generally shorter than names. If ~/.Xdefaults is the first file you've edited since starting elvis, then its buffer could be addressed as (1). The :buffer command shows the number for each user buffer.

Elvis also has several internal buffers, all of which have names that start with "Elvis ", such as (Elvis cut buffer x) and (Elvis error list). The :buffer! command (with a ! suffix) will list them all. For the sake of brevity, elvis allows you to refer to cut buffers as ("x). Similarly, the other internal buffers can be referred to via a " character and the initial letter in each word of the full name, such as ("Eel) for (Elvis error list).

Commands which don't access the text, such as ":quit", don't allow any line addresses. Other commands, such as ":mark", only allow a single line address. Most commands, though, allow two line addresses; the command is applied to all lines between the two specified lines, inclusively. The tables below indicate how many line addresses each command allows.

Line addresses are always optional. The first line address of most commands usually defaults to the current line. The second line address usually defaults to be the same as the first line address. Exceptions are :write, :lpr, :global, and :vglobal, which act on all lines of the file by default, and :!, which acts on no lines by default.

If you use the visual V command to mark a range of lines, and then use the visual : command to execute a single ex command, then the default range affected by the ex command will be the visibly marked text.

Line addresses consist of an absolute part and a relative part. The absolute part of a line specifier may be either an explicit line number, a mark, a dot to denote the current line, a dollar sign to denote the last line of the file, or a forward or backward search. An explicit line number is simply a decimal number, expressed as a string of digits. A mark is typed in as an apostrophe followed by a letter. Marks must be set before they can be used. You can set a mark in visual command mode by typing "m" and a letter, or you can set it in ex command mode via the "mark" command. A forward search is typed in as a regular expression surrounded by slash characters; searching begins at the default line. A backward search is typed in as a regular expression surrounded by question marks; searching begins at the line before the default line.

If you omit the absolute part, then the default line is used.

The relative part of a line specifier is typed as a + or - character followed by a decimal number. The number is added to or subtracted from the absolute part of the line specifier to produce the final line number.

As a special case, the % character may be used to specify all lines of the file. It is roughly equivalent to saying 1,$. This can be a handy shortcut.

Here are some addressing examples, using the :p command:

   COMMAND      | ACTION
   -------------|-------------------------------------------
   :p           | print the current line
   :37p         | print line 37
   :'gp         | print the line which contains mark g
   :/foo/p      | print the next line that contains "foo"
   :$p          | print the last line of the buffer
   :20,30p      | print lines 20 through 30
   :1,$p        | print all lines of the buffer
   :%p          | print all lines of the buffer
   :(zot)%p     | print all lines of the "zot" buffer
   :/foo/-2,+4p | print 5 lines around the next "foo"

The optional addresses are followed by the command name. Command names may be abbreviated. In the sections that follow, the command's full name is given with the optional part enclosed in square brackets.

Some commands allow a '!' character to appear immediately after the command name. The significance of the '!' varies from one command to another, but typically it forces the command to do something dangerous that it would ordinarily refuse to do. For example, :w file refuses to overwrite an existing file, but :w! file will do it.

Many commands allow (or even require) additional arguments. The descriptions below list which arguments each command accepts with optional commands denoted by square brackets. The most common argument types are:

/regexp/
This is a regular expression. You can use any punctuation character to delimit it, but the '/' character is the most commonly used.
/regexp/newtext/
This is a regular expression followed by replacement text.
count
This is a number - a string of digits. Generally, it is used as the repeat count for certain commands.
cutbuf
This is the name of a cut buffer - a single letter. Elvis also allows (but does not require) a quote character before the letter.
excmds
This is another ex command, or list of ex commands. Traditionally, the whole list of commands had to appear on the same line, delimited by '|' characters. Elvis has the added versatility of allowing a '{' character on the first line, each command on a separate following line, and then '}' on a line by itself to mark the end of the ex command list.
lhs
This is string of characters. If whitespace characters are to be included in it, then they must be quoted by embedding a ^V character before them.
line
This is a line address, as described earlier.
+line
Some commands which cause a file to be loaded also allow you to specify some other command to be executed after the loading is complete. To use this feature, you mist give a "+" followed by the command, in between the command name and the file name. Here's an example that loads foo and then moves the cursor to line 40.
	:e +40 foo

Usually the command is just a line number, so this is denoted as "+line" in this documentation. Other commands are allowed though, such as "+/text" to search for text, or "+normal" to force it to use the normal display mode.

Traditionally, commands supplied in this manner weren't allowed to contain whitespace, because that makes parsing the command line harder. This is too limiting, though, so elvis allows you to embed spaces in the command by wrapping the entire deferred command in double-quotes, like this:

	:e +"set bufdisplay=man" filedb.8
mark
This is the name of a mark - a single lowercase letter. Elvis allows (but does not require) an apostrophe before the letter.
rhs
This is a string of characters. If it begins with a whitespace character, then that character must be quoted by embedding a ^V character in the command line before it. Other whitespace characters in the string do not need to be quoted.
expr
This is an arithmetic expression using the normal syntax.
shellcmd
This is a command line which is passed to the system's command interpreter. Within the command line, the following character substitutions take place, unless preceded by a backslash:
	.-----------.----------------------------.
	| CHARACTER | REPLACED BY                |
	|-----------|----------------------------|
	|     %     | Name of current file       |
	|     #     | Name of alternate file     |
	|     #n    | Name of file whose bufid=n |
	|     !     | Previous command line      |
	|     \@    | Word at cursor location    |
	^-----------^----------------------------^
Note that the \@ substitution requires a backslash. This quirk exists for the sake of backward compatibility - the real vi doesn't perform any substitutions for just plain @.
file or files
This is one or more file name, or a "wildcard" pattern which matches the names of zero or more files. File names are subjected to three levels of processing. First, leading ~ characters and certain other characters are replaced with text, as follows:
    .-----------.------------------------------------------------.
    | SYMBOL    | REPLACED BY                                    |
    |-----------|------------------------------------------------|
    | ~user     | (Unix only) Replaced by home directory of user |
    | ~+        | Replaced by current working directory          |
    | ~-        | Replaced by previous directory (previousdir)   |
    | ~         | Replaced by home directory (home)              |
    | %         | Replaced by the name of the current file       |
    | #         | Replaced by the name of the alternate file     |
    | #n        | Replaced by the filename of buffer with bufid=n|
    | (space)   | Delimits one file name from another            |
    | `program` | Run program, interpret its output as filenames |
    ^-----------^------------------------------------------------^
The second stage of processing evaluates each name using the simpler expression syntax. This basically means that expressions of the form $NAME will be replaced with the value of the environment variable named NAME. Also, you can use parentheses around option names or more complex expressions. For example, if the user option f contains the name of a file, then you could say ":e (f)" to edit that file.

In either of the fiand -mode command with the ?regexp visual command, to search for an earlier command line.

When you hit the Enter key on a line in the "Elvis ex history" buffer, elvis sends that line to the ex command parser, which is described in the next section.

4.1.1 An example

Suppose you enter the command...
	:e ~/proj1/src/header.h
...and then realize that you really wanted "header2.h" instead of "header.h". You simplest way to get "header2.h" is to...
  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key, or ^O k to move back to the preceding command line (which was ":e ~/proj1/src/header.h"). ^O k works because ^O reads and executes one vi command, and the k vi command moves the cursor back one line. The Up arrow key works because it is mapped to "visual k", which does exactly the same thing as ^O k.
  3. Hit the Left arrow key twice, or ^O 2 h, to move the cursor back to the '.' character in "header.h".
  4. Hit 2 to insert a '2' before the '.' character. At this point, the line should look like ":e ~/proj1/src/header2.h".
  5. Hit Enter to submit the revised command line.

Or suppose you really wanted "footer2.h" instead of "header2.h". This is a little trickier because you want to delete characters in the middle of the command line, before inserting the correct text. The simplest way to do this is move the cursor to a point just after the last character that you want to delete, and then backspace over them. The steps are:

  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key or ^O k repeatedly to move back to the ":e ~/proj1/src/header2.h"command line.
  3. Hit the Left arrow key five times, or ^O 5 h, to move the cursor back to the last 'e' character in "header2.h".
  4. Hit the Backspace key four times to delete the word "head". It will still show on the screen, but elvis will know that it has been deleted. This is the same sort of behavior that elvis (and vi) exhibits when you backspace over newly entered text in input mode.
  5. Type f o o t to insert "foot" where "head" used to be. At this point, the line should look like ":e ~/proj1/src/footer2.h".
  6. Hit Enter to submit the revised command line.

4.1.2 The TAB key

The Tab key has a special function when you're inputing text into the "Elvis ex history" buffer. It is used for name completion. (Exception: Under MS-DOS, this feature is disabled in order to reduce the size of the program, so it will fit in the lower 640K.)

Name completion works like this: The preceding word is assumed to be a partial name for an ex command, an option, a tag, or a file. The type of name is determined by the context in which it appears -- commands appear at the start of an ex command line, and the others can only occur after certain, specific command names. Elvis searches for all matches of the appropriate type.

If there are multiple matches, then elvis fills in as many characters of the name as possible, and then stops; or, if no additional characters are implied by the matching names, then elvis lists all matching names and redisplays the command line. If there is a single match, then elvis completes the name and appends a tab character or some other appropriate character. If there are no matches, then elvis simply inserts a tab character.

Also, if while entering a :set command you hit the Tab key immediately after "option=" then elvis will insert the current value of the option. You can then edit that value before submitting the command line.

I tried to make elvis smart enough that the Tab key will only attempt file/command/option completion in contexts where it makes sense to do so, but that code might not be 100% correct. You can bypass the completion by typing a Control-V before the Tab key. You can also disable name completion altogether by setting the "Elvis ex history" buffer's inputtab option to "tab", via the following command:

	:(Elvis ex history)set inputtab=tab
or the abbreviated form:
	:("Eeh)se it=t

By default, elvis ignores binary files when performing filename completion. The completebinary option can be used to make elvis include binary files. That's a global option (unlike inputtab which is associated with a specific buffer), so you don't need to specify the buffer name; a simple :set completebinary will set it.

4.2 Syntax and Addressing

In general, ex command lines can begin with an optional window id. This may be followed by an optional buffer id, and then 0, 1, or 2 line addresses, followed by a command name, and perhaps some arguments after that (depending on the command name).

A window ID is typed in as a decimal number followed by a colon character. If you don't supply a window ID (and you almost never will) then it defaults to the window where you typed in the command line. The :buffer command lists the buffers, and shows which one is being edited in which window. Also, the windowid option indicates the ID of the current window.

A buffer ID is given by typing an opening parenthesis, the name of the buffer, and a closing parenthesis. For user buffers, the name of the buffer is usually identical to the name of the file that it corresponds to. For example, a file named ~/.Xdefaults would be loaded into a buffer which could be addressed as (~/.Xdefaults). Elvis also assigns numbers to user buffers, which may be more convenient to type since numbers are generally shorter than names. If ~/.Xdefaults is the first file you've edited since starting elvis, then its buffer could be addressed as (1). The :buffer command shows the number for each user buffer.

Elvis also has several internal buffers, all of which have names that start with "Elvis ", such as (Elvis cut buffer x) and (Elvis error list). The :buffer! command (with a ! suffix) will list them all. For the sake of brevity, elvis allows you to refer to cut buffers as ("x). Similarly, the other internal buffers can be referred to via a " character and the initial letter in each word of the full name, such as ("Eel) for (Elvis error list).

Commands which don't access the text, such as ":quit", don't allow any line addresses. Other commands, such as ":mark", only allow a single line address. Most commands, though, allow two line addresses; the command is applied to all lines between the two specified lines, inclusively. The tables below indicate how many line addresses each command allows.

Line addresses are always optional. The first line address of most commands usually defaults to the current line. The second line address usually defaults to be the same as the first line address. Exceptions are :write, :lpr, :global, and :vglobal, which act on all lines of the file by default, and :!, which acts on no lines by default.

If you use the visual V command to mark a range of lines, and then use the visual : command to execute a single ex command, then the default range affected by the ex command will be the visibly marked text.

Line addresses consist of an absolute part and a relative part. The absolute part of a line specifier may be either an explicit line number, a mark, a dot to denote the current line, a dollar sign to denote the last line of the file, or a forward or backward search. An explicit line number is simply a decimal number, expressed as a string of digits. A mark is typed in as an apostrophe followed by a letter. Marks must be set before they can be used. You can set a mark in visual command mode by typing "m" and a letter, or you can set it in ex command mode via the "mark" command. A forward search is typed in as a regular expression surrounded by slash characters; searching begins at the default line. A backward search is typed in as a regular expression surrounded by question marks; searching begins at the line before the default line.

If you omit the absolute part, then the default line is used.

The relative part of a line specifier is typed as a + or - character followed by a decimal number. The number is added to or subtracted from the absolute part of the line specifier to produce the final line number.

As a special case, the % character may be used to specify all lines of the file. It is roughly equivalent to saying 1,$. This can be a handy shortcut.

Here are some addressing examples, using the :p command:

   COMMAND      | ACTION
   -------------|-------------------------------------------
   :p           | print the current line
   :37p         | print line 37
   :'gp         | print the line which contains mark g
   :/foo/p      | print the next line that contains "foo"
   :$p          | print the last line of the buffer
   :20,30p      | print lines 20 through 30
   :1,$p        | print all lines of the buffer
   :%p          | print all lines of the buffer
   :(zot)%p     | print all lines of the "zot" buffer
   :/foo/-2,+4p | print 5 lines around the next "foo"

The optional addresses are followed by the command name. Command names may be abbreviated. In the sections that follow, the command's full name is given with the optional part enclosed in square brackets.

Some commands allow a '!' character to appear immediately after the command name. The significance of the '!' varies from one command to another, but typically it forces the command to do something dangerous that it would ordinarily refuse to do. For example, :w file refuses to overwrite an existing file, but :w! file will do it.

Many commands allow (or even require) additional arguments. The descriptions below list which arguments each command accepts with optional commands denoted by square brackets. The most common argument types are:

/regexp/
This is a regular expression. You can use any punctuation character to delimit it, but the '/' character is the most commonly used.
/regexp/newtext/
This is a regular expression followed by replacement text.
count
This is a number - a string of digits. Generally, it is used as the repeat count for certain commands.
cutbuf
This is the name of a cut buffer - a single letter. Elvis also allows (but does not require) a quote character before the letter.
excmds
This is another ex command, or list of ex commands. Traditionally, the whole list of commands had to appear on the same line, delimited by '|' characters. Elvis has the added versatility of allowing a '{' character on the first line, each command on a separate following line, and then '}' on a line by itself to mark the end of the ex command list.
lhs
This is string of characters. If whitespace characters are to be included in it, then they must be quoted by embedding a ^V character before them.
line
This is a line address, as described earlier.
+line
Some commands which cause a file to be loaded also allow you to specify some other command to be executed after the loading is complete. To use this feature, you mist give a "+" followed by the command, in between the command name and the file name. Here's an example that loads foo and then moves the cursor to line 40.
	:e +40 foo

Usually the command is just a line number, so this is denoted as "+line" in this documentation. Other commands are allowed though, such as "+/text" to search for text, or "+normal" to force it to use the normal display mode.

Traditionally, commands supplied in this manner weren't allowed to contain whitespace, because that makes parsing the command line harder. This is too limiting, though, so elvis allows you to embed spaces in the command by wrapping the entire deferred command in double-quotes, like this:

	:e +"set bufdisplay=man" filedb.8
mark
This is the name of a mark - a single lowercase letter. Elvis allows (but does not require) an apostrophe before the letter.
rhs
This is a string of characters. If it begins with a whitespace character, then that character must be quoted by embedding a ^V character in the command line before it. Other whitespace characters in the string do not need to be quoted.
expr
This is an arithmetic expression using the normal syntax.
shellcmd
This is a command line which is passed to the system's command interpreter. Within the command line, the following character substitutions take place, unless preceded by a backslash:
	.-----------.----------------------------.
	| CHARACTER | REPLACED BY                |
	|-----------|----------------------------|
	|     %     | Name of current file       |
	|     #     | Name of alternate file     |
	|     #n    | Name of file whose bufid=n |
	|     !     | Previous command line      |
	|     \@    | Word at cursor location    |
	^-----------^----------------------------^
Note that the \@ substitution requires a backslash. This quirk exists for the sake of backward compatibility - the real vi doesn't perform any substitutions for just plain @.
file or files
This is one or more file name, or a "wildcard" pattern which matches the names of zero or more files. File names are subjected to three levels of processing. First, leading ~ characters and certain other characters are replaced with text, as follows:
    .-----------.------------------------------------------------.
    | SYMBOL    | REPLACED BY                                    |
    |-----------|------------------------------------------------|
    | ~user     | (Unix only) Replaced by home directory of user |
    | ~+        | Replaced by current working directory          |
    | ~-        | Replaced by previous directory (previousdir)   |
    | ~         | Replaced by home directory (home)              |
    | %         | Replaced by the name of the current file       |
    | #         | Replaced by the name of the alternate file     |
    | #n        | Replaced by the filename of buffer with bufid=n|
    | (space)   | Delimits one file name from another            |
    | `program` | Run program, interpret its output as filenames |
    ^-----------^------------------------------------------------^
The second stage of processing evaluates each name using the simpler expression syntax. This basically means that expressions of the form $NAME will be replaced with the value of the environment variable named NAME. Also, you can use parentheses around option names or more complex expressions. For example, if the user option f contains the name of a file, then you could say ":e (f)" to edit that file.

In either of the fiand -mode command with the ?regexp visual command, to search for an earlier command line.

When you hit the Enter key on a line in the "Elvis ex history" buffer, elvis sends that line to the ex command parser, which is described in the next section.

4.1.1 An example

Suppose you enter the command...
	:e ~/proj1/src/header.h
...and then realize that you really wanted "header2.h" instead of "header.h". You simplest way to get "header2.h" is to...
  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key, or ^O k to move back to the preceding command line (which was ":e ~/proj1/src/header.h"). ^O k works because ^O reads and executes one vi command, and the k vi command moves the cursor back one line. The Up arrow key works because it is mapped to "visual k", which does exactly the same thing as ^O k.
  3. Hit the Left arrow key twice, or ^O 2 h, to move the cursor back to the '.' character in "header.h".
  4. Hit 2 to insert a '2' before the '.' character. At this point, the line should look like ":e ~/proj1/src/header2.h".
  5. Hit Enter to submit the revised command line.

Or suppose you really wanted "footer2.h" instead of "header2.h". This is a little trickier because you want to delete characters in the middle of the command line, before inserting the correct text. The simplest way to do this is move the cursor to a point just after the last character that you want to delete, and then backspace over them. The steps are:

  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key or ^O k repeatedly to move back to the ":e ~/proj1/src/header2.h"command line.
  3. Hit the Left arrow key five times, or ^O 5 h, to move the cursor back to the last 'e' character in "header2.h".
  4. Hit the Backspace key four times to delete the word "head". It will still show on the screen, but elvis will know that it has been deleted. This is the same sort of behavior that elvis (and vi) exhibits when you backspace over newly entered text in input mode.
  5. Type f o o t to insert "foot" where "head" used to be. At this point, the line should look like ":e ~/proj1/src/footer2.h".
  6. Hit Enter to submit the revised command line.

4.1.2 The TAB key

The Tab key has a special function when you're inputing text into the "Elvis ex history" buffer. It is used for name completion. (Exception: Under MS-DOS, this feature is disabled in order to reduce the size of the program, so it will fit in the lower 640K.)

Name completion works like this: The preceding word is assumed to be a partial name for an ex command, an option, a tag, or a file. The type of name is determined by the context in which it appears -- commands appear at the start of an ex command line, and the others can only occur after certain, specific command names. Elvis searches for all matches of the appropriate type.

If there are multiple matches, then elvis fills in as many characters of the name as possible, and then stops; or, if no additional characters are implied by the matching names, then elvis lists all matching names and redisplays the command line. If there is a single match, then elvis completes the name and appends a tab character or some other appropriate character. If there are no matches, then elvis simply inserts a tab character.

Also, if while entering a :set command you hit the Tab key immediately after "option=" then elvis will insert the current value of the option. You can then edit that value before submitting the command line.

I tried to make elvis smart enough that the Tab key will only attempt file/command/option completion in contexts where it makes sense to do so, but that code might not be 100% correct. You can bypass the completion by typing a Control-V before the Tab key. You can also disable name completion altogether by setting the "Elvis ex history" buffer's inputtab option to "tab", via the following command:

	:(Elvis ex history)set inputtab=tab
or the abbreviated form:
	:("Eeh)se it=t

By default, elvis ignores binary files when performing filename completion. The completebinary option can be used to make elvis include binary files. That's a global option (unlike inputtab which is associated with a specific buffer), so you don't need to specify the buffer name; a simple :set completebinary will set it.

4.2 Syntax and Addressing

In general, ex command lines can begin with an optional window id. This may be followed by an optional buffer id, and then 0, 1, or 2 line addresses, followed by a command name, and perhaps some arguments after that (depending on the command name).

A window ID is typed in as a decimal number followed by a colon character. If you don't supply a window ID (and you almost never will) then it defaults to the window where you typed in the command line. The :buffer command lists the buffers, and shows which one is being edited in which window. Also, the windowid option indicates the ID of the current window.

A buffer ID is given by typing an opening parenthesis, the name of the buffer, and a closing parenthesis. For user buffers, the name of the buffer is usually identical to the name of the file that it corresponds to. For example, a file named ~/.Xdefaults would be loaded into a buffer which could be addressed as (~/.Xdefaults). Elvis also assigns numbers to user buffers, which may be more convenient to type since numbers are generally shorter than names. If ~/.Xdefaults is the first file you've edited since starting elvis, then its buffer could be addressed as (1). The :buffer command shows the number for each user buffer.

Elvis also has several internal buffers, all of which have names that start with "Elvis ", such as (Elvis cut buffer x) and (Elvis error list). The :buffer! command (with a ! suffix) will list them all. For the sake of brevity, elvis allows you to refer to cut buffers as ("x). Similarly, the other internal buffers can be referred to via a " character and the initial letter in each word of the full name, such as ("Eel) for (Elvis error list).

Commands which don't access the text, such as ":quit", don't allow any line addresses. Other commands, such as ":mark", only allow a single line address. Most commands, though, allow two line addresses; the command is applied to all lines between the two specified lines, inclusively. The tables below indicate how many line addresses each command allows.

Line addresses are always optional. The first line address of most commands usually defaults to the current line. The second line address usually defaults to be the same as the first line address. Exceptions are :write, :lpr, :global, and :vglobal, which act on all lines of the file by default, and :!, which acts on no lines by default.

If you use the visual V command to mark a range of lines, and then use the visual : command to execute a single ex command, then the default range affected by the ex command will be the visibly marked text.

Line addresses consist of an absolute part and a relative part. The absolute part of a line specifier may be either an explicit line number, a mark, a dot to denote the current line, a dollar sign to denote the last line of the file, or a forward or backward search. An explicit line number is simply a decimal number, expressed as a string of digits. A mark is typed in as an apostrophe followed by a letter. Marks must be set before they can be used. You can set a mark in visual command mode by typing "m" and a letter, or you can set it in ex command mode via the "mark" command. A forward search is typed in as a regular expression surrounded by slash characters; searching begins at the default line. A backward search is typed in as a regular expression surrounded by question marks; searching begins at the line before the default line.

If you omit the absolute part, then the default line is used.

The relative part of a line specifier is typed as a + or - character followed by a decimal number. The number is added to or subtracted from the absolute part of the line specifier to produce the final line number.

As a special case, the % character may be used to specify all lines of the file. It is roughly equivalent to saying 1,$. This can be a handy shortcut.

Here are some addressing examples, using the :p command:

   COMMAND      | ACTION
   -------------|-------------------------------------------
   :p           | print the current line
   :37p         | print line 37
   :'gp         | print the line which contains mark g
   :/foo/p      | print the next line that contains "foo"
   :$p          | print the last line of the buffer
   :20,30p      | print lines 20 through 30
   :1,$p        | print all lines of the buffer
   :%p          | print all lines of the buffer
   :(zot)%p     | print all lines of the "zot" buffer
   :/foo/-2,+4p | print 5 lines around the next "foo"

The optional addresses are followed by the command name. Command names may be abbreviated. In the sections that follow, the command's full name is given with the optional part enclosed in square brackets.

Some commands allow a '!' character to appear immediately after the command name. The significance of the '!' varies from one command to another, but typically it forces the command to do something dangerous that it would ordinarily refuse to do. For example, :w file refuses to overwrite an existing file, but :w! file will do it.

Many commands allow (or even require) additional arguments. The descriptions below list which arguments each command accepts with optional commands denoted by square brackets. The most common argument types are:

/regexp/
This is a regular expression. You can use any punctuation character to delimit it, but the '/' character is the most commonly used.
/regexp/newtext/
This is a regular expression followed by replacement text.
count
This is a number - a string of digits. Generally, it is used as the repeat count for certain commands.
cutbuf
This is the name of a cut buffer - a single letter. Elvis also allows (but does not require) a quote character before the letter.
excmds
This is another ex command, or list of ex commands. Traditionally, the whole list of commands had to appear on the same line, delimited by '|' characters. Elvis has the added versatility of allowing a '{' character on the first line, each command on a separate following line, and then '}' on a line by itself to mark the end of the ex command list.
lhs
This is string of characters. If whitespace characters are to be included in it, then they must be quoted by embedding a ^V character before them.
line
This is a line address, as described earlier.
+line
Some commands which cause a file to be loaded also allow you to specify some other command to be executed after the loading is complete. To use this feature, you mist give a "+" followed by the command, in between the command name and the file name. Here's an example that loads foo and then moves the cursor to line 40.
	:e +40 foo

Usually the command is just a line number, so this is denoted as "+line" in this documentation. Other commands are allowed though, such as "+/text" to search for text, or "+normal" to force it to use the normal display mode.

Traditionally, commands supplied in this manner weren't allowed to contain whitespace, because that makes parsing the command line harder. This is too limiting, though, so elvis allows you to embed spaces in the command by wrapping the entire deferred command in double-quotes, like this:

	:e +"set bufdisplay=man" filedb.8
mark
This is the name of a mark - a single lowercase letter. Elvis allows (but does not require) an apostrophe before the letter.
rhs
This is a string of characters. If it begins with a whitespace character, then that character must be quoted by embedding a ^V character in the command line before it. Other whitespace characters in the string do not need to be quoted.
expr
This is an arithmetic expression using the normal syntax.
shellcmd
This is a command line which is passed to the system's command interpreter. Within the command line, the following character substitutions take place, unless preceded by a backslash:
	.-----------.----------------------------.
	| CHARACTER | REPLACED BY                |
	|-----------|----------------------------|
	|     %     | Name of current file       |
	|     #     | Name of alternate file     |
	|     #n    | Name of file whose bufid=n |
	|     !     | Previous command line      |
	|     \@    | Word at cursor location    |
	^-----------^----------------------------^
Note that the \@ substitution requires a backslash. This quirk exists for the sake of backward compatibility - the real vi doesn't perform any substitutions for just plain @.
file or files
This is one or more file name, or a "wildcard" pattern which matches the names of zero or more files. File names are subjected to three levels of processing. First, leading ~ characters and certain other characters are replaced with text, as follows:
    .-----------.------------------------------------------------.
    | SYMBOL    | REPLACED BY                                    |
    |-----------|------------------------------------------------|
    | ~user     | (Unix only) Replaced by home directory of user |
    | ~+        | Replaced by current working directory          |
    | ~-        | Replaced by previous directory (previousdir)   |
    | ~         | Replaced by home directory (home)              |
    | %         | Replaced by the name of the current file       |
    | #         | Replaced by the name of the alternate file     |
    | #n        | Replaced by the filename of buffer with bufid=n|
    | (space)   | Delimits one file name from another            |
    | `program` | Run program, interpret its output as filenames |
    ^-----------^------------------------------------------------^
The second stage of processing evaluates each name using the simpler expression syntax. This basically means that expressions of the form $NAME will be replaced with the value of the environment variable named NAME. Also, you can use parentheses around option names or more complex expressions. For example, if the user option f contains the name of a file, then you could say ":e (f)" to edit that file.

In either of the fiand -mode command with the ?regexp visual command, to search for an earlier command line.

When you hit the Enter key on a line in the "Elvis ex history" buffer, elvis sends that line to the ex command parser, which is described in the next section.

4.1.1 An example

Suppose you enter the command...
	:e ~/proj1/src/header.h
...and then realize that you really wanted "header2.h" instead of "header.h". You simplest way to get "header2.h" is to...
  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key, or ^O k to move back to the preceding command line (which was ":e ~/proj1/src/header.h"). ^O k works because ^O reads and executes one vi command, and the k vi command moves the cursor back one line. The Up arrow key works because it is mapped to "visual k", which does exactly the same thing as ^O k.
  3. Hit the Left arrow key twice, or ^O 2 h, to move the cursor back to the '.' character in "header.h".
  4. Hit 2 to insert a '2' before the '.' character. At this point, the line should look like ":e ~/proj1/src/header2.h".
  5. Hit Enter to submit the revised command line.

Or suppose you really wanted "footer2.h" instead of "header2.h". This is a little trickier because you want to delete characters in the middle of the command line, before inserting the correct text. The simplest way to do this is move the cursor to a point just after the last character that you want to delete, and then backspace over them. The steps are:

  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key or ^O k repeatedly to move back to the ":e ~/proj1/src/header2.h"command line.
  3. Hit the Left arrow key five times, or ^O 5 h, to move the cursor back to the last 'e' character in "header2.h".
  4. Hit the Backspace key four times to delete the word "head". It will still show on the screen, but elvis will know that it has been deleted. This is the same sort of behavior that elvis (and vi) exhibits when you backspace over newly entered text in input mode.
  5. Type f o o t to insert "foot" where "head" used to be. At this point, the line should look like ":e ~/proj1/src/footer2.h".
  6. Hit Enter to submit the revised command line.

4.1.2 The TAB key

The Tab key has a special function when you're inputing text into the "Elvis ex history" buffer. It is used for name completion. (Exception: Under MS-DOS, this feature is disabled in order to reduce the size of the program, so it will fit in the lower 640K.)

Name completion works like this: The preceding word is assumed to be a partial name for an ex command, an option, a tag, or a file. The type of name is determined by the context in which it appears -- commands appear at the start of an ex command line, and the others can only occur after certain, specific command names. Elvis searches for all matches of the appropriate type.

If there are multiple matches, then elvis fills in as many characters of the name as possible, and then stops; or, if no additional characters are implied by the matching names, then elvis lists all matching names and redisplays the command line. If there is a single match, then elvis completes the name and appends a tab character or some other appropriate character. If there are no matches, then elvis simply inserts a tab character.

Also, if while entering a :set command you hit the Tab key immediately after "option=" then elvis will insert the current value of the option. You can then edit that value before submitting the command line.

I tried to make elvis smart enough that the Tab key will only attempt file/command/option completion in contexts where it makes sense to do so, but that code might not be 100% correct. You can bypass the completion by typing a Control-V before the Tab key. You can also disable name completion altogether by setting the "Elvis ex history" buffer's inputtab option to "tab", via the following command:

	:(Elvis ex history)set inputtab=tab
or the abbreviated form:
	:("Eeh)se it=t

By default, elvis ignores binary files when performing filename completion. The completebinary option can be used to make elvis include binary files. That's a global option (unlike inputtab which is associated with a specific buffer), so you don't need to specify the buffer name; a simple :set completebinary will set it.

4.2 Syntax and Addressing

In general, ex command lines can begin with an optional window id. This may be followed by an optional buffer id, and then 0, 1, or 2 line addresses, followed by a command name, and perhaps some arguments after that (depending on the command name).

A window ID is typed in as a decimal number followed by a colon character. If you don't supply a window ID (and you almost never will) then it defaults to the window where you typed in the command line. The :buffer command lists the buffers, and shows which one is being edited in which window. Also, the windowid option indicates the ID of the current window.

A buffer ID is given by typing an opening parenthesis, the name of the buffer, and a closing parenthesis. For user buffers, the name of the buffer is usually identical to the name of the file that it corresponds to. For example, a file named ~/.Xdefaults would be loaded into a buffer which could be addressed as (~/.Xdefaults). Elvis also assigns numbers to user buffers, which may be more convenient to type since numbers are generally shorter than names. If ~/.Xdefaults is the first file you've edited since starting elvis, then its buffer could be addressed as (1). The :buffer command shows the number for each user buffer.

Elvis also has several internal buffers, all of which have names that start with "Elvis ", such as (Elvis cut buffer x) and (Elvis error list). The :buffer! command (with a ! suffix) will list them all. For the sake of brevity, elvis allows you to refer to cut buffers as ("x). Similarly, the other internal buffers can be referred to via a " character and the initial letter in each word of the full name, such as ("Eel) for (Elvis error list).

Commands which don't access the text, such as ":quit", don't allow any line addresses. Other commands, such as ":mark", only allow a single line address. Most commands, though, allow two line addresses; the command is applied to all lines between the two specified lines, inclusively. The tables below indicate how many line addresses each command allows.

Line addresses are always optional. The first line address of most commands usually defaults to the current line. The second line address usually defaults to be the same as the first line address. Exceptions are :write, :lpr, :global, and :vglobal, which act on all lines of the file by default, and :!, which acts on no lines by default.

If you use the visual V command to mark a range of lines, and then use the visual : command to execute a single ex command, then the default range affected by the ex command will be the visibly marked text.

Line addresses consist of an absolute part and a relative part. The absolute part of a line specifier may be either an explicit line number, a mark, a dot to denote the current line, a dollar sign to denote the last line of the file, or a forward or backward search. An explicit line number is simply a decimal number, expressed as a string of digits. A mark is typed in as an apostrophe followed by a letter. Marks must be set before they can be used. You can set a mark in visual command mode by typing "m" and a letter, or you can set it in ex command mode via the "mark" command. A forward search is typed in as a regular expression surrounded by slash characters; searching begins at the default line. A backward search is typed in as a regular expression surrounded by question marks; searching begins at the line before the default line.

If you omit the absolute part, then the default line is used.

The relative part of a line specifier is typed as a + or - character followed by a decimal number. The number is added to or subtracted from the absolute part of the line specifier to produce the final line number.

As a special case, the % character may be used to specify all lines of the file. It is roughly equivalent to saying 1,$. This can be a handy shortcut.

Here are some addressing examples, using the :p command:

   COMMAND      | ACTION
   -------------|-------------------------------------------
   :p           | print the current line
   :37p         | print line 37
   :'gp         | print the line which contains mark g
   :/foo/p      | print the next line that contains "foo"
   :$p          | print the last line of the buffer
   :20,30p      | print lines 20 through 30
   :1,$p        | print all lines of the buffer
   :%p          | print all lines of the buffer
   :(zot)%p     | print all lines of the "zot" buffer
   :/foo/-2,+4p | print 5 lines around the next "foo"

The optional addresses are followed by the command name. Command names may be abbreviated. In the sections that follow, the command's full name is given with the optional part enclosed in square brackets.

Some commands allow a '!' character to appear immediately after the command name. The significance of the '!' varies from one command to another, but typically it forces the command to do something dangerous that it would ordinarily refuse to do. For example, :w file refuses to overwrite an existing file, but :w! file will do it.

Many commands allow (or even require) additional arguments. The descriptions below list which arguments each command accepts with optional commands denoted by square brackets. The most common argument types are:

/regexp/
This is a regular expression. You can use any punctuation character to delimit it, but the '/' character is the most commonly used.
/regexp/newtext/
This is a regular expression followed by replacement text.
count
This is a number - a string of digits. Generally, it is used as the repeat count for certain commands.
cutbuf
This is the name of a cut buffer - a single letter. Elvis also allows (but does not require) a quote character before the letter.
excmds
This is another ex command, or list of ex commands. Traditionally, the whole list of commands had to appear on the same line, delimited by '|' characters. Elvis has the added versatility of allowing a '{' character on the first line, each command on a separate following line, and then '}' on a line by itself to mark the end of the ex command list.
lhs
This is string of characters. If whitespace characters are to be included in it, then they must be quoted by embedding a ^V character before them.
line
This is a line address, as described earlier.
+line
Some commands which cause a file to be loaded also allow you to specify some other command to be executed after the loading is complete. To use this feature, you mist give a "+" followed by the command, in between the command name and the file name. Here's an example that loads foo and then moves the cursor to line 40.
	:e +40 foo

Usually the command is just a line number, so this is denoted as "+line" in this documentation. Other commands are allowed though, such as "+/text" to search for text, or "+normal" to force it to use the normal display mode.

Traditionally, commands supplied in this manner weren't allowed to contain whitespace, because that makes parsing the command line harder. This is too limiting, though, so elvis allows you to embed spaces in the command by wrapping the entire deferred command in double-quotes, like this:

	:e +"set bufdisplay=man" filedb.8
mark
This is the name of a mark - a single lowercase letter. Elvis allows (but does not require) an apostrophe before the letter.
rhs
This is a string of characters. If it begins with a whitespace character, then that character must be quoted by embedding a ^V character in the command line before it. Other whitespace characters in the string do not need to be quoted.
expr
This is an arithmetic expression using the normal syntax.
shellcmd
This is a command line which is passed to the system's command interpreter. Within the command line, the following character substitutions take place, unless preceded by a backslash:
	.-----------.----------------------------.
	| CHARACTER | REPLACED BY                |
	|-----------|----------------------------|
	|     %     | Name of current file       |
	|     #     | Name of alternate file     |
	|     #n    | Name of file whose bufid=n |
	|     !     | Previous command line      |
	|     \@    | Word at cursor location    |
	^-----------^----------------------------^
Note that the \@ substitution requires a backslash. This quirk exists for the sake of backward compatibility - the real vi doesn't perform any substitutions for just plain @.
file or files
This is one or more file name, or a "wildcard" pattern which matches the names of zero or more files. File names are subjected to three levels of processing. First, leading ~ characters and certain other characters are replaced with text, as follows:
    .-----------.------------------------------------------------.
    | SYMBOL    | REPLACED BY                                    |
    |-----------|------------------------------------------------|
    | ~user     | (Unix only) Replaced by home directory of user |
    | ~+        | Replaced by current working directory          |
    | ~-        | Replaced by previous directory (previousdir)   |
    | ~         | Replaced by home directory (home)              |
    | %         | Replaced by the name of the current file       |
    | #         | Replaced by the name of the alternate file     |
    | #n        | Replaced by the filename of buffer with bufid=n|
    | (space)   | Delimits one file name from another            |
    | `program` | Run program, interpret its output as filenames |
    ^-----------^------------------------------------------------^
The second stage of processing evaluates each name using the simpler expression syntax. This basically means that expressions of the form $NAME will be replaced with the value of the environment variable named NAME. Also, you can use parentheses around option names or more complex expressions. For example, if the user option f contains the name of a file, then you could say ":e (f)" to edit that file.

In either of the fiand -mode command with the ?regexp visual command, to search for an earlier command line.

When you hit the Enter key on a line in the "Elvis ex history" buffer, elvis sends that line to the ex command parser, which is described in the next section.

4.1.1 An example

Suppose you enter the command...
	:e ~/proj1/src/header.h
...and then realize that you really wanted "header2.h" instead of "header.h". You simplest way to get "header2.h" is to...
  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key, or ^O k to move back to the preceding command line (which was ":e ~/proj1/src/header.h"). ^O k works because ^O reads and executes one vi command, and the k vi command moves the cursor back one line. The Up arrow key works because it is mapped to "visual k", which does exactly the same thing as ^O k.
  3. Hit the Left arrow key twice, or ^O 2 h, to move the cursor back to the '.' character in "header.h".
  4. Hit 2 to insert a '2' before the '.' character. At this point, the line should look like ":e ~/proj1/src/header2.h".
  5. Hit Enter to submit the revised command line.

Or suppose you really wanted "footer2.h" instead of "header2.h". This is a little trickier because you want to delete characters in the middle of the command line, before inserting the correct text. The simplest way to do this is move the cursor to a point just after the last character that you want to delete, and then backspace over them. The steps are:

  1. Hit the : key to start a new ex command line.
  2. Hit the Up arrow key or ^O k repeatedly to move back to the ":e ~/proj1/src/header2.h"command line.
  3. Hit the Left arrow key five times, or ^O 5 h, to move the cursor back to the last 'e' character in "header2.h".
  4. Hit the Backspace key four times to delete the word "head". It will still show on the screen, but elvis will know that it has been deleted. This is the same sort of behavior that elvis (and vi) exhibits when you backspace over newly entered text in input mode.
  5. Type f o o t to insert "foot" where "head" used to be. At this point, the line should look like ":e ~/proj1/src/footer2.h".
  6. Hit Enter to submit the revised command line.

4.1.2 The TAB key

The Tab key has a special function when you're inputing text into the "Elvis ex history" buffer. It is used for name completion. (Exception: Under MS-DOS, this feature is disabled in order to reduce the size of the program, so it will fit in the lower 640K.)

Name completion works like this: The preceding word is assumed to be a partial name for an ex command, an option, a tag, or a file. The type of name is determined by the context in which it appears -- commands appear at the start of an ex command line, and the others can only occur after certain, specific command names. Elvis searches for all matches of the appropriate type.

If there are multiple matches, then elvis fills in as many characters of the name as possible, and then stops; or, if no additional characters are implied by the matching names, then elvis lists all matching names and redisplays the command line. If there is a single match, then elvis completes the name and appends a tab character or some other appropriate character. If there are no matches, then elvis simply inserts a tab character.

Also, if while entering a :set command you hit the Tab key immediately after "option=" then elvis will insert the current value of the option. You can then edit that value before submitting the command line.

I tried to make elvis smart enough that the Tab key will only attempt file/command/option completion in contexts where it makes sense to do so, but that code might not be 100% correct. You can bypass the completion by typing a Control-V before the Tab key. You can also disable name completion altogether by setting the "Elvis ex history" buffer's inputtab option to "tab", via the following command:

	:(Elvis ex history)set inputtab=tab
or the abbreviated form:
	:("Eeh)se it=t

By default, elvis ignores binary files when performing filename completion. The completebinary option can be used to make elvis include binary files. That's a global option (unlike inputtab which is associated with a specific buffer), so you don't need to specify the buffer name; a simple :set completebinary will set it.

4.2 Syntax and Addressing

In general, ex command lines can begin with an optional window id. This may be followed by an optional buffer id, and then 0, 1, or 2 line addresses, followed by a command name, and perhaps some arguments after that (depending on the command name).

A window ID is typed in as a decimal number followed by a colon character. If you don't supply a window ID (and you almost never will) then it defaults to the window where you typed in the command line. The :buffer command lists the buffers, and shows which one is being edited in which window. Also, the windowid option indicates the ID of the current window.

A buffer ID is given by typing an opening parenthesis, the name of the buffer, and a closing parenthesis. For user buffers, the name of the buffer is usually identical to the name of the file that it corresponds to. For example, a file named ~/.Xdefaults would be loaded into a buffer which could be addressed as (~/.Xdefaults). Elvis also assigns numbers to user buffers, which may be more convenient to type since numbers are generally shorter than names. If ~/.Xdefaults is the first file you've edited since starting elvis, then its buffer could be addressed as (1). The :buffer command shows the number for each user buffer.

Elvis also has several internal buffers, all of which have names that start with "Elvis ", such as (Elvis cut buffer x) and (Elvis error list). The :buffer! command (with a ! suffix) will list them all. For the sake of brevity, elvis allows you to refer to cut buffers as ("x). Similarly, the other internal buffers can be referred to via a " character and the initial letter in each word of the full name, such as ("Eel) for (Elvis error list).

Commands which don't access the text, such as ":quit", don't allow any line addresses. Other commands, such as ":mark", only allow a single line address. Most commands, though, allow two line addresses; the command is applied to all lines between the two specified lines, inclusively. The tables below indicate how many line addresses each command allows.

Line addresses are always optional. The first line address of most commands usually defaults to the current line. The second line address usually defaults to be the same as the first line address. Exceptions are :write, :lpr, :global, and :vglobal, which act on all lines of the file by default, and :!, which acts on no lines by default.

If you use the visual V command to mark a range of lines, and then use the visual : command to execute a single ex command, then the default range affected by the ex command will be the visibly marked text.

Line addresses consist of an absolute part and a relative part. The absolute part of a line specifier may be either an explicit line number, a mark, a dot to denote the current line, a dollar sign to denote the last line of the file, or a forward or backward search. An explicit line number is simply a decimal number, expressed as a string of digits. A mark is typed in as an apostrophe followed by a letter. Marks must be set before they can be used. You can set a mark in visual command mode by typing "m" and a letter, or you can set it in ex command mode via the "mark" command. A forward search is typed in as a regular expression surrounded by slash characters; searching begins at the default line. A backward search is typed in as a regular expression surrounded by question marks; searching begins at the line before the default line.

If you omit the absolute part, then the default line is used.

The relative part of a line specifier is typed as a + or - character followed by a decimal number. The number is added to or subtracted from the absolute part of the line specifier to produce the final line number.

As a special case, the % character may be used to specify all lines of the file. It is roughly equivalent to saying 1,$. This can be a handy shortcut.

Here are some addressing examples, using the :p command:

   COMMAND      | ACTION
   -------------|-------------------------------------------
   :p           | print the current line
   :37p         | print line 37
   :'gp         | print the line which contains mark g
   :/foo/p      | print the next line that contains "foo"
   :$p          | print the last line of the buffer
   :20,30p      | print lines 20 through 30
   :1,$p        | print all lines of the buffer
   :%p          | print all lines of the buffer
   :(zot)%p     | print all lines of the "zot" buffer
   :/foo/-2,+4p | print 5 lines around the next "foo"

The optional addresses are followed by the command name. Command names may be abbreviated. In the sections that follow, the command's full name is given with the optional part enclosed in square brackets.

Some commands allow a '!' character to appear immediately after the command name. The significance of the '!' varies from one command to another, but typically it forces the command to do something dangerous that it would ordinarily refuse to do. For example, :w file refuses to overwrite an existing file, but :w! file will do it.

Many commands allow (or even require) additional arguments. The descriptions below list which arguments each command accepts with optional commands denoted by square brackets. The most common argument types are:

/regexp/
This is a regular expression. You can use any punctuation character to delimit it, but the '/' character is the most commonly used.
/regexp/newtext/
This is a regular expression followed by replacement text.
count
This is a number - a string of digits. Generally, it is used as the repeat count for certain commands.
cutbuf
This is the name of a cut buffer - a single letter. Elvis also allows (but does not require) a quote character before the letter.
excmds
This is another ex command, or list of ex commands. Traditionally, the whole list of commands had to appear on the same line, delimited by '|' characters. Elvis has the added versatility of allowing a '{' character on the first line, each command on a separate following line, and then '}' on a line by itself to mark the end of the ex command list.
lhs
This is string of characters. If whitespace characters are to be included in it, then they must be quoted by embedding a ^V character before them.
line
This is a line address, as described earlier.
+line
Some commands which cause a file to be loaded also allow you to specify some other command to be executed after the loading is complete. To use this feature, you mist give a "+" followed by the command, in between the command name and the file name. Here's an example that loads foo and then moves the cursor to line 40.
	:e +40 foo

Usually the command is just a line number, so this is denoted as "+line" in this documentation. Other commands are allowed though, such as "+/text" to search for text, or "+normal" to force it to use the normal display mode.

Traditionally, commands supplied in this manner weren't allowed to contain whitespace, because that makes parsing the command line harder. This is too limiting, though, so elvis allows you to embed spaces in the command by wrapping the entire deferred command in double-quotes, like this:

	:e +"set bufdisplay=man" filedb.8
mark
This is the name of a mark - a single lowercase letter. Elvis allows (but does not require) an apostrophe before the letter.
rhs
This is a string of characters. If it begins with a whitespace character, then that character must be quoted by embedding a ^V character in the command line before it. Other whitespace characters in the string do not need to be quoted.
expr
This is an arithmetic expression using the normal syntax.
shellcmd
This is a command line which is passed to the system's command interpreter. Within the command line, the following character substitutions take place, unless preceded by a backslash:
	.-----------.----------------------------.
	| CHARACTER | REPLACED BY                |
	|-----------|----------------------------|
	|     %     | Name of current file       |
	|     #     | Name of alternate file     |
	|     #n    | Name of file whose bufid=n |
	|     !     | Previous command line      |
	|     \@    | Word at cursor location    |
	^-----------^----------------------------^
Note that the \@ substitution requires a backslash. This quirk exists for the sake of backward compatibility - the real vi doesn't perform any substitutions for just plain @.
file or files
This is one or more file name, or a "wildcard" pattern which matches the names of zero or more files. File names are subjected to three levels of processing. First, leading ~ characters and certain other characters are replaced with text, as follows:
    .-----------.------------------------------------------------.
    | SYMBOL    | REPLACED BY                                    |
    |-----------|------------------------------------------------|
    | ~user     | (Unix only) Replaced by home directory of user |
    | ~+        | Replaced by current working directory          |
    | ~