Text editing with vi and vim
- 1 Introduction to Text Editing
- 1.1 Text Files vs. Document Formatted Files
- 1.2 Why vi?
- 1.3 History and nomenclature: Why is it called "vi?"
- 1.4 Basics
- 1.5 vi as a Language
- 1.6 Advanced Tips and Technique
Introduction to Text Editing
One of the most pervasive practical skills used by programmers and system administrators has traditionally been the editing of text. Most programming is done by the creation and manipulation of source code which is normally stored and passed to compilers and interpreters as text files. Similarly the traditional configuration and management of systems (particularly of UNIX and similar systems) has been done by maintaining configuration data in text files (such as /etc/passwd and various sorts of *.conf files).
Although modern IDEs (Integrated Development Environments), and package, system and configuration management tools typically hide the details, text files still permeate the operations of most development and operating systems. Often any non-trivial configurations or options require the use of a text editor.
Text Files vs. Document Formatted Files
New students to programming or systems administration are often confused by the distinction between "text files" and any of the various document formats used by word processing systems, spread sheet programs or other applications. The fact that many word processing and other applications can transparently import from and sometimes export back into text, and that many modern text editors support "syntax highlighting" (whereby the contents of the text are parsed for certain patterns as hints for how it should be displayed in different fonts or colors), makes this distinction somewhat more difficult to explain.
A text file normally consist only of printable ASCII characters (alphanumeric and punctuation), and "whitespace" (spaces, tabs, and line terminators). Such files normally look almost identical when accessed with a text editor or when dumped to a terminal or printer using the UNIX 'cat' (concatenate) or the old MS-DOS 'TYPE' commands.
By comparison the various types of "document" formats used by word processors normally contain special codes to describe the presentation of the document's contents, things like layout, typeface and size information, and so on.
There are many text editors, and many programs (such as integrated development environments (IDEs) have their own text editing features. Indeed every web browser offers support for text areas in HTML forms, which is, of course, normally provided by an embedded text editor.
Most of these use a familiar, common subset of features (cursor keys moving around, the mouse is used to highlight, cut and paste passages of the text, etc.).
vi is much different. While most modern versions of vi support the use of cursor keys, and some even allow the mouse to be used for cut & paste operations, vi doesn't assume that a keyboard has cursor keys and doesn't require a mouse ... among many other things.
So, it's reasonable for a new student of systems administration or programming on UNIX-like systems to ask whether it's worth the effort to learn vi.
The most obvious answer is that vi (and the underlying line editor ex ... or its predecessor ed) are the oldest and most ubiquitous editors across the range of UNIX-like system. Even a 30 year old PDP-11 or an exotic Cray supercomputer running UNICOS is likely to have a copy of vi (or, at very least ed) that will work the same as the base commands supported by vim from the latest versions of Linux and Mac OS X. Also, because vi has been supported since the earliest days of time-shared computing ... and supports almost any sort of terminal connection, it's possible run vi across almost any connection that can supply a shell prompt ... including some last resort dial-up connection to a modem in some distant server closet, for example. It can also be useful that vi can be used, possibly in a degraded mode, on somewhat damaged system (where, for example, many of the libraries upon which graphical editors might be unavailable).
For sysadmins this ubiquity and resilience can be critical; and struggling to learn an unfamiliar editor while trying to troubleshoot and resolve some emergency is a horrifying prospect.
However, there are better reasons to learn vi. It embodies a different philosophy about the text editing task implementing a language through which the user conveys to the system how he or she wants the cursor to move and how he or she wants the text to be modified. This is a highly specialized, expressive, and terse (efficient) language.
History and nomenclature: Why is it called "vi?"
While it may seem like a useless bit of trivia, knowing that "vi" was so-named because it was implemented as a "visual interface" to an existing line editor named ex ... and further learning that ex was the "extended version" of the original line "editor" can provide insights into why it's designed as it is and why certain commands work as they do. (Later, we'll learn that the ":" (colon) commands are simply vi's way of providing access to the underlying ex features where that made the most sense).
vi is an alternative interface to an older editor which was an ex-tended version of the first UNIX "line editor" (ed).
An Historical Note on Line Editors
Many computer users today are unfamiliar what the phrase "line editor" even means. They haven't been necessary on more than a handful of machines for at least twenty five years.
In the earliest years of digital computing one could not use computers interactively. It was necessary to encode programs and data on to punched cards or paper tape and feed those into systems as "batch jobs." Results where printed out (usually on "fanfold" paper, often with "green bars" pre-printed on each sheet to make it easy for one's eyes to track across the page).
During that era there also emerged "interactive timesharing systems" which allowed users at terminals to work concurrently "on" the computer. Because even those old computers (with a fraction of the power and capacity of the most modest modern home computer system) could read and execute commands, and print out results far faster than humans can type, it was possible for a single computer to handle multiple users at the same time with each user getting a fraction (a "slice") of the computer's processing time and power.
The earliest timesharing systems were accessed by  devices—essentially electro-mechanical typewriters or paper tape "punch" machines with a serial line relay.
Editing text on such devices had to be done by programs which could be operated without a computer screen. One would print lines of the text, issue commands to insert new lines between existing lines, delete them or move them around—and, of course, to change portions of selected lines.
Such line editing programs typically provide little or no feedback after each command was issued. For the system to print out sections of the text after each command would be both slow and wasteful (consuming paper and for most TTYs, or "teletypewriters", relatively expensive types of paper, in rolls or, alternatively boxes of "fanfold" or "greenbar" as it was called).
Thus, the earliest programs for editing text on computer were much different than those to which we're accustomed today. Computers were much different back then, too.
As we'll see these old line editor commands and concepts are still supported and sometimes extremely useful in vi today.
In the case of ex an editing session consists of commands entered at a "colon" prompt. The editor loads the text into memory and prints a : (colon) character as a prompt (similar to the familiar shell command line prompt). From there the user issues commands (usually abbreviated as single characters) to manipulate the existing text. Adding new lines of text is done by adding or inserting whole lines (a and i commands respectively). From text entry mode one uses Ctrl-C to complete the additions and return to the colon prompt. Commands operate over whole lines which are specified by their line numbers. By default commands operate over the current line. Entering just a line number selects that line to be current. Most commands can be prefixed by ranges of lines; so a command like 10,15d would delete lines 10 through 15 (inclusive). Line numbers prefixed by a + or − (plus or minus signs) are relative to the current line (so -5,+8p would print from five lines before to 8 lines after the current one) and there are a couple of abbreviations for current line (.—the dot) and the last line ($—dollar sign) and all lines The range (1,$) can be referred to as % (the percent sign). Thus a command like: .,$m0 would move the lines from the current one through the end of the file to the beginning of the file (deleting them from the end and inserting them before the prior beginning of the text). Lines can also be addressed by matching a pattern (regular expression) surrounded by / (the "slash" characters) in the text. Thus a command like: /a/,/b/m$ would search from the current line for the nearest containing the letter "a" and for the nearest containing the letter "b" ... and move those and any lines between them to the end of the file. (In this example "a" and "b" can be any strings or regular expressions).
Changes within any line of text are done by either deleting and re-entering them or by using the "substitute" command. The s command defaults to changing the first matching substring (and matching as much text to the pattern as possible—so-called "greedy" matching). Flags to the s command can force it to be applied globally across each line, to make the pattern case-insensitive, and to interactively prompt and confirm each change. The "global" flag to a substitute command should not be confused with the "global" command itself.
The "global" and "inverted global" (g and v commands, respectively) can match a set of lines and apply some command to them. For example g/re/p would apply the p (print) command to all lines containing the regular expression "re." In fact it is from this command (and the way it was documented to ed users) that we get the name for the quintessential UNIX utility: grep (the global regular expression printer). The ex global command can be used a variety of other commands. So, for example, a command like 10,15g/c/s/a/b/ will globally substitute "b" for "a" on any lines containing "c" between lines 10 and 15 inclusive. (The inverted global would apply those substitution only on lines which did NOT match the pattern /c/: 10,15v/c/s/a/b/).
It's useful to know these older ex commands even when using the "visual interface." For example substitutions ("search and replace" in the terminology of most text editing and word processing tools) is still done using the ":" commands even when operating in vi mode. Also there are some cases where a succinct ex command can save quite a few error-prone steps if they were done interactively. (For example v/^\*/-1j can find all the lines that don't start with a * (bullet) and join them to the previous line ... thus "un-line-wrapping" a bullet list).