# Grokking vi with ed



## UNIXgod (Jul 17, 2012)

This document is to aid a new vi user into operating ex mode. This tutor is meant to further one's ability after they understand basic vi mode operations. If your an absolute beginner and have vim installed you can run the command â€œvimtutorâ€ at your terminal. This document is meant to be read after the user is comfortable with the visual layer of vi.

Bill Joyâ€™s vi was initially a five mode operational terminal editor. The current implementations only have four modes whereas the original fifth mode known as â€œopenâ€ mode was the same as the visual mode meant for terminals that had no screen cursor (i.e. paper based hardcopy terminals).

Both nvi and vim have the four modes of operation which are the visual presentation layer we know as vi, text input mode; accessible from the vi layer, the ex mode for executing commands as well as an input mode accessible from ex.

Though most users consider ex a mode of vi; the presentation layer is what they see when they first start the editor. Interestingly enough itâ€™s the opposite. The vi layer is actually a mode built on top of ex;  therefore is â€œvisual on exâ€.

The ex editor is based on source derived from ed, the venerable UNIX line editor. The tutorial uses syntax from ed to help new users understand how to use ex. Information on how to get into ex from vi mode is at the end of the tutorial.

From the command line to enter ed is is as simple as this syntax:

`% ed -p '(ed)~> '`

This will give it a nice user friendly prompt.

*Append*

First we will add some text to the buffer to work with. This is as simple as using the append command (*a*) which will put the editor into text input mode. To return to the command mode type single dot (*.*) at the beginning of the line followed immediately by a carriage return as so:


```
(ed)~> [B]a[/B]
The ed utility is a line-oriented text editor
Vi is a a screen oriented text editor
Vim  is a text editor that is upwards compatible to Vi
[B].[/B]
(ed)~>
```

*Addressing*

To address a line one could simply type the line number. for example to see the second line:


```
(ed)~> [B]2
[/B]Vi is a a screen oriented text editor
```

For adding text after a line address one would use the address combined with an append â€˜*a*â€™ command as so:


```
(ed)~> [B]2a[/B]
Bosticâ€™s nvi is a bug-for-bug compatible replacement of 4BSD vi
.
```

*Print*

To view the change one could also use a range for addressing with the command (*p*) to print the text in that range. Address ranges are delimited by the comma.

```
(ed)~> [B]2,4p[/B]
Vi is a a screen oriented text editor
Bosticâ€™s nvi is a bug-for-bug compatible replacement of 4BSD vi
Vim  is a text editor that is upwards compatible to Vi
```

This can be read as follows: _print from line 2 to line 4_.

*Insert*

To enter text before a line one can insert text with the insert (*i*) command which in this case is the analog to â€˜*a*â€™


```
(ed)~> [B]2i[/B]
The line editor ex, short for EXtended, is a fork of source derived from ed
.
```

To view the entire buffer, which contains could be titled â€œ_The Evolution of Unix Text Utilities_â€, one might consider the â€˜*1,5p*â€™. Though this method will work the editor can address the variable last line with the currency symbol (*$*) thus can be written as* 1,$p*. Shorthand for printing the first line to the end is the percent symbol (*%*) which was further shortened to simply comma (*,*) for making it accessible for touch typists. Therefore all of these constructs will provide the same results:


```
(ed)~> [B]1,$p[/B]
(ed)~> [B]%p[/B]
(ed)~> [B],p[/B]
```

In ex the print (*p*) command is optional as itâ€™s as itâ€™s implied. Therefore the first two examples could be constructed as :*1,$* and :*%* in ex. Finally the ed construct â€˜*,p*â€™ is not interpreted in ex. For touch typists looking for a solution which would not require using shift key I have found that :*1,*  works well.

The dot (*.*) will print the current line. Most commands leave the current line at the last which was affected. Here is an example usage of (*.*):


