Blog

Making Markdown tables line up in any terminal

A Markdown table is supposed to line up. In a terminal it often doesn't: put a column of , ⚠️ and next to each other and the box drifts a character at a time until the borders go ragged. editxr 1.6 fixes that — and the honest fix turned out to be to stop guessing.

│ Panic attack     │ ★ │ ⛔    │ Generate │
│ Fear             │ ✓ │ ⚠️   │ Partial  │   ← this row used to slip left
│ Loss of a pet    │ — │ ⛔    │ Generate │
One wrong guess in the status column, repeated down the table.

Why terminal tables drift

A terminal is a grid of fixed cells, and every glyph occupies a whole number of them — one column or two. To draw a border in the right place, the editor has to know that width for each character. ASCII is one, most CJK is two; those are easy. Emoji and symbols are where it falls apart.

(U+2605) and (U+2713) look like emoji but most terminals draw them narrow, one column. and take two. And ⚠️ depends on the terminal: Terminal.app draws it narrow, iTerm2 with "Unicode 9 widths" draws it wide — and that's a per-user setting. There is no static table of widths that is correct everywhere. Guess two columns for a glyph the terminal draws in one, repeat it down a status column, and every border below slides over by one.

Measure, don't guess

So editxr stopped guessing and started asking. On startup it prints each unusual glyph off-screen and sends the one question every terminal answers — ESC [ 6 n, "where is the cursor now?" — then reads back the column and takes the difference as the glyph's true width. Whatever your terminal and your settings actually do, editxr measures it and lays the table out to match.

It re-measures when you open a file that brings in symbols it hasn't seen, and when there's no terminal to ask — a pipe, a test, a silent terminal — it falls back to a sensible heuristic instead of hanging. Curious what your terminal does? editxr --probe-widths prints the measured width of each symbol next to the built-in guess.

And a smaller nicety: tables that agree with each other

Once each table lines up on its own, the next thing you notice is that two tables in the same document don't line up with each other. So editxr now pads every table out to the width of the widest one, so their borders run straight down the page. It's on by default; toggle "Align tables to widest" from the command palette (Ctrl+/) if you'd rather each table keep its natural width.

A sidebar came along too

The same release adds a docked left sidebar with two modes. Outline lists the document's headings and follows your cursor as you scroll — press Enter on one to jump there. Files is an explorer for the current directory. Tab moves focus into the panel, arrows (or j/k) move, Enter opens a file or jumps to a heading, and Esc hands focus back to the editor. Both modes live behind the palette.

Update and point it at a folder of notes.

brew install pixdeo/tap/editxr
View on GitHub