In the beginning there was Unix. At least, that’s where I want to start exploring how vim
came to be.
For many trades, knowing your tool so well that it’s transparent between you and your work is vital. And to me, that includes knowing the history that led up to the tools at hand. Today, I mostly use Visual Studio Code as my editor (with a plugin to give me vi/vim
keybindings), and vim
is my go to for quick edits and most “sysadmin” type changes.
But our story for how vim
came to be starts with Unix, and more precisely with ed
, the standard editor.
Who is Ed?
In the Unix userland, there are many tools that we all expect to just be there: cat
, cp
, dd
, ls
, and so on. GNU calls this set of tools the “coreutils”. But when Ken Thompson was developing Unix, he saw that three things were needed for development in Unix: an assembler, editor, and shell. In 1969, he developed ed
to fit the role of the editor in his equation.
ed
, to a modern user, is archaic. It follows a line editor paradigm, operating on just a single line at a time. Consider this file called hello.c
:
|
|
Compiling and executing gives us:
|
|
Oops! We forgot to include a newline (\n
) in our printf()
. Let’s fix that with ed
!
|
|
Alright. So what are we looking at?
ed
has opened the file, and read in 78
characters. Now it’s just waiting on us to give it commands. The easiest is q
(and <ENTER>
) to close ed
and get back to our shell. But let’s finish editing this file to insert a newline during the printf()
.
|
|
The first command I entered was P
. This toggles the command prompt in ed
. This isn’t required, but adds a *
at the beginning of the commands I entered to make it a bit easier to read for this demonstration.
pn
prints the current line with the line number. Note that it shows we are on line 7 (ed
starts you on the last line in the file).
1,7pn
passes a range of 1 through 7 to p
and we have n
there as well so that we get line numbers. Now we can see our entire file. We are concerned with line 5, so let’s edit that.
5c
tells ed
that we want to change line 5. Crazy right?
This doesn’t return any output, so the next line was my input. In this case, it was 4 spaces followed by an updated printf()
with the \n
included. Ctrl-c ends the input.
p
prints out the current line. Since we just changed line 5, that’s our current line. So we see our change.
w
writes the buffer to disk and returns the amount of characters written, which was 80 in this case.
q
quits ed
as previously mentioned. Then I’m back on the shell and compile and run my code to see the new output with our freshly minted \n
.
This is just a small example of ed
. If you’d like to dive down the rabbit hole, just make sure you have ed
installed and run info ed
to read the Info pages. But even based on this small example, you can see how ed
is modal. There’s a command mode (the default), and then an insert mode where I was able to change a line.
But before we move on, let’s look at one more feature of ed
:
|
|
The command here is g/re/p
. Which Globally searched for the regular expression “re”, and printed the result. If we added an n
at the end, we would have also seen the line number (6 in this case).
That global searching of a file with a Regular Expression birthed a new program, keeping inline with the unix philosophy of a tool doing one thing well, and that’s basically how we ended up with our regex searching tool being called grep
. But that’s probably a whole other blog post.
At this point you may be wondering why ed
just works line-at-a-time. Remember, we’re dealing with a program developed in 1969. At the time, a user would most likely be interfacing with the computer via a teletype. A multiline display method just wasn’t feasible or useable in most scenarios. Moreover, an idea for Unix was that it would be able to run on less expensive systems, like a PDP-7.
By mid-1972, Unix had 10 installations, and development was happening with ed
.
That leads us nicely into the next chapter in the saga. Another Bell Labs creation: sed
.
Yea, what he sed
By 1974, Lee E. McMahon working at Bell Labs in New Jersey had developed sed
. What he called a “Non-interactive Text Editor”. sed
gets its name from being a stream editor.
Let’s take a quick sidebar to talk about what it means to be a stream editor. To facilitate the recurring theme of doing just one job and doing it well, we have pipes that allow you to pass the output of one command to the input of the next. For example, if we want to display the list of files in our directory we would use ls
. If we want to count the lines in a file we use wc
with the -l
flag. We can combine those as shown below:
|
|
That’s a really simple example, obviously, but it shows that using the pipe (|
) we can pass the output of one command as the input to another.
Now imagine we want to change all of the indentation in our hello.c
from four spaces to tabs instead. That’s where sed
comes in. We could do this with ed
, but with sed
we don’t have to worry about moving around the file or even loading the entire file into memory first.
|
|
Here, our regular expression is finding four spaces and replacing that with a \t
character in hello.c
. Note that this doesn’t write to disk. Instead, it just outputs the results of the changes. We can add > hello.c
to the end of our command to redirect the output back to the hello.c
file and replace the contents completely.
And again, this argument to sed
is working line-at-a-time through the input to arrive at our results. But let’s look at another example that takes advantage of sed
being able to work on streams of data passed in via pipes.
|
|
In this example, we are taking the output of date
and editing with sed
. We are using a regular expression that matches all lowercase letters and converting them to their uppercase equivalent. The g
at the end says to do it globally. Without that g
switch, it would stop executing the regex after the first match. This shows that we don’t have to write the output of date
to disk first to manipulate it.
The EXtended Editor and the original eVIl editor
By 1976, Bill Joy had began writing a “new” line editor for Unix called ex
. This time for the first BSD release, 1BSD. Of course ex
didn’t live in a vacuum. em
was another editor developed in the early 70s that was meant to utilize video terminals. To me, this influence seems to be what sparked the ideas that lead up to the eventual creation vi
.
vi
and ex
are closely tied together. On my machine, the vi
command is a symlink to ex
for example.
|
|
vi
and ex
exists as two sides of the same coin. vi
is the visual mode, and ex
is the line mode of the same editor. By 1979, in the Second BSD release, a user could (like today) type vi
in their shell to go straight into the visual mode of ex
.
If you’ve ever been curious about the usage of the <ESC>
and h j k l
keys in vi
, look no further than the keyboard for the ADM-3A terminal that Bill Joy used at the time. You’ll see that the <ESC>
key sits where your <TAB>
key most likely sits today, and the h j k l
keys have arrows on them that correspond to the cardinal directions that they represent in vi
.
Improving on a Classic
In 1987, Tim Thompson was using an Amiga ST. He developed a clone of vi
called “Stevie” which was an abbreviation of “ST Editor for VI Enthusiasts”. Bram Moolenaar, based on this work, began developing vim
for the Amiga in 1988 with an initial public release in 1991.
The name vim
was originally chosen to represent Vi IMitation
but eventually came to mean Vi IMproved
as it was ported to other systems. Among these improvements were new modes, extended regular expressions, a scripting interface for developing plugins, editing of archives (gzip, tar, etc), spell checking, splitting and tabbed windows, syntax highlighting, and a long list of other changes and additions. vim
is described as “very much compatible with vi
”, but is not strictly compatible with the POSIX specification of vi
.
As you can see, the evolution of these tools has a long-lasting legacy. Each iteration brought new ideas, but stood on the shoulders of the giants that came before them.
Today, vim
is still in active development, with the latest release at time of writing being Vim 8.2, released in December of 2019. With projects like Neovim being actively developed, the lineage of ed
is alive and well, and the next 50 years of ed
or vi
(or however you see it) will continue to see improvements and new users.
Conclusion
This was a very brief history of Vim’s lineage, and doesn’t touch on the influence on (and of) POSIX, Emacs, or any of the other editors and programmers in the story. I hope you’ve learned a bit about your tools. Now get out there and use ’em!