```
(ed)~> [B]3[/B]
Vi is a a screen oriented text editor
(ed)~> [B].[/B]
Vi is a a screen oriented text editor
(ed)~> [B]2[/B]
The line editor ex, short for EXtended, is a fork of source derived from ed
(ed)~> [B].,3p[/B]
The line editor ex, short for EXtended, is a fork of source derived from ed
Vi is a a screen oriented text editor
(ed)~> [B].,$[/B]
Vim  is a text editor that is upwards compatible to Vi
```

To address before the first line the user can use address 0 where it makes sense. For example *0a* would be the equivalent to *1i* in ed. Though *0i* doesnâ€™t work in ed; it is interpreted in ex. The simple fact that ex knows â€œ_what the user meant_â€ shows where Joy wanted a more user friendly version of ed when creating ex.

*Delete*

Here is example usage which also shows how one would use delete (*d*) to remove one or more lines and finally to change (*c*) a line :


```
(ed)~> [B]0i[/B]
?
(ed)~> [B]0a[/B]
top
.
(ed)~> [B]1,2p[/B]
top
The ed utility is a line-oriented text editor
(ed)~> [B]1c[/B]
This is the top
of the file
.
(ed)~> [B]1,4p[/B]
This is the top
of the file
The ed utility is a line-oriented text editor
The line editor ex, short for EXtended, is a fork of source derived from ed
(ed)~> [B]1,2d[/B]
(ed)~> [B]%p[/B]
```

The last statement youâ€™ll see that the file is intact. If a mistake was made the user could undo (*u*) the last operation with the â€˜*u*â€™ command.

*Join*

The final command to take only a range is to join (*j*) two lines together. The operation will combine two or more lines into one. An example join line 4 to the end of line is (*3,4j*) or line 3 to the END of the document to line 2 would be (*2,$j*).

*List*

The join (*j*) command would be best to used in conjunct with the list (*l*) command which prints the text with a currency symbol (*$*) at the end of each line where a carriage return has taken place. The command (*%l*) will show where all the carriage returns are in the buffer.

*Change*

The change (*c*) command can take a range address as well such as (*2,4c* or *.,$c*). The behavior is the same. If the range is of three lines those three lines will be replaced If less than three lines are entered through input mode the rest of the text is truncated to the last entered line. Itâ€™s essentially a combination of delete the addressed line (*1d*) and insert at the addressed line (*1i*).

Input commands boil down to *a* (_append_), *i* (_insert_) or *c* (_change_). These are the only commands which will move the editor from command mode to input mode.

*Address Numbering*

To view the number of lines in in the buffer the (*=*) symbol will provide the integer. In combination with the current line number would be to combine the two as so â€˜*.=*â€™ . Numbers can be printed at the beginning of the line with the number (*n*) command. Here is an example:

```
(ed)~> [B]4[/B]
Bosticâ€™s nvi is a bug-for-bug compatible replacement of 4BSD vi
(ed)~> [B].[/B]
Bosticâ€™s nvi is a bug-for-bug compatible replacement of 4BSD vi
(ed)~>[B] .=[/B]
4
(ed)~> [B]1[/B]
The ed utility is a line-oriented text editor
(ed)~> [B].[/B]
The ed utility is a line-oriented text editor
(ed)~> [B].=[/B]
1
(ed)~> [B]=[/B]
5
```

Commands may require zero, one, or two addresses. If no address is given the default address (*.*) is implied.

*Move* and *Transfer*: _cut, copy and paste_

The last two line based operations are similar to the gui paradigm of _cut, copy, and paste_. In vi mode to copy a line one would â€œyankâ€ the text and to paste one would â€œputâ€ the yanked text a line below where the cursor was placed. In ed and ex the operations are a bit simpler. The awkwardly named transfer (*t*) command is a _copy then paste_ operation which syntax would look like (*4,5t2*) which copies lines 3 through 4; then pastes them to line 2. The move (*m*) command has the same structure; its operation is effectively the same as the _cut and paste_ metaphor today. A simple move example would be (*3,$m0*) which is cut lines 3 through END and paste the lines to the beginning of the file.


