In my oh-so-abundant free time, I’ve been working on my own little text editor. And one of my motivations is TECO: one of the oldest, and one of the very best, ever written. It’s both a text editor and a programming language – and, in fact, that’s exactly what made it such a brilliant tool. So much of the drudgery of programming is stuff that really could be done by a program. But we’ve spent so much time learning to be fancy that we’ve lost track of that. Nowadays, you can write an emacs lisp program to do the stuff you used to do in TECO; only it’s awkward enough that you usually don’t.
The problem, though, with just re-implementing TECO with a modern UI is that it was designed in a different time. When TECO was written, every byte was critical. And so the language, the syntax, the structure, it was completely ridiculous. And, as a result, it became the world’s most useful pathological programming language. It’s a glorious, hideous, wonderful, horrific piece of computing history
TECO is one of the most influential pieces of software ever written. If, by chance, you’ve ever heard of a little editor called “emacs”; well, that was originally a set of editor macros for TECO (EMACS = Editor MACroS). As a language, it’s both wonderful and awful. On the good side, The central concept of the language is wonderful: it’s a powerful language for processing text, which works by basically repeatedly finding text that matches some kind of pattern, taking some kind of action when it finds it, and then selecting the next pattern to look for. That’s a very natural, easy to understand way of writing programs to do text processing. On the bad side, it’s got the most god-awful hideous syntax ever imagined.
History
TECO deserves a discussion of its history – it’s history is basically the history of how programmers’ editors developed. This is a very short version of it, but it’s good enough for this post.
In the early days, PDP computers used a paper tape for entering programs. (Mainframes mostly used punched cards; minis like the PDPs used paper tape). The big problem with paper tape is that if there’s an error, you need to either create a whole new tape containing the correction, or carefully cut and splice the tape together with new segments to create a new tape (and splicing was very error prone).
This was bad. And so, TECO was born. TECO was the “Tape Editor and COrrector”. It was a turing complete programming language in which you could write programs to make your corrections. So you’d feed the TECO program in to the computer first, and then feed the original tape (with errors) into the machine; the TECO program would do the edits you specified, and then you’d feed the program to the compiler. It needed to be Turing complete, because you were writing a program to find the stuff that needed to be changed.
A language designed to live in the paper-tape world had to have some major constraints. First, paper tape is slow. Really slow. And punching tape is a miserable process. So you really wanted to keep things as short as possible. So the syntax of TECO is, to put it mildly, absolutely mind-boggling. Every character is a command. And I don’t mean “every punctuation character”, or “every letter”. Every character is a command. Letters, numbers, punctuation, line feeds, control characters… Everything.
But despite the utterly cryptic nature of it, it was good. It was very good. So when people started to use interactive teletypes (at 110 baud), they still wanted to use TECO. And so it evolved. But that basic tape-based syntax remained.
When screen-addressable terminals came along – vt52s and such – suddenly, you could write programs that used cursor control! The idea of a full-screen editor came along. Of course, TECO lovers wanted their full screen editor to be TECO. For Vaxes, one of the very first full screen editors was a version of TECO that displayed a screen full of text, and did commands as you typed them; and for commands that actually needed extra input (like search), it used a mode-line on the bottom of the screen (exactly the way that emacs does now).
Not too long after that, Richard Stallman and James Gosling wrote emacs – the editor macros for TECO. Originally, it was nothing but editor macros for TECO to make the full screen editor easier to use. But eventually, they rewrote it from scratch, to be Lisp based. And not long after that, TECO faded away, only to be remembered by a bunch of aging geeks. The syntax of TECO killed it; the simple fact is, if you have an alternative to the mind-boggling hideousness that is TECO syntax, you’re willing to put up with a less powerful language that you can actually read. So almost everyone would rather write their programs in Emacs lisp than in TECO, even if TECO was the better language.
The shame of TECO’s death is that it was actually a really nice programming language. To this day, I still come across things that I need to do that are better suited to TECO than to any modern day programming language that I know. The problem though, and the reason that it’s disappeared so thoroughly, is that the syntax of TECO is so mind-bogglingly awful that no one, not even someone as insane as I am, would try to write code in it when there are other options available.
A Taste of TECO Programming
Before jumping in in and explaining the basics of TECO in some detail, let’s take a quick look at a really simple TECO program. This program is absolutely remarkably clear and readable for TECO source. It even uses a trick to allow it to do comments. The things that look like comments are actually “goto” targets.
0uz ! clear repeat flag ! <j 0aua l ! load 1st char into register A ! <0aub ! load 1st char of next line into B ! qa-qb"g xa k -l ga-1uz ' ! if A>B, switch lines and set flag ! qbua ! load B into A ! l .-z;> ! loop back if another line in buffer ! qz;> ! repeat if a switch was made last pass !
The basic idea of TECO programming is pretty simple: search for something that matches some kind of pattern; perform some kind of edit operation on the location you found; and then choose new search to find the next thing to do.
The example program above is a rather sophisticated version of that for such a small program. It searches for the beginnings of consecutive lines. For each pair of lines, if they’re not in sorted order, it swaps them, and then searches for the next pair of lines. That’s enclosed in a loop which keeps repeated the scan through the file up until every consecutive pair is in order. In other words, it’s a swap-sort.
The fundamental (the only?) data structure in TECO is a buffer. All TECO programs are based on the idea that you’ve got a buffer full of text, and you want to do something to change it. The way that you access a buffer is through a cursor, which is a pointer into the buffer, which represents the position at which any edit operations will be performed. So TECO operations all work by either reading text at the cursor; editing text at the cursor; or moving the cursor. In TECO lingo, the position of the cursor is called dot. Dot is always between two characters.
TECO Commands
I can’t possibly explain all of TECO in one post, so I’m just going to go through enough to give you the flavor, and to make it possible to walk you through a sample program. If you want, you can go and see the full command list, or even read the TECO manual.
TECO commands are generally single characters. But there is some additional structure to allow arguments. There are two types of arguments: numeric arguments, and text arguments. Numeric arguments come before the command; text arguments come after the command. Numeric values used as arguments can be either literal numbers, commands that return numeric values, “.” (for the index of the buffer pointer), or numeric values joined by arithmetic operators like “+”, “-“, etc.
So, for example, the C
command moves the pointer forward one character. If it’s preceded by a numeric argument N, it will move forward N characters. The J
command jumps the pointer to a specific location in the buffer: the numeric argument is the offset from the beginning of the buffer to the location where the pointer should be placed.
String arguments come after the command. Each string argument can be delimited in one of two ways. By default, a string argument continues until it sees an Escape character, which marks the end of the string. Alternatively (and easier to read), if the command is prefixed by an “@” character, then the first character after the command will be used as a string delimiter, so that the string parameter will continue until the next instance of that character.
So, for example, the first thing that most TECO programs do is specify what it is that they want to edit – that is, what they want to read into the buffer. The command to do that is “ER”. It needs a string argument to tell it the name of the file to read – so the command to edit a file “foo.txt” is ERfoo.txt
(followed by pressing escape twice to tell TECO to run the command). Alternatively, you could use one of the other variations for string arguments. For example, you could quote the filename, using @ER'foo.txt'
. Or you could use quoting in a deliberately silly way: @ER foo.txt
. (That is, using space as the quote character, giving you nearly invisible quoting.)
In addition to the standard arguments, you can also modify commands, by placing a “:” in front of them. For most commands, “:” makes them return either a 0 (to indicate that the command failed), or a -1 (to indicate that the command succeeded). For others, the colon does something else. The only way to know is to know the command.
So, now that we know basically what commands and arguments look like, we can start looking at the commands that create the beast that was TECO.
There are, of course, a bunch of commands for printing out some part of the buffer. Remember, TECO originally comes from the pre-full-screen-editor days, so you needed to be able to ask it to show you what the text looked like after a sequence of edits, to make sure you had it right before you went and saved it. The basic print command is T
, which prints out the current line. To print a string, you’d use the command ^A (that is, control-A; I said everything is a command!).
This means that now, we can finally say how to write the good
old classic “Hello, World” program in TECO! It’s very simple:
@^A'Hello, World!'
That is, string argument quoted, print, followed by the quoted
string. Perfoctly clear, right?
There are also, naturally, commands to edit text in various ways:
D
- delete the character after the cursor.
FD
- Find-and-delete. Takes a string argument, finds the next occurrence of the string, and deletes it.
K
- Delete the text from the cursor to the end of the line.
HK
- Delete the entire current buffer.
I
- Insert text. Obviously, this needs a string argument, which is the text that it inserts.
<tab>
- A second insert command; the only difference is that the tab character is also inserted into the text.
Next are the commands for moving dot around in the buffer.
C
move the pointer forward one character if no argument is supplied; if it gets a numeric argument J
- jumps the pointer to a location specified by its numeric argument. If there is no location specified, it jumps to location 0.
J
can be preceeded by a “:
” to see if it succeeded. ZJ
- jumps to the position after the last character in the file.
-
L
- pretty much like
C
, except that it moves by lines instead of characters. -
R
- moves backwards one character – it’s basically the same as
C
with a negative argument. S
- searches for its argument string, and positions the cursor after the last character of the search string it found, or at position 0 if the string isn’t found.
number,numberFB
- searches for its argument string between the buffer positions specified by the numeric arguments. Search strings can include something almost like regular expressions, but with a much worse syntax. I don’t want to hurt your brain too much, so I won’t go into detail.
N
, it moves forwards N characters. C
can be preceeded by a “:
” to return a success value.
TECO has variables; in it’s own inimitable fashion, they’re not called variables; they’re called Q-registers. There are 36 global Q-registers, named “A” through “Z” and “0”-“9”. There are also 36 local Q-registers (local to a particular macro, aka subroutine), which have a “.”
character in front of their name.
Q-registers are used for two things. First, you can use them as variables: each Q-register stores a string and an integer. Second, any string stored in a Q-register can be used as a subroutine; in fact, that’s the only way to create a subroutine. The commands to work with Q-registers include:
nUq
-
n
is a numeric argument;q
is a register name. This stores the valuen
as the numeric value of the registerq
. m,nUq
- both
m
andn
are numeric arguments, andq
is a register name. This storesn
as the numeric value of registerq
, and then returnsm
as a parameter for the next command. n%q
- add the number
n
to the numeric value stored in registerq
. ^Uqstring
- Store the string as the string value of register
q
. :^Uqstring"
- Append the string parameter to the string value of register
q
. nXq
- clear the text value of register
q
, and copy the nextn
lines into its string value. m,nXq
- copy the character range from position
m
to positionn
into registerq
. .,.+nXq
- copy
n
characters following the current buffer pointer into registerq
. *Qq
- use the integer value of register
q
as the parameter to the next command. nQq
- use the ascii value of the
n
th character of registerq
as the parameter to the next command. :Qq
- use the length of the text stored in register
q
as the parameter to the next command. Gq
- copy the text contents of register
q
to the current location of the buffer pointer. Mq
- invoke the contents of register
q
as a subroutine.
And last, but definitely not least, there’s control flow. First, there are loops. A loop is “n<commands>
“, which executes the text between the left brack and the right bracket “n” times. Within the loop, “;” branches out of the loop if the last search command failed; “n;” exits the loop if the value of “n” is greater than or equal to zero. “:;” exits the loop if the last search succeeded. “F>” jumps to the loop close bracket (think C continue), “F<" jumps back to the beginning of the loop.
Conditionals are generally written n"Xthen-command-string|else-command-string'
. The quotes there are part of the command!) The double-quote character introduces the conditional, and the single-quote marks the end. In this command, the "X" is one of a list of conditional tests, which define how the numeric argument n
; is to be tested. Some possible values of X
include:
- “A”: tests if n is the character code for an alphabetic character.
- “D”: tests if n is the character code of a digit
- “E”: tests if n is zero or false
- “G”: tests if n is greater than zero
- “N”: tests if n is not equal to zero
- “L”: test if n is a numeric value meaning that the last command succeeded.
Example TECO Code
So, time for a couple of real TECO programs.
Let’s start by looking back at the swapsort program up at the top of this
post.
0uz
: set the Q-register z to 0.<j
: start a loop, and set dot to the beginning of the
file.-
0aua
read the character at the beginning of the line, and pass it as a numeric argument toua
, which updates the value of register a. So register a contains the first character of the line. -
l
: advance by one line. -
<0aub
: start a new loop, and assign the first character of the new line to register b. -
qa-qb"g
: subtract the value of register b from register a. If the result is greater than 0, then do the following:-
xa
: load the current line (the second of these two consecutive lines) into register A. -
k
: delete this line. -
-l
: move back one line. -
ga
: insert the contents of a (what used to be the later line) into the line. So now, we used to have … L1 L2 …; we’ve deleted L2, giving us … L1 …, and now we’ve jumped the cursor back to before L1, and inserted, so we’ve got … L2 L1 … – so we’ve swapped the two lines. -
-1uz
: set register z to -1. This is just setting a flag saying “I did a swap”. -
'
: end of the conditional.
-
qbua
: put what was in register b into register a.l .-z;>
: if there are any more lines in the buffer, then go to the beginning of the (inner) loop.qz;>
: if the z flag is non-zero, ther repeat the outer loop.
Gosh, wasn’t that simple? All kidding aside, it really is. Once you get used to the idea of editing a text buffer, it’s really very natural. It’s damned near impossible to read… but it’s not at all bad, semantically.
So now you should be ready for something that’s a bit less clearly written. No one wrote code like that example, with all of that documentation! This is an example of what real, working TECO code looked like. It’s a really useful program: it scans through a file containing a mixture of spaces and tabs, and replaces all of the tabs, assuming that tab stops appear every 8 columns.
FEB :XF27: F H M Y<:N ;'.U 0L.UAQB-QAUC<QC-9"L1;'-8%C>9-QCUD S DQD<I >>EX
That’s perfectly clear now, isn’t it?
Ok, since that was so easy, how about something challenging?
This little baby takes a buffer, and executes its contents as a BrainFuck program. Yes, it’s a BrainFuck interpreter in TECO!
@^UB#@S/{^EQQ,/#@^UC#@S/,^EQQ}/@-1S/{/#@^UR#.U1ZJQZ^SC.,.+-^SXQ-^SDQ1J# @^U9/[]-+<>.,/<@:-FD/^N^EG9/;>J30000<0@I//>ZJZUL30000J0U10U20U30U60U7 @^U4/[]/@^U5#<@:S/^EG4/U7Q7; -AU3(Q3-91)"=%1|Q1"=.U6ZJ@i/{/Q2@i/,/Q6@i/} /Q6J0;'-1%1'>#<@:S/[/UT.U210^T13^TQT;QT"NM5Q2J'>0UP30000J.US.UI <(0A-43)"=QPJ0AUTDQT+1@I//QIJ@O/end/'(0A-45)"=QPJ0AUTDQT-1@I/ /QIJ@O/end/'(0A-60)"=QP-1UP@O/end/'(0A-62)"=QP+1UP@O/end/'(0A-46)"=-.+QPA ^T(-.+QPA-10)"=13^T'@O/end/'(0A-44)"=^TUT8^TQPJDQT@I//QIJ@O/end/'(0A-91) "=-.+QPA"=QI+1UZQLJMRMB -1J.UI'@O /end/'(0A-93)"=-.+QPA"NQI+1UZQLJMRMC-1J.UI'@O/end/' !end!QI+1UI(.-Z)"=.=@^a/END/^c^c'C>
If you’re actually insane enough to want to try this masochistic monstrosity, you can get a TECO interpreter, with documentation and example programs, from here.
Holy fuckenoloy!
Do not disrespect the sacred TECO. TECO made me a lot of money in the early 80’s. Emacs still has me be more productive today than any other text editor.
🙂
I’m not disrespecting it! I think that TECO is one of the most important computer programs ever written. I believe that it shaped the entire history of software development tools. It’s terribly ugly looked at with today’s aesthetics, but back in its day, it was absolutely brilliant, a true gem. And even with all of the horrors of its syntax, it’s still a fantastic tool – better at what it does than most of the tools we’re using today.
TECO reminds me of Refal ( http://en.wikipedia.org/wiki/Refal ) which is also based on recursive text substitution.
How about sed? Seems a bit in the same spirit, but more readable.
I believe that sed is *vastly* less powerful. Sed is strictly line/stream based; TECO could shuttle forwards and backwards around your buffer. Sed is also not turing compete.
That’s not to say that Sed isn’t an incredibly useful tool. It’s just much more limited that TECO.
sed is Turing complete, and you can jump around in the file if you want to.
I just found this Turing machine simulator in sed: http://en.literateprograms.org/Turing_machine_simulator_%28Sed%29
And the code for another one: http://sed.sourceforge.net/local/scripts/turing.sed.html
Of course, it also rather lays to rest any claims that sed is more readable than TECO…
You bring back both fond and disturbing memories. I remember moving to teco from ‘ed’ and how much of a step forward it was.
It’s beautiful. Also, crazy.
Wow. Why didn’t they teach us this kind of history in computer science classes? That’s awesome. And frightening.
Also, my mind is officially blown – earlier today I was starting to work on the Project Euler problems, and looked at the stats for what languages people use – and there at the bottom was TECO. I’m astounded if anyone actually was able to do some of that math with this thing …
Also, are you going to give us an update on your text editor? I’m curious what a modern version of this would look like – or are you just taking inspiration from the “editor as language” concept?
I’ll write some more about the editor at some point.
The actual motivation is more sam/acme, the two plan9 editors. They both have a notion of structural regular expressions and actions as a primary editor construct – which are, effectively, a programming language for editing text. The problem with both of them is that the UIs are absolutely ghastly.
But once I started working on it, the TECO stuff kept coming back to me. So I’m basically building a simple language based on structural regular expressions, and turning it into the back-end of an editing tool.
The front-end will just be a GUI shell – very much like samterm. All that the UI will really do is translate your UI actions into commands that get piped to the interpreter. And you’ll be able to also enter commands directly in the editor, very much the way that you can in Sam.
I’m planning on eventually having multiple front-ends. The current prototype is wxWidgets, but I’d like to implement something that can live in a browser (looking towards the day when I get a ChromeOS netbook), and perhaps eventually do something tiled like Acme.
Ok, so that officially makes me an aging geek then. I used TECO on a DECsystem10 when I needed a way to edit ALGOL code on a teletype. Luckily I don’t remember any of the syntax.
My exposure to TECO was through a legend where “edit” somehow selected everything in the buffer, deleted it and inserted the letter ‘t’, the moral being modal editors were not so cool. I don’t really know if it is true but thanks for writing this up. I think I will give TECO a try 😉
‘course you can do the same thing even faster in Notepad: ^At.
This makes me long for my days of writing a hello world program in malbolge.
Back in college (76-80), Teco was a source of beer money; way too few of my classmates had mothers who made it clear to them that they wouldn’t type their papers in high school (I had too many college classmates who never had to write papers in high school, and I went to one of the most prestigious liberal arts colleges in the US). I think I typed at least one classmate’s paper on an ASR-33 (though VT-52s were much more common). Of course, TECO couldn’t actually format a paper; that was up to runoff. All this was done under RSTS-E on a PDP-11/40; yup, a 16-bit processor with a whopping 64K of memory was a real campus-wide timesharing system back in the Good Old Days.
TECO – my favorite program. I port it everywhere. i got the source for visual TECO 20 years ago and I’ve ported it to every machine and operating system I’ve worked on. It does so many things that nothing else can do – like editing binary files. Data General had a version called SPEED for the nove and eclipse machines..
This brought back some happy memories: the first serious computer I had access to was a PDP-10, and TECO was the editor of choice.
In those days, we had a simple test to distinguish the TECO gurus from mere mortals. A guru was someone who could explain how TECO would react when given their full name as input.
In Gentoo:
app-editors/teco
Latest version available: 1.00-r3
Latest version installed: [ Not Installed ]
Size of files: 210 kB
Homepage: http://www.ibiblio.org/pub/linux/apps/editors/tty/ http://w
ww.ibiblio.org/pub/academic/computer-science/history/pdp-11/teco
Description: Classic TECO editor, Predecessor to EMACS
License: freedist
I’m emerging it now. Interesting, although I’m not sure what things it can do that emacs can’t. Does explain the pervasive buffer and point system, tho.
It’s not that it can do anything that emacs can’t. Elisp is turing complete, so obviously, anything you could do in Teco, you can do in emacs. It’s just that in TECO, doing the edits by writing the program was the way that you edited, and that made some things much more natural.
In TECO, doing a search and replace where you’d find something that matched a pattern, tested it with some condition, extracted something from it, showed you the proposed replacement, and asked you to confirm whether you wanted to do it or not – that was actually something that was very natural. Going from “search and replace specific text” to “search and replace regex” to “search and replace regex with confirmation” to “search and replace regex with automatic test followed by confirmation” was a natural progression. In emacs, you can do the search and replace – M-%. And you can do search-and-replace-regexp, again with a keystroke (which I don’t remember). But there’s a *huge* difference between using M-% and writing an elisp program to do search-and-replace-with-test.
Ow ow ow ow! Was it truly necessary to subject us to such a detailed description of TECO?
Some of us have the good fortune to have been born into the age of visual editors. I thought you were discussing the details in order to then explain how your new editor makes a modern version of this… but no, you just end the article after describing the monstrosity. (which I’m sure may have been a pleasant reminder of days of yore for some…)
My sympathies to those who had to use such things, because that was the state of the art.
P.S. The worst editor I ever was subjected to on a regular basis was a modal editor under DOS called SEE which used the letter keys as commands, had one line of “help” text at the top to suggest commands. It reminds me in some ways of vi, but had nowhere the power or speed of vi. I either used a version before they added macro processing, or simply was never aware of how to use it due to a lack of a manual.
I happened to cut my teeth on VAXen, though I spent time in other editors, including the excellent TPU.
I recall the saying that one could not tell the difference between random transmission noise and a teco program.
I’d forgotten about TECO. It would be hard to convey to somebody raised on modern computers what a wonder it seemed when I first encountered it, after my previous experience in which the closest thing to an editor was a card punch machine.
Ahhhh, TECO, there’s a manual around here somewhere. I can’t bear to part with it. TECO gave me the feeling of power, I could make that PDP-10 do stuff for *me*, if I could only get it fed into TECO right.
Didn’t you all old geezers like me play the game of typing your name as a command and then seeing what was left? My real name starts with “D”, with disastrous results….
Brainfuck in TECO – that’s wild!
Ahh!!! After this post, I’m not sure I will ever try to read your blog again. 🙂
So I guess awk, with its pattern{action} paradigm was based, conceptually at least, on TECO.
gawk is my scripting language of choice.
This article made me nostalgic for Boeing’s cmedit… a character editing program that was available on the Cyber, PDP and VAX systems in the mid 1980s.
I could set up a batch cmedit program in the Cyber Star command file to change the data files so I could run multiple parameter studies (I set them to go sequentially as I left for home, and come in the next morning to several time series results being printed and plotted). One of my favorite moments was when a Computer Systems guy asked me why I didn’t use the new fangled (1985) editors on the VAX, and then with three key strokes ran a cmedit batch file to change several data sets. The look on his face was priceless (these days the same thing would be a macro script, which was not a concept then).
Wow, I feel very old now. Especially since I started out using punch cards (but not paper tape!).
Working with the registers reminds me a lot of the same in vi: 0aua would “ayl.
I guess it’s down to cross-pollination of the two in the times of ex?
After reading this I looked TECO up on wikipedia and eventually I found this:
http://en.wikipedia.org/wiki/LOLCODE
I must learn this now.
Please post an update on your text editor when it is complete. As far as text editors go, there are some good ones already, but the differences you envision would be wonderful.
If you can really create a legible, sensible update to TECO, and embed it in a plain text editor, I’d easily see it replacing my current one (generally TextWrangler for OS X).
I so appreciate this discussion … it makes me feel young! I got to use the newer tools (Scribe and emacs on a DEC 20) to prepare my Master’s Thesis. I was able to leave the paper tape and Hollerith cards (and JCL) behinds when I finished my BS.
There are two separate C ports of teco – the one you linked and the one available the Gentoo ports and MacPorts.
The latter appears to be somewhat more complete; e.g. it has a working split screen mode with a live view of the buffer.
Also: thank you for showing this. I can now use an editor twice as old as me.
I worked my way through college programming in the mid-70s and spent a fair amount of time on a DEC-10. What I remember most about TECO was that there was some useful combination of commands that was very close to HK (kill the buffer, and oh, by the way, it’s not undoable). This was fixed in a release sometime around 1975 by changing the commands to make it harder to lose all your work. The hell with Beatles on iTunes; THAT was a day I’ll remember forever!
TECO was clearly influenced by Expensive Typewriter (ET) which ran on the PDP-1 using Friden Flexowriters. It had a great syntax for editing, even if it does seem obscure today. Too many editors were line oriented, so it was hard to diddle text in the middle of the line without typing in a complicated substitution command or giving up and just retyping the whole damned line. I liked TECO syntax so much I borrowed it for a file system maintenance and repair package. It was trivial to write a short command to grovel through a chain of disk blocks resetting bad flags or looking for bad block pointers.
By the early 70s, TECO was quite baroque and had commands for everything. One command, control-R, entered real time screen editing mode and let you specify a buffer that assigned each possible input character to a specified substring (I think based on chunks of six characters because six characters fit in a PDP-10 word.) The first usable screen version of TECO was known as RMACS, if I remember correctly, but EMACS quickly evolved, and I still remember and use the keystrokes I learned in 1973. (Control-A and Control-E work in most Cocoa text entry fields on the Mac; wow, they work here in Firefox.)
Bernie Greenberg wrote the first Lisp based EMACS for the old Multics system. He was one of the more serious system kernel programmers, but you had to be a kernel programmer to write EMACS because Multics didn’t let anyone output a control-E which triggered automatic identification on an IBM 2741 terminal which could be used to defeat the time sharing CPU allocation algorithms by faking a user interaction. Since Bernie had access to the kernel code, he could send a control-E, so unlike others, he could send a command to move to the fifth line or fifth column on certain terminals.
Only later did Richard Stallman develop EMACS based on his own dialect of Lisp, though that programming language was basically compatible of Greenberg’s version. In many ways, TECO and Lisp are both good languages for providing a simple programming substrate for all sorts of applications because neither is particularly hard to parse. You don’t have to fire up YACC or Bison to deal with syntax. FORTH was another language with that characteristic, and FORTH survives as Postscript today.
You wrote “Vaxes” and Eric (above) wrote “VAXen” (which is what I remember). Were they both ok?
I remember the TRS-80 level 2 BASIC line-editor being TECO-inspired, at least for simple commands like i,k,x, optional prefixes, etc.
I think SNOBOL was probably the most powerful text-massager around…
And ICON…
Crack the beer! Pathological Programming is back!
(Add another plea for updates on the editor, Mark.)
Good article. Interesting that in 38 plus years, TECO is still handy. Although, I have to type it without thinking too much — its still in the fingers!
Hi! I’m interested whether you still work on your TECO implementation.
I also did one with the motivation of updating TECO with more recent text editing features like syntax highlighting, interactivity, GUI interfaces and so on.
This is what I came up with: http://rhaberkorn.github.io/sciteco/
The main paradigmatic difference is I think that while you try to separate the interactive command dispatcher (i.e. function keys/mouse events) from the TECO interpreter like sam/Acme, I tried to combine them by making the language itself interactive.
The result is useful enough I’m already using it day to day as my *standard* editor!
btw. I’m also the one who did the project Euler solutions in TECO a few years ago 🙂
I’m not really trying to build TECO – I’m doing a new language that’s motivated by my love of TECO. I think that it’s possible to build a cleaner, more legible, modern programming language that has many of the beautiful properties of teco.
My project has been sitting idle for quite a while – I was too busy to give it much attention. But in the last few weeks, I’ve actually been working on bringing it back to life.
I’m definitely going to check out what you’ve done – it sounds very exciting. Using a visual TECO again would be glorious.