This section describes the features of vile that make simple text editing easier and more powerful.
vile records your ex commands in a buffer named [History]. This feature is controlled with the history option, which is true by default. Turning it off disables the history feature and removes the [History] buffer. The command show-history will split the screen and display the [History] buffer in a new window.
The colon command line is really a minibuffer. You can use it to recall lines from the [History] buffer and edit them.
You use the ↑ and ↓ keys to scroll backward and forward in the history, and ← and → to move around within the line. Your current delete character (usually BACKSPACE) can be used to delete characters. Any other characters you type will be inserted at the current cursor position.
You can toggle the minibuffer into vi mode by typing the mini-edit character (by default, ^G). When you do this, vile will highlight the minibuffer using the mechanism specified by the mini-hilite option. The default is reverse, for reverse video. In vi mode, you can use vi style commands for positioning. You can also use other vile commands which are appropriate to editing within a single line, such as i, I, a, and A. vile decides which commands to accept based on its command-tables, which allows your key bindings to work in the minibuffer, too.
An interesting feature is that vile will use the history to show you previous data that corresponds to the command you're entering. For instance, after typing :set followed by a space, vile will prompt you with Global value:. At that point, you can use ↑ to see previous global variables that you have set, should you wish to change one of them.
The ex command line provides completion of various sorts. As you type the name of a command, you can hit the TAB key at any point. vile will fill out the rest of the command name as much as possible. If you type a TAB a second time, vile will create a new window showing you all the possible completions.
Completion applies to built-in and user-defined vile commands, tags, filenames, modes (described later in this chapter), variables, enumerated values (such as color names) and to the terminal characters (the character settings such as backspace, suspend, and so on, derived from your stty settings).
As a side point, this leads to an interesting phenomenon. In vi-style editors, commands may have long names, but they tend to be unique in the first few characters, since abbreviations are accepted. In emacs-style editors, command names often are not unique in the first several characters, but command completion still allows you to get away with less typing.
Tag stacking is described in Section 8.5.2. In vile, tag stacking is available and straightforward. It is somewhat different than the other clones, most notably in the vi mode commands that are used for tag searching and popping the tag stack. Table 12.2 shows the vile tag commands.
Table 12.2. vile Tag Commands
Command | Function |
---|---|
next-tag | Continues searching through the tags file for more matches. |
pop[!] | Pops a cursor position off the stack, restoring the cursor to its previous position. |
show-tagstack | Creates a new window that displays the tag stack. The display changes as tags are pushed onto or popped off of the stack. |
ta[g][!] [tagstring] | Edit the file containing tagstring as defined in the tags file. The ! forces vile to switch to the new file if the current buffer has been modified but not saved. |
The vi mode commands are described in Table 12.3.
Table 12.3. vile Command Mode Tag Commands
Command | Function |
---|---|
^] | Look up the location of the identifier under the cursor in the tags file, and move to that location. The current location is automatically pushed onto the tag stack. |
^T ^X ^] | Return to the previous location in the tag stack, i.e., pop off one element. |
^A ^] | Same as the :next-tag command. |
As in the other editors, options control how vile manages the tag related commands, as shown in Table 12.4.
Table 12.4. vile Options for Tag Management
Option | Function |
---|---|
pin-tagstack | Makes tag searches and pop not change the current window, thereby "pinning" it. By default this option is false. |
tagignorecase | Makes tag searches ignore case. By default this option is false. |
taglength | Controls the number of significant characters in a tag that is to be looked up. The default value of zero indicates that all characters are significant. |
tagrelative | When using a tags file in another directory, filenames in that tags file are considered to be relative to the directory where the tags file is. |
tags | Can be set to a whitespace separated list of tags files to use for looking up tags. vile loads all tags files into separate buffers that are hidden by default, but that can be edited if you wish. You can place environment variables and shell wildcards into tags. |
tagword | Uses the whole word under the cursor for the tag lookup, not just the sub-word starting at the current cursor position. This option is disabled by default, which keeps vile compatible with vi. |
vile is similar in principle but different in practice from the other editors. Like elvis and vim, there is an undo limit you can set, but like nvi, the . command will do the next undo or redo, as appropriate it. Separate vi mode commands implement successive undo and redo.
vile uses the undolimit option to control how many changes it will store. The default is 10, meaning that you can undo up to the 10 most recent changes. Setting it to zero allows true "infinite undo," but this may consume a lot of memory.
To start an undo, first use either the u or ^X u commands. Then each successive . command will do another undo. Like vi, two u commands just toggle the state of the change; however, each ^X u command does another undo.
The ^X r command does a redo. Typing . after the first ^X r will do successive redos. You can provide a count to the ^X u and ^X r commands, in which case vile will perform the requested number of undos or redos.
vile can edit files with arbitrary length lines, and with an arbitrary number of lines.
vile automatically handles binary data. No special command lines or options are required. To enter 8-bit text, type ^V followed by an x and two hexadecimal digits, or a 0 and three octal digits, or three decimal digits.
You can also enter 16-bit Unicode values by typing ^V followed by an u and up to four hexadecimal digits. If the current buffer's file-encoding option is one of the Unicode flavors (utf-8, utf-16 or utf-32), vile stores it directly as UTF-8, displaying it according to the capabilities of the terminal or display.
This leads us into the topic of localization.
At the time of the 6th Edition of this book in 1998, vile had rudimentary locale support. In part this was because locale support on the various platforms was (except for vendor UNIX systems) rudimentary. It had its own character type tables (i.e., control, numeric, printable, punctuation, as well as application-specific filename, wildcard, shell) allowing you to specify which of those non-ASCII characters were printable.
Times change, and vile continues to evolve according to its users' needs. Here is a brief summary of those changes, in order of development:
Rather than having a fixed notion of the character types, vile imports the host's character type tables and then provides commands to modify the data via scripts. [1]
vile regular expressions support POSIX character classes, as well as classes corresponding to vile's own character types.
Editing an file containing 8-bit data, e.g., encoded in ISO-8859-7 (Greek), when the host's locale encoding uses UTF-8 can be challenging. When vile starts up, it checks if the host locale ends with UTF-8 (or similar), e.g., el_GR.UTF-8. It supports editing in the corresponding 8-bit locale, e.g., el_GR.
Back to regular expressions; vile supports extraction of tokens from the screen, e.g., for tags, for scripting, etc. Those were a mixture of character-type tests with special parsing logic. Now they are purely regular expressions, with no need for the parsing logic.
Again, editing files in a host environment supporting UTF-8, there are files encoded in UTF-8. In the newest release, you can tell vile to write a file in various Unicode encodings, and to read the same encodings. The 8-bit editing model is carried forward, translating to the 8-bit encoding for buffers which are marked as 8-bit, and directly editing (no translation) the Unicode buffers.
These are all extensions; at each stage the older features are still retained.
There are other aspects of localization which are not addressed in vile, e.g., message formatting, collating.
When vile reads a file, it makes several guesses about its content, to present you with useful data:
It checks if the file permissions allow you to write to the file.
It checks for line-endings, which may be different flavors of CR, LF or CR/LF.
It checks for Unicode byte order marks.
It checks for Unicode multibyte encodings.
Based on these checks, vile may set properties (called "modes") of the newly read buffer which apply to that buffer. In addition, it may translate the data as it is read:
It removes the line-endings from each line, remembering the associated recordseparator mode.
If the file is missing a final line-ending, vile sets the nonewline option.
It translates UTF-16 and UTF-32 data into UTF-8, remembering the associated file-encoding option.
When you tell vile to write a buffer to a file, it uses those local option settings to reconstruct the file.
As mentioned in Section 8.6.4, you perform incremental searching in vile using the ^X S and ^X R commands. It is not necessary to set an option to enable incremental searching.
The cursor moves through the file as you type, always being placed on the first character of the text that matches. ^X S incrementally searches forward through the file, while ^X R incrementally searches backwards.
You may wish to add these commands (described below) to your .vilerc file to make the more familiar / and ? search commands work incrementally:
bind-key incremental-search / bind-key reverse-incremental-search ?
Also of interest is the "visual match" facility, which will highlight all occurrences of the matched expression. For a .vilerc file:
set visual-matches reverse
This command directs vile to use reverse video for visual matching. Since the highlighting can sometimes be visually distracting, the = command will turn off any current highlighting until you enter a new search pattern.
As mentioned in Section 8.6.5 in Chapter 8, you enable left-right scrolling in vile using :set nolinewrap. Unlike the other editors, left-right scrolling is the default. Long lines are marked at the left and right edges with < and >. The value of sideways controls the number of characters by which vile shifts the screen when scrolling left to right. With sideways set to zero, each scroll moves the screen by one third. Otherwise the screen scrolls by the desired number of characters.
vile is different from elvis and vim in the way you highlight the text you want to operate on. It uses the "quoted motion" command, q.
You enter q at the beginning of the region, any other vi motions to get to the opposite end of the region, and then another q to end the quoted motion. vile highlights the marked text.
Arguments to the q command determine what kind of highlighting it will do. 1q (same as q) does an exact highlighting, 2q does line-at-a-time highlighting, and 3q does rectangular highlighting.
Typically, you use a quoted motion in conjunction with an operator, such as d or y. Thus, d3qjjwq deletes the rectangle indicated by the motions. When used without an operator, the region is left highlighted. It can be referred to later using ^S. Thus, d ^S will delete the highlighted region.
In addition, rectangular regions can be indicated through the use of marks.[2] As you know, a mark can be used to refer to either a specific character (when referred to with `) or a specific line (when referred to with '). In addition, referring to the mark (say a mark set with mb) with `b instead of 'b can change the nature of the operation being done—d'b will delete a set of lines, and d`b will delete two partial lines and the lines in between. Using the ` form of mark reference gives a more "exact" region than the ' form of mark reference.
vile adds a third form of mark reference. The \ command can be used as another way of referring to a mark. By itself, it behaves just like ` and moves the cursor to the character at which the mark was set. When combined with an operator, however, the behavior is quite different. The mark reference becomes "rectangular," such that the action d\b will delete the rectangle of characters whose corners are marked by the cursor and the character which holds mark b.
The commands which define arbitrary regions and operate upon them are summarized in Table 12.5.
Table 12.5. vile Block Mode Operations
Command | Operation |
---|---|
q | Start and end a quoted motion. |
^A r | Open up a rectangle. |
> | Shift text to the right. Same as ^A r when the region is rectangular. |
< | Shift text to the left. Same as d when the region is rectangular. |
y | Yank the whole region. vile remembers that it was rectangular. |
c | Change the region. For a non-rectangular region, delete all the text between the end points and enter insert mode. For a rectangular region, prompt for the text to fill the lines. |
^A u | Change the case of the region to all uppercase. |
^A l | Change the case of the region to all lowercase. |
^A ~ | Toggle the case of all alphabetic characters in the region. |
^A SPACE | Fill the region with spaces. |
p, P | Put the text back. vile does a rectangular put if the original text was rectangular. |
^A p, ^A P | Force previously yanked text to be put back as if it were rectangular. The width of the longest yanked line is used for the rectangle's width. |
[1] | This feature is useful even on the vendor UNIXs which do not always deliver correct tables. |
[2] | Thanks to Paul Fox for this explanation. |