----------



## UNIXgod (Jul 17, 2012)

*Context Search*

Though the use of addresses is one way to navigate and operate on the buffer; context searches may be used where a line number is not known. The operation is best suited for larger buffers. To do a forward search the (*/*) symbol is used and to do a reverse search (*?*) symbol is used. Here are examples of context searching:

```
(ed)~> [B]/ed[/B]
The ed utility is a line-oriented text editor
(ed)~> [B]/Vi[/B]
Vi is a a screen oriented text editor
(ed)~> [B]?ex[/B]
The line editor ex, short for EXtended, is a fork of source derived from ed
(ed)~> [B]/EX[/B]
The line editor ex, short for EXtended, is a fork of source derived from ed
(ed)~> [B]/screen/,/BSD/p[/B]
Vi is a a screen oriented text editor
Bosticâ€™s nvi is a bug-for-bug compatible replacement of 4BSD vi
```

As one might observe the concept of context searching parses the whole line for a match. The pattern after (*/*) or (*?*) is a regular expression literal. To repeat the search incrementally the syntax would be â€˜*//*â€™ to move to the next match and â€˜*??*â€™ to move to the previous. The last example shows a context search to fulfill the same role as range addresses where â€˜*/screen/,/BSD/p*â€™ is the same as â€˜*3,4p*â€™.

Though this is not a tutorial for regular expressions it is an essential part of the UNIX system and these editors. The next logical step to have more granular control over your text manipulation; only after running through this tutorial, is to become familiar with regular expressions.

A more experienced user will also note that these work the same way they do on the system pager commands (*more*) and (*less*).  The systems manual (*man*) use environment defaulted pager to view and study commands. Though originally intended to use shared resources as the original time sharing systems were limited; there is the by-product that the user can learn one paradigm to be used in many system utilities.

