Imagine if you had to edit a document that you couldn’t see. All you could do was ask specific questions about it and issue succinct and unambiguous commands to manipulate it. It sounds like it would be maddening, but this is exactly what text editing was like in the old days, with editors like Ed and its successor, Ex, and as we will see, there was more method to it than madness. And it wasn’t just text editors. A lot of things were like this back in those days, including computer games, the so-called “text adventures” or “interactive fiction.” Just like Ed, such games didn’t have access to modern graphical hardware, so they used something even better — our minds. Let’s make a digression into text adventures for a bit and experience what gaming was like once upon a time, to gain some perspective.
In text adventure games, you are presented with descriptions of the world you are in, and you can issue commands to take actions, or ask specific questions to learn more about the world or about the things in it. The most basic of these questions is “look,” or simply l
for short. Upon typing l
, you would be presented with a detailed description like this one1:
This is a sandy section of beach. You can’t help but notice that the colour of the sand is pure white. As you listen to waves crash on the beach, you notice the distinctive smell of the salty ocean. Peering westward through the fog you can make out the shape of a ship’s mast. Old stone steps lead up the cliffs from here. You can see a red bottle, nestled in the sand.
Inside the red bottle is:
A note.
You navigate the world by entering compass directions like w
or “west”, or “up” or “down” which are often abbreviated as u
and d
. And you could issue commands like this:
> open bottle
The red bottle opens.
> read note
… and so on. 🙂
The editor Ed (we will use Ed and Ex interchangeably) is a lot like this. You edit a document you can’t see directly, but which you can ask questions about and issue commands to modify, and Ed can tell you what effect those changes have had. While you could learn “Ex mode” commands in the context of Vim, I think it’s best if we leave Vim behind for now, and venture boldly down into the subterranean depths of Ex.
Hit Q
.
This should put you in Ex mode, and it will tell you so. If it doesn’t, then if you’re a Vim user, type :unmap Q
and try again. If you’re a user of another Vimlike (such as Evil) that doesn’t support persistent Ex mode, just go to a normal shell and type ex
. Now, we should all be in Ex mode.
e <filename>
— Edit file. Use any convenient file. If you like, copy the text of this entire tip into a new file, and use that filename here1
— this takes you to the first line (that’s the number one, not L)p
— “print” — this is analogous to l
or “look” in text adventures. It shows you the contents of the line you are on.
You navigate the document by typing -
or +
to go up or down a line, or by entering a number to go directly to that line, or by typing /
to go to the line containing the next occurrence of some term. Ex sees the world as made up of lines. You cannot make changes at a more fine-grained level than full lines. Therefore, all of these commands operate on lines, usually the current line.
d
— delete (that is, delete the line)i
— insert before this linea
— insert after this line.
— done inserting (must be on a line by itself at the end of the text you enter)c
— changej
— joins/old/new
— substitute the first occurrence of old with new (on this line)
It’s like navigating the world of text in the dark with a flashlight. Explore for a while.
More commands to try, just to demythologize them:
m<line_no>
— move (the line) to line number line_no!
— execute shell commandnorm <commands>
— Execute Vim normal mode commands
Some commands accept additional parameters at the end such as:
s/old/new/g
— substitute all (and not only the first) occurrences of old with new (on this line)
But in fact, Ex doesn’t just operate on a specific line, rather, it operates on a range of lines. Just as Vim’s underlying noun is a character range, Ex’s underlying noun is a line range. You can prefix any command with a line range to have it operate on those lines. Each command also assumes a default line range if you don’t specify one, which for most commands, as we’ve seen, is just the current line. Just like Vim (or the other way around!), Ex commands are composable.
1,3 d
to delete lines 1-3.3 i
to insert a new line before line number 3.6,10 m20
move lines 6-10 to line 204,/hello/ c
to change lines 4 through the next line containing hello. /hello/
is interpreted as a line address just like 4
is.
and so on. Adding a space between the line range and the command is optional, and it is typically left out. Ex also recognizes convenient aliases for common line ranges:
.
— current line (often this is assumed and you don’t need to specify it)$
— the last line of the file%
— all lines, a shorthand for 1,$
So that for instance,
%s/old/new/g
means substitute all occurrences of old with new on all lines
There’s also the “global” addressing commands g
and v
(not to be confused with the g
used as a parameter in the substitute command above!), which simply identify a set of lines that match a search pattern. Just like with simple line ranges, you can compose these with any command.
g/hello/p
— “print” all lines containing hello (this is how “grep” got its name — g/re/p, since, as usual, the search term can be any regular expression)1,100 v/hello/p
— “print” all lines in the first 100 lines not containing hello (“vrep” never quite caught on)
Parse the above as e.g. g/hello/ p
to understand how this is simply an address range composed with a command. But as g
and v
are themselves commands, you can indicate their scope by using a line range just like with any other command, as the second example shows. Unlike most other commands, g
and v
by default assume the line range %
, or all lines (that’s why they are called “global”).
And with that, let’s emerge into the light of the editor we know and love by typing:
visual
or, for short,
vi
This is how vi
got its name — it’s the visual interface built on top of the older ex/ed editor, enabling us to see the document we formerly could not see.
Well that was quite a journey, but why did we bother? We spent a lot of time down in the Ex world, but in practical Vim usage you’d want to leverage Ex only occasionally — this is what :
does. Whenever you type :
, you temporarily enter Ex mode to enter a single command. Now that you’ve been to that world, you’re a resident. :
is no longer a portal to a strange land but a portal to a familiar one. But, you may ask, why would we go there at all? Surely it is better to see the text than not to see it?
Perhaps, but sometimes, the eye of the mind can see in the darkness what is obscured from sight by a million lights. While on the one hand the fact that Ex can reason only in terms of lines is a severe constraint, on the other, it is a great strength. Just like in elementary physics where we apply simple mechanical models to phenomena that are vastly more complex, and find such models to be enormously useful in the cases where the finer details of the phenomena don’t matter to the essence of our purpose, in a similar manner, Ex mode can be seen as a simple model for the world of text encoding the idea that this world is made up of lines. When this model is the right one for our purposes, it allows us to do a great many things easily that would otherwise be completely intractable, even with all of the things we’ve learned about Vim. We will see common uses for Ex mode in the next tip, all of which fall under the rubric of aggregate operations.
1 From Skullduggery by David Jewett (1986)
Aaron
Thanks. l enjoyed this. Nice to see someone blogging about vim. I’m bored of all the impersonal ad-laden tutorial websites.
sid
Hehe, glad to hear it!
Lambert
Thanks for these blog posts, about Vim!
sid
You got it 🙂