Ah-hem. I meant to say Death to monospace and the TTY layer.
—Who radicalised you?
—The 70s, man.
This article primarily serves as an overview, for those who are similarly inclined.
Preface
First, I assert that monospace (fixed-pitch) fonts are hard and unpleasant to read, and that for decades now there has been no good reason to keep inflicting this relic on users. Even if these users are mostly developers. Developers are people and deserve humane treatment.
Further, I assert that terminal emulators—which use these monospace fonts—have grown into an absurd joke regardless, and should have largely disappeared a long time ago—if only we weren’t both completely incompetent as an industry and apathetic as people.
I’m not going to bother supporting these assertions here. If you agree, you agree.[1]
Illustrated
I can push the point across more simply. These are the same thing, only minimally iterated upon:
The Teletype Model 33 on the left is from 1963. 60+-year-old technology, in heavy use today, due to getting ossified within UNIX and its derivatives. The fixed character grid is a purely technical limitation carried over.
Meanwhile, here is a research computer from 1973. 50+ years old. Fully graphical. You can reprogram the environment from within itself in real time.[2] Its main problem was cost.
NeXT, Inc. later decided to combine the two concepts—UNIX and Smalltalk—into what’s now called macOS. It’s an automobile towing a horse.[3]
And to Hell with ASCII too
We take ASCII for granted, but we’re stuck with some extremely weird basic glyphs and key meanings for the rest of computing history. For example, the underscore (_) is there purely for formatting, the backtick (`) purely for diacritics (it has no stand-alone sense, yet it’s now an important spacing character), and the hyphen-minus (-) doesn’t know what it is. The backslash (\) is a bizarre invention for approximating ∧ ∨ as /\ \/, funnily shown as ¥ or ₩ in Japanese or Korean Windows instead.[4]
Strong typewriter legacy. Admittedly, the diacritics set ("',^`~) is useful for the compose key mechanism, even if you don’t use a teletype. I need neither a German keyboard layout, nor a Unicode selector to add a few umlauts.[5]
Also see: Sir, Please Step Away from the ASR-33!
A sigh
I deeply enjoy good typography. I like graphical user interfaces. Yet I punished myself with years of terminal-heavy Linux usage. At the same time, GNOME kept pulling the rug out from under me and made the GUI parts of the system unbearable.[6]
Enough is enough, and I’m on my way to figuring this out.
Proportional history
Places where variable pitch was used in programming contexts. The general observation is that we gave up on modernity in the 90s.[7]
Editors, environments
It largely points towards Xerox PARC (which strongly influenced 1. Steve Jobs; 2. Niklaus Wirth, who then influenced Rob Pike[8]).
-
~1973 Smalltalk (on the aforementioned research computer, see the screenshot above; today, it lives on in Squeak, Cuis, Pharo [traitor]).
-
~1974 The Alto actually let you program in the first WYSIWYG editor ever, Bravo.[9]
-
~1980s Interlisp-D, and certainly its Medley Interlisp version (in the Exec REPL) combined fixed pitch with variable pitch, though not to any greater extent.
-
~1982 The Cedar programming environment lets you put pictures in source code.
-
~1984 MacPascal, ~1986 Lightspeed/THINK Pascal
-
~1987 Oberon System
-
~1994 Oberon/F, open sourced as BlackBox Component Builder
-
~1994 Plan 9’s Acme editor defaults to proportional fonts. Rob Pike explains why. This is from someone who had seen a Teletype in person. Sadly, his prediction didn’t come true:
Fixed-pitch will soon follow in the footsteps of CAPITAL LETTERS AND PUNCHED CARDS.
-
1998 Serial Experiments Lain is fictional but I can’t leave it out.
-
~2011 Lamdu is an experimental AST-based editor.
I wish I could find more. Alas.
Intermezzo: Unusual shells
-
~1986 MPW Shell lets you use the Enter key to execute lines in the middle of a buffer. Otherwise it uses fixed pitch.
-
~1992 Plan 9 from Bell Labs in general. Shell transcripts can be freely edited, as if they were one big text file. This works by treating only text after the ‘output point’—which gets reset to the end of each shell prompt—as pending shell input to be sent on Return. All editing is handled by the window system. (A concept first used on the Blit. Skeptics could argue that this is a step from terminals back towards teletypes, where you could edit the printout with a pen and scissors. Only this time, the teletype knows OCR.)
rio/rc/mc can align command output to columns in a proportional font, through what I consider a hack, though that’s not the default look of the system.
These also qualify, in their own way:
-
A Minimalist Global User Interface (a 1991 paper) is about Help, the predecessor of Acme.
-
Acme: A User Interface for Programmers (a 1994 paper) explains Acme in detail.
It is a great shame that my brain is hardwired for Vim’s modal navigation, and I can’t stand coarse bitmap fonts. Though you can always make new derivatives of older stuff.
Books
-
Report on the Algorithmic Language ALGOL 60 (1960, revised)
-
Smalltalk-80: The Interactive Programming Environment, Mesa Language Manual, and other books related to Xerox PARC.
-
Algorithms + Data Structures = Programs by Niklaus Wirth (1976, revised), Project Oberon: The Design of an Operating System, a Compiler, and a Computer (1992, revised), and other books of the same provenance.
-
The C++ Programming Language, 3rd edition by Bjarne Stroustrup (1997) explicitly argues for proportional-width fonts in 1.1.1. This note disappeared in the 4th edition.
-
TeX: The Program (1986, with revisions approaching π) is the output of the program specified in the document itself. This also-book goes one step further than the rest, because it uses ligatures in code.
-
Pseudocode in papers is typically given in variable pitch.
Problems of variable pitch in programming
The primary problem is that we put pre-typeset code and markup in source files, following semi-arbitrary, often locally invented standards. The formatting should instead happen automatically, and tabs vs spaces should not be a question.
Line length limits
The magic number of 80 originated in punched cards, although that’s not important.
-
If you try to use classic character-based wrapping, hoping for the best, you will get odd results. First, compared to fixed-pitch, variable-pitch fonts have much wider capitals: shouting is more effective. Second, any bold text is usually much wider as well: font weight jumps of syntax highlighting become more jarring than usual.[10]
Variable-pitch-based wrapping produces different results for every font. The only reliable solution is, therefore, dynamic line wrapping in the editor. The wrapping should be syntax-aware, just like automatic formatters—prefix-marked comments are particularly troublesome, as they need to invent characters.
-
You can’t use the wrap guide/right margin functionality of editors anymore, at least not in a meaningful way. Perhaps in the sense of CSS max-width.
-
If you only use soft wrapping, line-based diffs may become noisier. git’s --word-diff option somewhat alleviates this.
Alignment
-
You want to use tabs for indentation as well as alignment. The common two-space indent in particular is normally extremely thin, unless you hack around this in the font. Space alignment will never match.
Automatic formatters like gofmt or clang-format can’t deal with a tab-only style, unless you patch them (which has recently been made cheap with LLMs).
If the spaces must remain in files, you can create an automatic filter that converts files on opening and saving.
Fonts
-
A large subset of variable-pitch fonts doesn’t particularly care about legibility, i.e., ‘I’ and ‘l’, or ‘O’ and ‘0’ looking like different characters. This can often be toggled using OpenType font features, which are not exactly user-friendly: first you need to know which features the font has and what they do, then either 1. toggle them in your editor, if at all possible; 2. force them at the system level (Fontconfig rules can do that); or 3. hardcode them in font files using the OpenType Feature Freezer.
Miscellaneous
-
Thin characters can be difficult to hit precisely with a mouse.
-
If you like to separate sections of code with horizontal lines, you’re in a tough place. Emacs sets a precedent by using ^L form feed characters for this purpose. These can be rendered prettily: in fact, its form-feed and page-break-lines packages do exactly that. A modern alternative approach is adding an extremely wide
// ---ligature to fonts. That will survive autoformatters. -
In general, ‘ASCII art’ stops being an option. Elastic tabstops can still solve simple left-aligned tables.
Meta-problem: other people
-
On style mismatch, one group will get the short end of the stick. It may help to create an automatic filter that converts files on the fly, as mentioned before.
Solutions
-
Elastic tabstops (also see): simple, occasionally supported by things, not necessarily well.
-
They don’t solve asterisk alignment in C, though that’s a minor issue.
-
-
Syntax-aware dynamic wrapping: I’m not aware of any meaningful implementation. It’s up for further research. That said, many editors can at least make soft wrapping follow indentation, which may be good enough.
-
Headings in Markdown/AsciiDoc: If you use Setext-style underlined headings, switch to the ATX-style prefixed ones. Once you find or make a document editor with live markup preview, the latter becomes superior.
Situation as of today
With the assumption that you want to keep on using major operating systems, and popular programming or markup languages.
Editors
Say goodbye to Vim—gVim doesn’t know what to do with proportional fonts. Luckily, many programming editors and IDEs with decent Vim emulation handle them just fine:
-
Qt Creator has FakeVim integrated.
-
Visual Studio Code has a VSCodeVim extension.
-
Zed has a Vim mode integrated.
-
JetBrains IDEs have an IdeaVim plugin.
-
Kate has vi-mode integrated.
-
Emacs has variable-pitch-mode and evil-mode. tabble-mode implements elastic tabstops.
Fonts
-
Go sans-serif is a good start, though semi-abandoned, and perhaps not too nice to read. I like it for notes, not code.[11]
-
Lisnoti Code has pretty ligatures, plus other programming-relevant features.
-
Atkinson Hyperlegible Next
-
Iosevka Etoile and Input Sans are no improvement over monospace. Why bother?
-
Iosevka Aile and other fonts need font features toggled for good legibility.
-
Recursive is interesting: 1. it doesn’t change in width with weight, which works out fine; 2. it can be set to any point between ‘sans’ and ‘mono’. Though once it’s closer to the latter, it adds serifs, skewing scientific measurements.
Programming language
As an aside, the Go programming language is notably well suited to editing in something like the Acme editor, used by at least Rob Pike and Russ Cox:
-
It standardises tab character indentation.
-
The suggestion to use semantic linefeeds has different reasoning behind it but works in our favour.
-
If you take a moment to notice, Go reads very well without syntax highlighting. You can’t say this about that many languages.
It still has gofmt’s space alignment problem but making an appropriate filter program to adjust sources on load is made easy: the go/printer package may only need RawFormat toggled. It’s elastic tabstops from there.
Terminals
If you don’t feel like using Plan 9 or plan9port, you’re basically out of luck if you’re looking for something comprehensive. Too much of our current systems depends on the old ways, in one way or another—including basic programs like cal, ls, wc, or command line shells. You ideally want a separate REPL.
These are misguided or useless:
-
mlterm and spft may be the only real *nix terminal emulators supporting proportional fonts. The latter even does elastic tabstops. But the rest of your system keeps assuming a regular cell grid.
-
Various attempts at combining *nix terminals with a web browser, or similar. Examples: TermKit, DomTerm.
If it’s important to be able to run software remotely in a terminal, as well as locally in a way that doesn’t make your eyes bleed, you can use a hybrid model. At least that’s what I did with my terminal/X11/AppKit MPD client and terminal/X11 IRC client frontend. It’s a compromise, mind you—the terminal will constrain you severely. Also, Wayland is a pain, because it can’t draw for you. A cleaner solution would be to define a new terminal protocol that translates to either version, rather than to special case in the program. It gets harder the higher you aim.
Related
-
Programming fonts: proportional vs monospaced (Nick Gravgaard)
-
The case for proportional programming fonts (Martijn Storck)
-
Programming Deserves Better than Monospace (Victoria Lacroix)
-
Proportional fonts and yapf vs black (Nelson Minar)
-
Lisnoti – a proportional font that works for coding too (Tim Gordon)
-
My Transition from Fixed to Proportional Width Fonts for Editing Source Code (Ronald Weigelt)
About terminals and shells
-
The UNIX-HATERS Handbook: chapter 6 talks about additional problems with the implementation of teletypes on UNIX.
-
The Day of a new Command-Line Interface: Shell, which is also a good hypertext root.
1. It was revealed to me in front of a computer.
2. If you load Smalltalk, which was one of the first applications for the Alto.
3. This was at least to some extent recognised at its inception.
4. Yes, they will show C:₩Users₩Administrator.
5. At least Linux coöperates like that; one would be naïve to think macOS offers it as well. I miss this mainly with proper typographical characters, such as – — ‘ ’ “ ” ° ² ³ €.
6. I had a friendly and pretty system back in 2011. Then I suddenly didn’t.
7. Meanwhile, I personally reject a lot of ‘modernity’ within the realm of GUIs. This hypocrisy doesn’t escape me, though I have my reasons.
8. I asked: ‘Wirth was a friend I met through work and I visited him and ETH a number of times, and spent perhaps two weeks total there actually using their systems.’
9. It stored paragraph formatting after a ^Z character. Compilers skipped it, similarly to trailing comments.
10. Some people argue that making keywords bold, which dates back at least to the ALGOL 60 report from 1960, is stupid as well.
11. The font comes from the Lucida lineage, which was also used in Plan 9. It’s closer to the later Luxi family designed for XFree86. I find it very odd-looking. I can’t quite point out what’s so weird about it.





Comments
Use e-mail, webchat, or the form below. I'll also pick up on new HN, Lobsters, and Reddit posts.