Introduction
Welcome to the Emulator.ca Systems Text Editor.
In November 1971, Ken Thompson sat at a teletype terminal connected to a PDP-11 running the first version of UNIX. He needed to edit text files, and he needed to do it through a device that printed output on paper, one line at a time. There was no screen, no cursor, no way to see the whole file at once. Out of this constraint, he created ed -- and in doing so, invented the patterns that would shape text editing for the next fifty years.
This might seem like ancient history, but the techniques Thompson devised remain remarkably relevant. When you connect to a BBS over a 300-baud modem, you face the same constraints he did: limited bandwidth, no guarantee that your terminal can display more than one line at a time, and the need to make precise edits without seeing the surrounding context. The line editor is not a relic -- it is the right tool for this environment.
Our text editor faithfully implements the classic ed command set. The learning curve is real: ed expects you to keep a mental model of your file, to know which line you are on without being told, to specify exactly what you want changed. In return, it offers something no screen editor can match: the ability to edit files of any size, over any connection, with complete precision. Users who master ed often find themselves reaching for it even when fancier editors are available.
WHY SO TERSE?
Ed's single-letter commands and cryptic error messages seem hostile to modern users, but they were a kindness in 1971. Every character you typed was transmitted over expensive, slow connections. Every character the computer sent back cost time and money. "?" is not rude -- it is efficient.
Quick Start
Do not let ed's reputation intimidate you. Creating and saving a file takes just a few commands. Dial 555-0730 and follow along:
:a Enter append mode (add text after current line)
Hello, world! Type your first line of content
This is my file. Type your second line
. A period alone on a line exits append mode
:1,$p Print all lines (1,$ means "first through last")
Hello, world!
This is my file.
:w hello.txt Write buffer to file named "hello.txt"
34 Editor confirms: 34 bytes written
:q Quit the editor
That is a complete editing session. You entered text, viewed it, saved it, and exited. Everything else in this manual builds on these four operations.
The Essential Commands
| Command | What It Does | Example |
|---|---|---|
a |
Append text after current line | Type content, end with . alone |
1,$p |
Print all lines | See your entire file |
w name |
Write (save) to filename | w letter.txt |
q |
Quit | Exit the editor |
The Mental Model
Ed does not show you the file continuously -- you must ask to see it. Think of it like editing a document through a mail slot: you can request specific lines, make changes, and slide new pages through, but you cannot see the whole stack at once. This feels strange at first, but it works reliably over any connection speed.
Description
ed is a modal editor operating in either command mode or input mode. In command mode, typed characters are interpreted as commands. In input mode, typed characters are entered into the text buffer.
Unlike screen editors that display the entire file, ed operates on one line at a time. This design was essential for use over slow teletype connections and remains the most reliable way to edit text over low-bandwidth modem links.
NOTE
ed uses minimal output by design. The default error message is simply ?. Use the h command after an error for a detailed explanation.
GETTING CONNECTED
To connect to the line editor service:
- Ensure your modem is properly configured (see system manual)
- Dial 555-0730 using the AT command set
- Wait for CONNECT message
- The editor starts with an empty buffer - no prompt is shown
CONNECTION EXAMPLE
CODE_FENCE_0
The colon (:) prompt indicates command mode.
Traditional ed shows no prompt at all — you simply type commands into the void and hope you are in the right mode. Our implementation displays a : prompt as a usability improvement. This tells you that you are in command mode and ready to accept commands. If you are used to classic ed's silent treatment, rest assured the commands work identically.
The editor starts with no file loaded — you must either create text with the a (append) command or load an existing file with e (edit).
ADDRESSING
Most commands accept zero, one, or two addresses. An address specifies which line(s) the command operates on. Addresses are specified before the command letter.
Address Forms
| Address | Description |
|---|---|
| n | Line number n (lines are numbered starting from 1) |
| . | Current line (the line most recently referenced) |
| $ | Last line in buffer |
| + | Next line (equivalent to .+1) |
| - | Previous line (equivalent to .-1) |
| +n | Current line plus n lines |
| -n | Current line minus n lines |
| /pattern/ | Next line containing pattern (wraps around) |
| ?pattern? | Previous line containing pattern (wraps backward) |
| 'x | Line marked with lowercase letter x |
Address Ranges
Two addresses separated by a comma specify a range of lines:
| Range | Description |
|---|---|
| 1,5 | Lines 1 through 5 |
| .,$ | Current line through end of buffer |
| 1,$ | Entire buffer (all lines) |
| , | Entire buffer (shorthand for 1,$) |
| ; | Like comma, but sets current line to first address |
ADDRESSING EXAMPLES
CODE_FENCE_0
COMMANDS
Commands consist of an optional address (or address range), followed by a single-letter command, optionally followed by command parameters. All commands are terminated by pressing RETURN.
Input Commands
| Command | Description |
|---|---|
| (.)a | Append - Enter input mode, adding text after addressed line |
| (.)i | Insert - Enter input mode, inserting text before addressed line |
| (.,.)c | Change - Delete addressed lines, then enter input mode |
INPUT MODE
After a, i, or c, enter text line by line. To exit input mode and return to command mode, type a single period (.) on a line by itself.
Display Commands
| Command | Description |
|---|---|
| (.,.)p | Print - Display addressed lines |
| (.,.)n | Number - Display addressed lines with line numbers |
| (.,.)l | List - Display lines showing non-printing characters |
| (.)= | Print line number of addressed line |
Editing Commands
| Command | Description |
|---|---|
| (.,.)d | Delete - Remove addressed lines from buffer |
| (.,.)j | Join - Combine addressed lines into single line |
| (.,.)m(n) | Move - Move addressed lines after line n |
| (.,.)t(n) | Transfer - Copy addressed lines after line n |
| (.,.)s/old/new/ | Substitute - Replace first old with new |
| (.,.)s/old/new/g | Substitute - Replace all occurrences (global) |
| (.)kx | Mark - Mark addressed line with letter x |
| u | Undo - Reverse last change |
File Commands
| Command | Description |
|---|---|
| e file | Edit - Load file into buffer (replaces current contents) |
| (.)r file | Read - Insert file contents after addressed line |
| (1,$)w file | Write - Save addressed lines to file |
| q | Quit - Exit editor (warns if buffer modified) |
| Q | Quit - Force quit, discarding changes |
Global Commands
| Command | Description |
|---|---|
| (1,$)g/pat/cmd | Global - Execute cmd on lines matching pat |
| (1,$)v/pat/cmd | V - Execute cmd on lines NOT matching pat |
Help Commands
| Command | Description |
|---|---|
| h | Help - Print explanation of last error |
| H | Help mode - Toggle verbose error messages |
REGULAR EXPRESSIONS
The s, g, v commands and /pattern/, ?pattern? addresses support regular expressions for pattern matching.
Basic Patterns
| Pattern | Matches |
|---|---|
| c | Literal character c |
| . | Any single character |
| ^ | Beginning of line |
| $ | End of line |
| [abc] | Any character in set |
| [^abc] | Any character NOT in set |
| [a-z] | Character range |
| * | Zero or more of preceding |
| + | One or more of preceding |
| ? | Zero or one of preceding |
| \ | Escape special character |
REGULAR EXPRESSION EXAMPLES
CODE_FENCE_0
COMMON EDITING TASKS
Before diving into detailed examples, here are quick recipes for tasks you will perform frequently:
"How do I see what is in my file?"
:1,$p Print entire file
:1,$n Print with line numbers (helpful for navigation)
:.p Print just the current line
:5,10p Print lines 5 through 10
"How do I find a specific line?"
:/error/ Jump to next line containing "error"
:?begin? Jump to previous line containing "begin"
:/TODO/p Find and print line containing "TODO"
"How do I fix a typo on line 7?"
:7p First, print line 7 to see it
:7s/teh/the/ Replace "teh" with "the" on line 7
:7p Print again to verify the fix
"How do I delete a line?"
:5d Delete line 5
:3,7d Delete lines 3 through 7
:/DEBUG/d Delete next line containing "DEBUG"
:g/^#/d Delete all lines starting with #
"How do I add text in the middle of a file?"
:5 Go to line 5
:a Append after current line (new text goes after line 5)
New text here
. End input mode
"I made a mistake! How do I undo it?"
:u Undo the last change (can repeat up to 100 times)
EXAMPLE SESSIONS
Creating a New File
SESSION 1: Create and save a file
CODE_FENCE_0
Editing an Existing File
SESSION 2: Edit an existing file
CODE_FENCE_0
Using Substitution
SESSION 3: Search and replace
CODE_FENCE_0
Using Marks and Movement
SESSION 4: Marks and block operations
CODE_FENCE_0
Global Commands
SESSION 5: Global operations
CODE_FENCE_0
COMMAND REFERENCE
Complete alphabetical listing of all commands:
| Cmd | Address | Args | Description |
|---|---|---|---|
| = | (.) | - | Print line number |
| a | (.) | - | Append text after line |
| c | (.,.) | - | Change (replace) lines |
| d | (.,.) | - | Delete lines |
| e | - | file | Edit file (load into buffer) |
| g | (1,$) | /re/cmd | Global - run cmd on matching lines |
| h | - | - | Help - explain last error |
| H | - | - | Toggle verbose error mode |
| i | (.) | - | Insert text before line |
| j | (.,.+1) | - | Join lines |
| k | (.) | x | Mark line with letter x |
| l | (.,.) | - | List lines (show special chars) |
| m | (.,.) | n | Move lines after line n |
| n | (.,.) | - | Number - print with line numbers |
| p | (.,.) | - | Print lines |
| q | - | - | Quit (warns if modified) |
| Q | - | - | Quit unconditionally |
| r | (.) | file | Read file after line |
| s | (.,.) | /re/rep/[gp] | Substitute pattern |
| t | (.,.) | n | Transfer (copy) lines after n |
| u | - | - | Undo last change |
| v | (1,$) | /re/cmd | Global inverse - non-matching |
| w | (1,$) | [file] | Write lines to file |
TIP
The address in parentheses shows the default if no address is given. (.) means current line, (.,.) means current line only, (1,$) means entire buffer.
SUBSTITUTION FLAGS
The substitute command s/pattern/replacement/ accepts optional flags:
| Flag | Description |
|---|---|
| g | Global - replace all occurrences on line, not just first |
| p | Print - display line after substitution |
SUBSTITUTION EXAMPLES
CODE_FENCE_0
DIAGNOSTICS
In keeping with UNIX tradition, ed reports all errors with the single character ?. This behavior can be modified:
| Command | Effect |
|---|---|
| h | Print explanation of last error message |
| H | Toggle automatic verbose error messages |
Common Error Conditions
- Invalid address (line number out of range)
- No file loaded when file operation expected
- Attempting to quit with unsaved changes
- Pattern not found in search
- Invalid regular expression syntax
- Invalid command syntax
WARNING
Attempting to quit (q) with unsaved modifications will print ? and a warning. Use Q to force quit, or w to save first.
NOTES
Input Mode
When in input mode (after a, i, or c), ed accepts text line by line. The only way to exit input mode is to type a line containing only a period (.).
Current Line
After most commands, the current line is set to the last line affected. Pressing RETURN alone advances to the next line and prints it.
File Persistence
Files saved with the w command persist across sessions. They are stored in your personal account space on the BBS.
Undo
The u command undoes the most recent buffer modification. Multiple undos are supported — up to 100 levels of undo history are maintained. This is a significant improvement over classic ed, which supported only a single undo.
If you make a mistake, type u immediately. You can keep typing u to undo multiple changes in sequence. This is your safety net — use it liberally.
Troubleshooting
Common Problems and Solutions
Problem: I type a command but nothing happens.
Solution: Make sure you press RETURN after each command. If you are in input mode (after a, i, or c), you must type a period (.) on a line by itself to return to command mode.
Problem: The editor prints ? and I do not know what went wrong.
Solution: Type h immediately after the error to see an explanation. Type H to enable verbose error messages for the rest of your session.
Problem: I cannot quit the editor.
Solution: If you have unsaved changes, ed will warn you with ?. Either save your work with w and then q, or use Q (capital Q) to quit without saving.
Problem: My search pattern is not finding anything.
Solution: Remember that searches wrap around: /pattern/ searches forward from the current line and wraps to the beginning. Check your spelling and remember that patterns are case-sensitive.
Problem: I deleted the wrong lines.
Solution: Type u immediately to undo your last change. Multiple undos are supported.
Quick Reference Card
+------------------------------------------------------------------+
| ED LINE EDITOR QUICK REFERENCE |
+------------------------------------------------------------------+
| ADDRESSES | COMMANDS |
| . current line | a append text after line |
| $ last line | i insert text before line |
| n line number | c change (replace) lines |
| +/- next/prev | d delete lines |
| /re/ search fwd | p print lines |
| ?re? search back | n print with line numbers |
| | s/old/new/ substitute |
| RANGES | w write to file |
| 1,5 lines 1-5 | e edit (load) file |
| 1,$ all lines | q quit (warns if unsaved) |
| , all lines | Q force quit |
| | u undo last change |
| INPUT MODE | h explain last error |
| Type . alone to | H toggle verbose errors |
| exit input mode | |
+------------------------------------------------------------------+
| EXAMPLES: |
| :a append text :1,$p print all |
| :3d delete line 3 :1,$s/a/b/g replace all a->b |
| :w file.txt save file :q quit |
+------------------------------------------------------------------+
Glossary
Address -- A way to specify which line or lines a command should operate on. Can be a line number, the current line (.), the last line ($), or a search pattern.
Buffer -- The temporary storage area where your text is held while editing. Changes to the buffer are not saved until you use the write (w) command.
Command Mode -- The default mode where typed characters are interpreted as editing commands rather than text input.
Current Line -- The line most recently affected by a command. Many commands default to operating on the current line.
Global Command -- A command (g or v) that executes another command on all lines matching (or not matching) a pattern.
Input Mode -- A mode entered by the a, i, or c commands where typed characters become part of the text buffer. Exit by typing a period alone on a line.
Line Editor -- An editor that operates on one line at a time, as opposed to a screen editor that displays multiple lines simultaneously.
Pattern -- A regular expression used to match text in searches and substitutions.
Range -- Two addresses separated by a comma, specifying a group of consecutive lines.
Regular Expression -- A notation for describing patterns of text. Used in searches and the substitute command.
Substitute -- The s command, which replaces text matching a pattern with new text.
See Also
Use the text editor alongside these other BBS services:
- SLP-BASIC (555-0300) -- Write BASIC programs, save them with ed
- Email System (555-0750) -- Compose messages offline, then paste into email
- File Manager (555-0603) -- Download text files, edit them locally
History
The ed editor first appeared in Version 1 AT&T UNIX (November 1971). It was written by Ken Thompson and is the ancestor of all subsequent UNIX editors including ex, vi, sed, and vim.
This implementation faithfully recreates the classic ed experience for the Emulator.ca Systems BBS, optimized for low-bandwidth modem connections.