Down with monospace and the TTY layer

Ah-hem. I meant to say Death to monospace and the TTY layer.

—Who radicalised you?
—The 70s, man.

A messy overview, and ways to get there.

Contents

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.

Illustrated

I can push the point across more simply. These are the same thing, only minimally iterated upon:

Teletype Model 33    DEC VT100   macOS Terminal.app

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.[1] Its main problem was cost.

Xerox Alto   Smalltalk GUI

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.[2]

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 a 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.[3]

Strong typewriter legacy. Admittedly, the diacritics set ("',^`~) is useful for the compose key mechanism, even if you don’t use a teletype.

A sigh

I deeply enjoy good typography. I like graphical user interfaces. Yet I punished myself with years of terminal-heavy Linux usage, while GNOME kept pulling the rug out from under me and made the GUI parts of the system unbearable.

Enough is enough, it’s time to figure 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.[4]

Editors, environments

It largely points towards Xerox PARC (which influenced Niklaus Wirth, who then influenced Rob Pike[5]).

  • ~1973 Smalltalk (on the aforementioned research computer, see the screenshot above)

  • ~1974 The Alto actually let you program in the first WYSIWYG editor ever, Bravo.[6]

  • ~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

  • ~1993 AppleScript Script Editor

  • ~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.

    rio/rc/mc can align command output to columns in a proportional font, through what I consider a hack, though it’s not the default look of the system.

These also qualify, in their own way:

Books


Inherent problems

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 happen automatically, and tabs vs spaces should not be a question.

Line length limits

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. Second, any bold text is automatically much wider as well. Font weight jumps of syntax highlighting become more jarring than usual.[7]

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.

Alignment

You want to use tabs for indentation as well as alignment. The common two-space indent in particular is normally extremely thin. 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.

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.

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 you want, then either 1. toggle them in the 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.

Meta-problem: working with 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

  • 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.

  • 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.

A sample of appropriate fonts:

  • Go sans-serif is a good start, though perhaps not very nice to read, and semi-abandoned.

  • Lisnoti Code has pretty ligatures, and 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.

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.

  • Kate has vi-mode integrated.

  • Emacs has variable-pitch-mode and evil-mode. tabble-mode implements elastic tabstops.

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.

These are misguided or useless:

  • mlterm may be the only real *nix terminal emulator that supports proportional fonts. The rest of your system keeps assuming a regular cell grid, so it’s not particularly useful.

  • Various attempts at combining *nix terminals with a web browser, or similar. Examples: TermKit, DomTerm.


About terminals and shells


1. If you load Smalltalk, which was one of the first applications for the Alto.
2. This was at least to some extent recognised at its inception.
3. Yes, they will show C:₩Users₩Administrator.
4. Meanwhile, I personally reject a lot of ‘modernity’ within the realm of GUIs. This hypocrisy doesn’t escape me, though I have my reasons.
5. 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.’
6. It stored paragraph formatting after a ^Z character. Compilers skipped it, similarly to trailing comments.
7. Some people argue that making keywords bold, which dates back at least to the ALGOL 60 report from 1960, is stupid as well.

Comments

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