2024-12-09 ed is the standard

`ed` is the standard editor, they say. I have strange fascination with it.

the standard editor

`ed` is a window in the past. This is a line-based editor, not a screen-based editor. It can be used with a line-printer instead of a screen. This also means that working with it is very different. I'll try to collect some interesting command sequences on this page.

I use `ed` to send mail from the command line. One way I do this is by using `mail` on the server. It's a line-oriented mail client. You can use any editor with it, but the default feels very close to `ed`.

When I started reading newsgroups again, I used `tin` and made it use `ed` as the editor.

As you can see, it's growing on me. 😅

And I'm not alone! On fedi, I'm following @aartaka@merveilles.town who occasionally posts things about `ed`.

And so, in order to get better with it, I decided to write this page. I expect to be adding to it.

Also check out Actually using ed by @tejr@mastodon.sdf.org.

Actually using ed

Documentation

Try `man ed` or `info ed` to learn more about the commands available to you within `ed`.

@mwl@io.mwl.io. wrote Ed Mastery which motivated me to get into `ed`.

Ed Mastery

Create a new file

Start `ed` without a file name. You'll be editing "lines" in a "buffer".

The commands to use:

alex@melanobombus ~> ed
i
Hello World!

This is a letter from me to you.
.
w hello.txt
47
q

Edit an existing file

When we provide ed with a filename, it is read into the buffer (and the number of bytes read are printed). The current line is the last line of the buffer.

alex@melanobombus ~> ed hello.txt 
47
.
This is a letter from me to you.
a

And that was it!
.
w
65

Now, `ed` is line-oriented and so we can provide line numbers and line ranges to our commands. If you omit a line number or the range, these commands apply to the current line only. A range is two comma-separated line numbers. If you omit numbers, defaults are "from the first line" and "to the last line". Thus, a single comma means "all the lines". ` gemini - alexschroeder.ch is always the last line. Relative addressing with negative offsets like `-1` and positive offsets like `+1` works as well.

These are all equivalent:

So now let's number the lines and then append to the first paragraph. Use `n` to find the right line number to append to, and use `p` at the end to proofread.

,n
1	Hello World!
2	
3	This is a letter from me to you.
4	
5	And that was it!
3a
It's pretty short, I know. I didn't have enough time to make it longer.
.
w
137
,p
Hello World!

This is a letter from me to you.
It's pretty short, I know. I didn't have enough time to make it longer.

And that was it!

Notice how we could only append new lines after the third line. We couldn't append new words to the third line itself. What we can do is join two lines, though. Unfortunately, that doesn't add a space!

One option is to add a single line containing a space. The other option is to use a substitution to add a space. That's what we will use.

Knowing that this concerns lines 3 and 4 there is no need to use `n`.

3s/$/ /
3,4j
p
This is a letter from me to you. It's pretty short, I know. I didn't have enough time to make it longer.

Processing with other tools

There is no way to process the buffer with external tools, but there is a way to do it with the current file.

w
137
e !fold -s %
fold -s hello.txt
138
,p
Hello World!

This is a letter from me to you. It's pretty short, I know. I didn't have 
enough time to make it longer.

And that was it!

To insert some command output

I like to start my blog posts with a level one heading, a date, and some text. Here's how I would insert a date. Note the invisible space after the `#`.

ed i # . r !date --iso 11 a ed is the standard . ,j p # 2024-12-09 ed is the standard

Using the buffer as a workspace

OK, I know this is weird. But in theory we can think of the buffer as a huge one-dimensional workspace. We can insert lines from files and process output here and there, and we can write line ranges to files.

Here we are writing a haiku, don't like the last line, insert a new third line and then write just the first three lines to the file. The fourth line not saved but it is still available in the buffer.

alex@melanobombus ~> ed
i
The words grow from lines
a growing snake on the screen
trying to escape
.
w haiku.txt
73
i
running off the page
.
1,3w
77

In this sense it's unclear what the default filename of the buffer is. It's the one-dimensional desktop!

f
haiku.txt

Using marks and line arithmetic

Perhaps working with the buffer as a long, one-dimensional workspace makes more sense if you drop markers as you work with files. Use `k` followed by a lower case letter.

Here we insert a first haiku, mark the first line, insert a new haiku, mark its beginning, and then we print the two, using the marks and some line arithmetic.

r haiku.txt
77
1ka
a
Lines grow from the left
voices talking in my head
overhead, a lamp
.
-2kb
'a,'a+2p
The words grow from lines
a growing snake on the screen
running off the page
'b,'b+2p
Lines grow from the left
voices talking in my head
overhead, a lamp
'b,$w haiku2.txt
68

Hit Enter too soon

Something I do often enough: I hit the Enter key when I didn't mean to. Fix it by beginning the new line with a space. Finish the line, and join the previous line with the current line:

i
Hello
 World!
.
-1,.j
p
Hello World!

​#ed ​#Editor