Vi users can access context searches without ever going into _ex_ by typing either */* or *?* from visual mode which is synonymous with the aforementioned system utilities. To step through to the next match is forward (_*n*_) and reverse (_shift_-*n*).

*Global*

Global searching can be done by prepending the context search with the global (*g*) command. The common usage of global context searching within the buffer was so popular it would eventually be duplicated into the utility known as *grep* (_global regular expression print_). The analog to (*g*) is (*v*) which selects lines which do not match the expression. Here is example usage:


```
(ed)~> [B]g/Vi/p[/B]
Vi is a a screen oriented text editor
Vim  is a text editor that is upwards compatible to Vi
(ed)~> [B]g/re/p[/B]
Vi is a a screen oriented text editor
Bosticâ€™s nvi is a bug-for-bug compatible replacement of 4BSD vi
(ed)~> [B]v/re/p[/B]
The ed utility is a line-oriented text editor
The line editor ex, short for EXtended, is a fork of source derived from ed
Vim  is a text editor that is upwards compatible to Vi
```

*Shell*

External commands can be executed directly inside the editor where the commands would be prepended by the bang (*!*) symbol. One might observe that this predates the hash-bang (_#!_) shell interpreter directive. Entering the shell without closing the editor is as simple as (*!sh*). The user then can do what ever they need on the shell, even open up  a new editing session, and when they are finished they can quit the shell <_ctrl_-*d*> and it will return to ed. Alternate shells can be used as well when the system sh is undesired; such as (*!zsh*) for the z shell.

*Read*

External commands can be read back into a specific position of the buffer as well. This can be provided from the read (*r*) command with a positional parameter. For example if the user wanted to put the output of the unix date command at the head of the document the syntax would be (*0r !date*).

*File Association*

To place the buffer into a file the write (*w*) command alone will write to a file if itâ€™s specified. To see the file associated the file (*f*) command alone will reveal itâ€™s name. If there is no association both (*f*) and (*w*) commands will take a full path with the name of the file. The default path is the location of the directory in which you launched the editor. It is useful to know that the write (*w*) command can take an address to only write out specific portions of the buffer.


```
(ed)~> [B]f[/B]
?
(ed)~> [B]f /tmp/junk[/B]
/tmp/junk
(ed)~> [B]f[/B]
/tmp/junk
(ed)~> [B]w[/B]
277
(ed)~> [B]!tr 'A-Za-z' 'N-ZA-Mn-za-m' < %[/B]
Gur rq hgvyvgl vf n yvar-bevragrq grkg rqvgbe
Gur yvar rqvgbe rk, fubeg sbe RKgraqrq, vf sbex bs fbhepr qrevirq sebz rq
Iv vf n n fperra bevragrq grkg rqvgbe
Obfgvp'f aiv vf n oht-sbe-oht pbzcngvoyr ercynprzrag bs 4OFQ iv
Ivz  vf n grkg rqvgbe gung vf hcjneqf pbzcngvoyr gb Iv
!
```

The last line shows how an external command could be used. In this case tr is used as rot13 also known as the caesar cipher. The percent (*%*) in this case represents the file and will expand to /tmp/junk when the command is executed.

Though this is not a tutorial on simple encryption it is worth exploring in vi. To leave the editor the command is quit (*q*). If the contents have not been saved it is best to do so so we will finish this tutorial in vim. If you see a (*?*) after giving the (*q*) command it means that you have not saved the buffer much in the same why you would have to use the (*q!*) in vi.

Once in vi you can access ex from pressing the colon (*:*) which returns to the visual mode right after execution of a single command or pressing the escape key. An alternate way enter ex is to press <_shift_-*q*> or (*Q*) which will allow ex to work as a pure line editor much like ed. The command to switch back to vi from ex is either :*vi* or :*visual*.

Finally from the shell prompt the command _vi_ will begin in visual mode and vi -e will begin in command mode just the same as the _ex_ command will enter command mode respectively as well as ex -v will enter visual mode.

`% vim -e /tmp/junk`

```
"/tmp/junk" 5L, 277C
Entering Ex mode.  Type "visual" to go to Normal mode.
:[B]vi[/B]
```

To alter text within the document via external command the user can prefix the bang command with an address or context search. Here are some examples with using our rot13 statement:


```
:[B]/EX/,/BSD/!tr 'A-Za-z' 'N-ZA-Mn-za-m'[/B]
:$[B]!tr 'A-Za-z' 'N-ZA-Mn-za-m'[/B]
:[B]2,$!tr 'A-Za-z' 'N-ZA-Mn-za-m'[/B]
:[B]%!tr 'A-Za-z' 'N-ZA-Mn-za-m'[/B]
```

If the last command is executed a second time the text will decrypt to the original form.

*Substitute*

The substitute command is one of the most useful commands to be used within these editor. The commands primary function is to search and replace. The main construct is (_*s*/pattern/replace_). Within ex it works one the first pattern it finds on the line which itâ€™s executed. If the there exists a repeated pattern the global (*g*) can be postfixed to the substitute statement alter further instances in that line.

Addressing can be used to alter specific lines or the whole file. The special ampersand character (*&*) can be used within the â€˜replaceâ€™ portion of the construct as shorthand to reuse the characters in the pattern without retyping them. An example of (*&*) usage would be *s/re/&place*) which will match the first instance of the letters â€˜_r_â€™ followed by â€˜_e_â€™ and change them to â€˜_replace_â€™.


```
:[B]s/ed/QED[/B]
The QED utility is a line-oriented text editor
```

Simple replace with literal context.

```
:[B]/screen/ s/$/; created by Bill Joy/[/B]
Vi is a screen oriented text editor; created by Bill Joy
```

The currency symbol in regular expressions represents the end of line therefore in the context above appends at the end.

