vile has a number of interesting features that are the topic of this section.
vile's editing model is somewhat different from vi's. Based on concepts from emacs, it provides key rebinding and a more dynamic command line.
vile supports editing "modes." These are groups of option settings that make it convenient for editing different kinds of files.
vile's procedure language allows you to define functions and macros that make the editor more programmable and flexible.
A number of smaller features make day-to-day editing easier.
In vi and the other clones,
editing functionality is "hardwired"
into the editor. The association between command characters and
what they do is built into the code. For example,
the x
key deletes characters, and the i
key enters insert mode.
Without resorting to severe trickery, you cannot switch the
functionality of the two keys (if it can even be done at all).
vile's editing model, derived from emacs
through MicroEMACS, is different.
The editor has defined, named functions, each of which performs a single
editing task, such as delete-next-character
or delete-previous-character
.
Many of the functions are then bound to keystrokes, such as binding
delete-next-character
to x
.
Changing bindings is very easy to do. You use the
:bind-key
command. As arguments, you give it the
name of the function, and then the key sequence to bind the
function to. You might put the following commands into
your .vilerc file:
bind-key incremental-search / bind-key reverse-incremental-search ?
These commands change the /
and ?
search commands to do incremental searching.
In addition to pre-defined functions, vile contains a simple programming language that allows you to write procedures. You may then bind the command for executing a procedure to a keystroke sequence. GNU emacs uses a variant of Lisp for its language, which is extremely powerful. vile has a somewhat simpler, less general-purpose language.
Also, as in emacs, the vile command line is very interactive. Many commands display a default value for their operand, which you can edit if not appropriate, or select by hitting [RETURN]. As you type vi mode editing commands, such as those that change or delete characters, you will see feedback about the operation in the status line.
The "amazing" ex mode that Paul
referred to earlier is best reflected in the behavior of the
:s
(substitute) command. It prompts for
each part of the command: the search pattern, the replacement
text, and any flags.
As an example, let's assume
you wish to change all instances of perl
to awk everywhere in your file.
In the other editors, you'd simply type
:1,$s/perl/awk/g
[RETURN],
and that's what would appear on the command line.
The following set of screens describes what you see on the
vile colon command line as you
type:
Keystrokes | Results |
---|---|
:1,$s | The first part of the substitute command. |
/ | substitute pattern: _ vile prompts you for the pattern to search for. Any previous pattern is placed there for you to re-use. |
perl/ | replacement string: _ At the next / delimiter, vile prompts you for the replacement text. Any previous text is placed there for you to re-use. |
awk/ | (g)lobally, ([1-9])th occurrence on line, (c)onfirm, and/or (p)rint result: _ At the final delimiter, vile prompts for the optional flags. Enter any desired flags, then [RETURN]. |
The last prompt line is broken for readability. vile prints it all on one line.
vile follows through with this style of behavior
on all appropriate ex commands. For example, the
read command (:r
)
will prompt you with the name of the
last file you read.
To read that file again, just hit [RETURN].
Finally, vile's ex command parser
is weaker than in the other editors.
For example, you cannot use search patterns to specify
line ranges (:/now/,/forever/s/perl/awk/g
),
and the move command (m
) is not implemented.
In practice, what's not implemented does not seem to hinder
you very much.
A major mode is a collection of option settings that apply when editing a certain class of file. Many of these options apply on a per-buffer basis, such as the tab-stop settings. The major mode concept was first introduced in vile 7.2, and is more fully developed in 7.4 and 8.0.
vile has one pre-defined major mode,
cmode
,
for editing C and C++ programs. With cmode
,
you can use %
to match C preprocessor conditionals
(#if
, #else
, and
#endif
).
vile will do automatic source code indentation
based on the placement of braces ({
and }
).
And it will do smart formatting of C comments.
The tabstop
and shiftwidth
options are set on a per-major-mode basis as well.
Using major modes, you can apply the same features to programs
written in other languages. This example, courtesy of
Tom Dickey, defines a new major mode, shmode
,
for editing Bourne shell scripts.
(This is useful for any Bourne-style shell, such as
ksh, bash, or
zsh.)
define-mode sh set shsuf "\.sh$" set shpre "^#!\\s*\/.*sh\\>$" define-submode sh comment-prefix "^\\s*/[:#]" define-submode sh comments "^\\s*/\\?[:#]\\s+/\\?\\s*$" define-submode sh fence-if "^\\s*\\<if\\>" define-submode sh fence-elif "^\\s*\\<elif\\>" define-submode sh fence-else "^\\s*\\<else\\>" define-submode sh fence-fi "^\\s*\\<fi\\>"
The shsuf
(shell suffix) variable describes the
file name suffix that indicates a file is a shell script.
The shpre
(shell preamble) variable describes a
first line of the file that indicates that the file contains
shell code.
The define-submode
commands then add options
that apply only to buffers where the corresponding major mode is
set. The examples here set up the smart comment formatting
and the smart %
command matching for shell programs.
vile's procedure language is almost
unchanged from that of MicroEMACS.
Comments begin with a semi-colon or a double quote character.
Environment variable names (editor options) start with a
$
, user variable names start with %
.
A number of built-in functions exist for doing comparisons and
testing conditions; their names all begin with &
.
Flow control commands and certain others begin with ~
.
An @
with a string prompts the user for input, and
the user's answer is returned.
This rather whimsical example from the macros.doc
file should give you a taste of the language's flavor:
~if &sequal %curplace "timespace vortex" insert-string "First, rematerialize\n" ~endif ~if &sequal %planet "earth" ;If we have landed on earth... ~if &sequal %time "late 20th century" ;and we are then write-message "Contact U.N.I.T." ~else insert-string "Investigate the situation....\n" insert-string "(SAY 'stay here Sara')\n" ~endif ~elseif &sequal %planet "luna" ;If we have landed on our neighbor... write-message "Keep the door closed" ~else setv %conditions @"Atmosphere conditions outside? " ~if &sequal %conditions "safe" insert-string &cat "Go outside......" "\n" insert-string "lock the door\n" ~else insert-string "Dematerialize..try somewhen else" newline ~endif ~endif
You can store these procedures into a numbered macro, or give them names that can be bound to keystrokes. The above procedure is most useful when using the Tardis vile port. :-)
This more realistic example from Paul Fox
runs grep, searching for the word under the cursor in all C
source files. It then puts the results in a buffer named after the word,
and sets things up so that the built-in error finder (^X ^X
)
will use this output as its list of lines to visit.
Finally, the macro is bound to ^A g
.
The ~force
command allows the following command
to fail without generating an error message:
14 store-macro set-variable %grepfor $identifier edit-file &cat "!egrep -n " &cat %grepfor " *.[ch]" ~force rename-buffer %grepfor error-buffer $cbufname ~endm bind-key execute-macro-14 ^A-g
Finally, the read-hook
and write-hook
variables can be set to names of procedures to run after reading and
before writing a file, respectively.
This allows you to do things similar to pre- and post-operation
files in elvis and the autocommand
facility in vim.
The language is quite capable, including flow control and comparison features, and variables that provide access to a large amount of vile's internal state. The macros.doc file in the vile distribution describes the language in detail.
Several other, smaller features are worth mentioning:
If you make vile the last command in a
pipeline, it will create a buffer named
[Standard Input]
and edit that buffer for you.
This is perhaps the "pager to end all pagers."
When set to true, the
dos
option causes vile
to strip carriage returns at the end of a line in files when reading,
and to write them back out again.
This makes it easy to edit DOS files on a UNIX or Linux system.
The ^A f
command reformats text, performing
word wrapping on selected text. It understands C and shell
comments (lines with a leading *
or #
)
and quoted email (a leading >
).
It is similar to the UNIX fmt command, but
faster.
The modeline-format
variable is a string
which controls the way vile formats the
mode line. This is the line at the bottom of each window that
describes the buffer's status, such as its name, current major
mode, modification status, insert versus command mode, and so on.
The string consists of printf
(3)
style percent-sequences. For example, %b
for the buffer name, %m
for the
major mode, and %l
for the line number if
ruler
has been set.
Characters in the string which are not part of a format specifier
are output verbatim.
vile has many other features. The vi finger-feel makes it easy to move to. The programmability provides flexibility, and its interactive nature and use of defaults is perhaps friendlier for the novice than traditional vi.