Skip to content

Why your terminal still thinks it's a typewriter

Published: at 07:21 PM

Terminal Typewriter

I’ve been spending a lot of time in the terminal lately. I really like that I can leave my hands on the keyboard and not constantly have to switch over to using the mouse. Terminal applications are super easy to build and maintain and people who use these applications quickly get very fast at navigating around them.

Obviously then, I started building a few of my own TUI applications. As an initial experiment, I figured I’d try to build a text editor for the terminal, inspired by VS Code. I was excited and work progressed quickly… then I started bumping into some really weird stuff.

Why does Ctrl + G beep? Why can’t my (very fancy programmable) keyboard send Shift + Enter cleanly to a terminal app? Why on earth would someone use hjkl instead of arrow keys? And what the heck does TTY even stand for?

It turns out there’s a 150-year story behind all of this. Once you’ve heard it, things are no less weird, but at least they make sense.

Table of contents

Open Table of contents

It started with crazy stock prices… 📈

In the late 1860s, stock prices moved fast, and the only way to get them out of the exchange was to send a runner, or have a skilled telegraph operator on each end translating Morse by hand. To solve this problem, folks like Edison came up with the stock ticker. This central transmitter on the exchange floor sent electrical pulses down a wire. Those pulses spun a little wheel inside a remote machine, and the wheel stamped letters and numbers straight onto a strip of paper. No operator needed at the other end - the machine itself did the decoding.

Essentially, they had a stream of text running down a single circuit, one character at a time, asynchronously. 🤔

By the 1920s, Teletype Corporation had turned this into a fully fledged global network called Telex - basically automated typewriters yelling at each other over telegraph lines. To keep bandwidth low they used Baudot code, which was 5 bits per character. 5 bits gives you 32 combinations, which is not enough for both letters and numbers, so the machines had a physical hardware hack called Figures Shift / Letters Shift that mechanically flipped the machine into “numbers and punctuation mode”.

ASCII and the birth of CTRL 🔡

Fast forward to the 1960s. Early computers were moving away from batch processing (where you handed a stack of punch cards to an operator and came back the next day). Researchers were inventing time-sharing, allowing multiple people to interact with a computer at the same time. But computers didn’t have monitors yet - monitors were still expensive, experimental radar tech. Teletypes, on the other hand, were already widely used.

One problem with Teletypes was that they still spoke the old 5-bit Baudot code used by the Telex telegram network but the computing and telecom industries desperately needed a standard, larger character set.

In 1963, two massive things happened simultaneously:

  1. The American Standards Association published ASCII.
  2. The Teletype Corporation commercially released the Teletype Model 33 as the flagship device for this new ASCII protocol.

ASCII bumped the wire signal up to 7 bits allowing for 128 combinations, divided into two parts.

Control characters don’t get printed - instead they’re instructions to the machine itself - remember we’re talking about a protocol that is designed to remotely control a typewriter. Control characters do things like “ring the bell”, “feed the paper up a line”, “slam the carriage back to the left margin”. The 7-bit ASCII signal carries both your text and the commands to drive the printer hardware down the same wire.

The Teletype Model 33 included a CTRL key for this purpose. Holding CTRL while pressing a letter would mask off the high bits of that letter’s ASCII code. Hit Ctrl + G and you’d strip the bits of G (decimal 71) down to decimal 7 - which is the BEL control character. Decimal 7 was wired up to a literal brass bell inside the machine. You pressed Ctrl + G and a physical bell went ding 🔔… weirdly enough, this still works inside the terminal on a MacBook Pro today (try typing CTRL + G in your terminal and enjoy the music)!

Many of the terminal keyboard shortcuts today stem from the design of the hugely influential model 33 (you can see the control characters printed above the letters on various keys):

Terminal Typewriter

ShortcutOriginally
Ctrl + SPause the paper feeder so it didn’t physically jam (X-OFF)
Ctrl + QResume the paper feeder (X-ON)
Ctrl + CRepurposed by OS designers as “emergency brake on the CPU”
\n and \rAdvance the paper and slam the carriage back

So the next time you press Ctrl + S and your terminal freezes, you can blame paper feed jams from the 60s (then press Ctrl + Q to resume).

Glass teletypes 📺

By the late 70s, CRT monitors were cheap enough to replace the paper roll. The DEC VT100 (1978) was the definitive “glass teletype” - same serial wire going in, but instead of hammering ink, a microprocessor painted pixels on a screen.

The VT100 wasn’t a typewriter and it needed to be able to do some things that typewriters didn’t. There was no room in the ASCII codes to add extra instructions. So instead they used the Escape byte (0x1B which you probably would have seen printed out as ^[ on your terminal at some point) to introduce ANSI Escape Sequences - strings like ^[[2J to clear the screen, or ^[[31m to switch to red text.

These VT100 escape sequences are still present in virtually every terminal emulator in use today. iTerm2, GNOME Terminal, Windows Terminal, Apple Terminal, Alacritty - they’re all emulating a piece of hardware from 1978… kinda like an electric car that will also run on coal for backward compatibility.

PTYs: lipstick on a teletype 💄

Once hardware terminals died off, operating systems invented PTYs (pseudo-teletypes) - a software shim whose entire job is to lie convincingly to old command-line software, making it believe it’s still talking to a mechanical typewriter over a serial wire… so that software will continue to run correctly.

Every time you open iTerm2 or Windows Terminal, a PTY spins up so that bash or zsh can happily keep speaking the 1960s teletype protocol. The terminal emulator parses the ASCII + VT100 stream on the other end and draws coloured rectangles on your fancy retina display.

This works! But it has consequences:

The renaissance 😺

The good news is that people have finally started building stuff that breaks out of the 7-bit prison. In 2021 the terminal emulator Kitty introduced a progressive enhancement protocol. A modern TUI app sends a query at startup. If the terminal is modern enough, it responds and the two sides agree to drop the teletype caveman speech and use a richer encoding instead.

If your terminal supports the Kitty protocol and you’re using a modern terminal app that can take advantage of it, lots of the constraints of ASCII and VT100 drop away:

Modern terminals like iTerm2, Alacritty, WezTerm, foot, Ghostty have all picked up the protocol, so if you’re building TUIs then this is the way!

Wrapping up

So it turns out the reason terminals are weird isn’t because terminal emulator designers are weird (well… not only that 🤓). It’s because even modern terminals are still dragged down by 150 years of oddly annoying constraints.

Knowing this doesn’t fix any of it, but it does make it easier to come to terms with and stuff like Kitty’s keyboard protocol offers a bit of light at the end of the tunnel.

With luck, one day, we’ll eventually be able to stop using our computers as though we’re still typing on 1920s typewriters.

If you want to be part of the cleanup: build your next dev tool as a TUI targeting the Kitty protocol, and use a terminal emulator that supports it.

The glass teletype is dead! Long live the glass teletype 🪦.