```
:[B]%s/^Bostic/Keith &/g[/B]
Keith Bostic's nvi is a bug-for-bug compatible replacement of 4BSD vi
```
The circumflex (*^*); or carrot is the analog of $ and represents the beginning of line. When alone it can be used to insert text at the beginning of the line.


```
:[B]$s/Vi\>/Joy's &/[/B]
Vim  is a text editor that is upwards compatible to Joy's Vi
```

The backslash greater than *\>* represents the end of a word. The backslash less than is the analog and represents the beginning of the word *\<*. These are useful for having more granular control over your matching. If it was not used in the previous example it would have matched word â€˜Vimâ€™ at the beginning of the line which was not was intended.


----------



## UNIXgod (Jul 17, 2012)

*Pipe*

To remove content within the buffer the last set of forward slashes should have no white space. The pipe (*|*) represents a delimitation of commands and allows multiple commands to coexist on the same line.

```
:[B]%s/4//g[/B]
Keith Bostic's nvi is a bug-for-bug compatible replacement of BSD vi
:[B]%s/\<BSD/Free& UNIX/[/B]
Keith Bostic's nvi is a bug-for-bug compatible replacement of FreeBSD UNIX vi
:[B]s/of/for/ | s/\<vi\>//[/B]
Keith Bostic's nvi is a bug-for-bug compatible replacement for FreeBSD UNIX
```
*
Addressing Arithmetic*

Both (*+*) and (*-*) symbols are considered relative positional parameters for operations that need to be done a line before or after the absolute line address.

```
:[B]%#[/B]
 1 The QED utility is a line-oriented text editor
 2 The line editor ex, short for EXtended, is a fork of source derived from ed
 3 Vi is a a screen oriented text editor; created by Bill Joy
 4 Keith Bostic's nvi is a bug-for-bug compatible replacement for FreeBSD
 5 Vim  is a text editor that is upwards compatible to Joy's Vi
:[B]4-#[/B]
 3 Vi is a a screen oriented text editor; created by Bill Joy
:[B]4-2#[/B]
 2 The line editor ex, short for EXtended, is a fork of source derived from ed
:[B]2+3#[/B]
 5 Vim  is a text editor that is upwards compatible to Joy's Vi
:[B]/fork/+2#[/B]
 4 Keith Bostic's nvi is a bug-for-bug compatible replacement for FreeBSD
```

*Regular Expressions*

In conclusion new users will want to explore regular expressions for further power usage.

Many utilities derived from ed beyond the visual editor such as grep, sed and the awk programming language which was initially created for users to script custom filters. The Perl programming language was conceived as an alternative to the â€œDoes one thing and does it wellâ€ UNIX philosophy. The Ruby programming language was influenced directly by Perl; as well as Python, Smalltalk and Lisp. Ruby provides a native regular expression class to instantiate regex objects.

Though Ruby and Perl have regular expressions built directly into the language, other languages such as Python or C++ have access to them via language extension or library.

A more interesting note is that the shell provided filename expansion via glob; shortened from global. Within the shell the only a small subset could be used. Modern interactive shells, such as the Z Shell (zsh), provide an option to extend the set to proper regular expression syntax.

Vim users may want to look into an extension called magic and very magic which enables various methods for dealing with escaping regular expression syntax with various regex implementations.

*Happy Hacking.*


----------



## UNIXgod (Jul 17, 2012)

*Final Thoughts*:

This tutorial was written in response to a common diatribe among new users I have spoken with on irc and various local user groups on the vi learning curve. 

The muscle memory to set in for visual mode could easily take a user several months to get used to. To make matters worse the shell defaults to emacs binding for shell line editing which effectively extends the learning curve.

Once the transition is made; these "bindings" will become second nature providing the user a fluid experience at the terminal as well as useful skills for the rest of their lives.

It is the author's hope that the information herein will alleviate the new user's frustrations with grokking vi.

~

*History*:

*1956* Stephen Cole Kleene, a student of Alonzo Church (lambda calculus), describes regular sets; mathmatical notation to describe automata and formal language theory. What we refer today as regular expressions.
*1962/63* TECO (paper) Tape Editor and COrrector is the oldest incarnation of the editor.
*December 1967* QED 'quick' editor written by Butler Lampson and Peter Deutsch for the Berkeley time-sharing system on the SDS 940 *
Ken Thompson implemented QED in IBM 7090 assembly language for MIT CTSS (Compatible Time-Sharing System) introducing NDFA regular expressions to the editor.
Thompson once again reimplemented QED, this time in BCPL, for the Multics project (Multiplexed Information and Computing Service).
*1969* Thompson creates ed in assembly for UNICS (UNiplexed Information and Computing Service) after he returns to Bell Laboratories. Ritchie begins working on what would become the C programming language.
*1972-1973* Dennis Ritchie's C programming language is implemented; ed is written in C; the kernel is rewritten and the system can compile itself. Kernighan suggests a new name; the system is renamed UNIX.
*1975-77* Bill Joy starts hacking em, "editor for mortals", which is George Coulouris' fork of Thompson's ed. Joy versioned by letter from em to en to ex. 
*1977* Joy distributes 1BSD with ex and a pascal system. 
*1978* 2BSD which implemented vi (the visual version of ex) and the C shell.
*1987* Stevie (ST editor for VI enthusiasts) a vi clone by Tim Thompson is released.
*1988* Bram Moolenaar begins to work on vim on his Amiga computer with stevie as the source. 
*1990* Steve Kirkendall posted elvis (a vi clone) to USENET. Keith Bostic proposes removal of non-AT&T code Within eighteen months, all the AT&T utilities had been replaced. Bostic used the source from elvis to create a bug-for-bug comparable clone nvi (new vi).
*1991* vim (Vi IMitation) is released to the public
*1993* Moolenaar changes the acronym to "Vi IMproved" as vim surpassed the original vi feature set.
*Descendants*:
Utilities and programming languages which where are where influenced from ed:

*ed* (1971) --> *grep* (1973) --> *sed* (1974) --> *awk* (1977) --> *perl* (1987) --> *ruby* (1993)

*Historical MAN pages*:

Bill Joy's ex/vi man pages:
ex(1)
vi(1)

Original ed source:
http://www.tuhs.org/Archive/PDP-11/Trees/V6/usr/source/s1/ed.c

The ADM-3A keyboard layout Joy used as a template for vi:
https://upload.wikimedia.org/wikipedia/commons/a/a0/KB_Terminal_ADM3A.svg

UNIX 1st edition:
ed(1)
UNIX 6th edition:
ed(1)
UNIX 8th edition:
ed(1)
vi(1)
Plan9:
ed(1)
Sun Microsystems man pages:
ed(1) << this is the most complete.
ed(1)
ex(1)
vi(1)

Papers:
An Introduction to Display Editing with Vi
Ex Reference Manual

QED manual (in html) authored by Dennis Ritchie and Ken Thompson.
http://cm.bell-labs.com/who/dmr/qedman.html
There is a nice section explaining regular expressions. Please note DMR's note at the top dating it at June 22, 1970.
This is the original document scan:
http://cm.bell-labs.com/cm/cs/who/dmr/qedman.pdf

BSD ed additions can be seen in source /usr/src/bin/ed


> 1) BSD commands have been implemented wherever they do not conflict with
> the POSIX standard.  The BSD-ism's included are:
> i) `s' (i.e., s[n][rgp]*) to repeat a previous substitution,
> ii) `W' for appending text to an existing file,
> ...



There is a tutorial in the source for nvi /usr/src/contrib/nvi which can be run with:
`% /usr/src/contrib/nvi/docs/tutorial/vi.tut.csh beginner`
or
`% /usr/src/contrib/nvi/docs/tutorial/vi.tut.csh advanced`


----------



## ikreos (Jul 17, 2012)

Very nice writeup! I learned something new today.


----------

