The Best Way to Put Em Dashes in a Git Commit Message
“They” say that em dashes are a sign of AI writing. Well, “they” can pry my em dashes from my cold, dead fingers.
If you’ve read literally any other post on this blog before, you’ve probably noticed that I use em dashes a lot. Maybe too much. It’s something I’m working on.
And it’s not just on my blog: I use them when writing emails, social media posts, even text messages.1 The one place where I haven’t been using them — until recently — is Git commit messages; and let me tell you, it’s felt like the rhetorical equivalent of having one hand tied behind my back.
The problem with the em dash in this context is that commit messages are often written and read in a terminal window, and consequently rendered with a monospaced font. When every character is bound to a single fixed-width cell, an em dash is nearly indistinguishable from a hyphen. Compare:
monospace — that is, fixed-width
vs.
monospace—that is, fixed-width
Depending on the specific font your browser
chose2 to render the above
<code>
element, you may or may not be able to tell the
difference between the two marks; but I’ll bet it’s much
less apparent than with the proportional text above it. This lack of distinction
really hampers readability — it forces me to pause, just for
a fraction of a second, to make sense of it; it throws off the flow, like
traversing a staircase where two or three of the steps, entirely at random, are
a different height than the rest.
Lesser workarounds
So, what to do? One obvious solution is to put spaces on either side:
a — b
. This looks fine in the terminal, and is certainly much
more readable. But while commits are often read in a terminal, they
aren’t always: plenty of code editors,
software forges,
etc. render them with a proportional font, and surrounding a
proper em dash with full spaces (a — b) just isn’t right.
You could use spaces with an en dash instead: a –
b
. This looks better on the proportional side (a – b), and indeed
is standard
usage in the U.K. I really prefer a real em dash, though; and to me,
the monospaced en dash looks a bit anemic.
You could use either two hyphens with spaces, or three without: a --
b
, a---b
. These were established conventions for typewriters
and for pure-ASCII contexts, and they look all right even when typeset
proportionally (a -- b, a---b). They have the added benefit of being easier to
type, given that neither the en nor the em dash has a dedicated
key on most keyboards. If your viewing software interprets commit text as
Markdown, then they might even be automatically converted to real en and
em dashes, respectively.
But not every proportional-font commit viewer interprets them as Markdown, and not every implementation of Markdown performs those particular conversions. And, damn it, we’re not using typewriters or ASCII anymore; we’re using computers and Unicode and we should be able to have nice typography.
(If you couldn’t tell: for someone who isn’t a type designer, I care an awful lot about typography. Maybe too much. But that’s not something I’m working on, nor is it something I have any intention of working on, because the desktop publishing revolution started before I was born and I shouldn’t have to.)
Enter U+200A
, the hair space
It turns out that traditional (i.e., pre-digital) typography
used a whole range of spaces of various widths, from em and en
spaces on the wider end to “thin” and “hair” spaces on
the narrower end. It was common practice, though perhaps not universal, to place
hair spaces on either side of a dash for a cleaner look: compare an em
dash with hair spaces (a — b) vs. without
(a—b). It’s a subtle difference; but having learned of it, I
promptly inserted a pair of  
es around every
—
and –
in my site’s markup.
They’re also nice for clarifying nested quotations:
“ ‘a’ ” vs.
“‘a’”.
In a monospaced font, of course, a hair space is exactly the same width as a regular space. The following lines are exactly the same sequence of characters, set first with a proportional font and then with a monospaced one:
monospace — that is, fixed-width
vs.
monospace — that is, fixed-width
Ahhhhh. So much better.
Actually typing the dang thing
Of course, now we’ve gone from needing one character that’s not on the keyboard to needing three for every em dash we type. Linux has a… let’s call it convenient shortcut for entering arbitrary Unicode characters, provided you know the code point: press Ctrl+Shift+U, then type the four-digit code point, then press Space. Windows has something similar.
So, you could type an em dash and two hair spaces as follows: Ctrl+Shift+U, 2, 0, 0, A, Space, Ctrl+Shift+U, 2, 0, 1, 4, Space, Ctrl+Shift+U, 2, 0, 0, A, Space. But that would be, obviously, a massive pain.
(Well, okay, with enough practice it might not be that bad. But still, we can do better.)
Far more convenient — provided your editor supports it — is to configure a substitution.3 In my case, that editor is Vim; and the substitution looks like this:4
inoremap <Leader>md <Char-0x200a>—<Char-0x200a>
(Where, yes, I typed the dash itself with the whole
Ctrl+Shift+U thing. You could put
<Char-0x2014>
instead if you wanted, but I think this version
is more clear when re-reading my .vimrc
.)
My <Leader>
key is the default, \. So, while in
insert mode, as I’m typing, I can hit \, m,
d in quick succession to produce a nice space-dash-space sequence
with ease.
The really nice thing about this approach is that it translates well to other contexts:
augroup html
autocmd!
autocmd FileType html inoremap <buffer> <Leader>md  — 
" ... other HTML-specific substitutions ...
augroup END
I won’t go into detail about Vim autocommands in this
post — I’m pretty new to them
myself — but suffice it to say this makes it so that when
I’m editing an HTML file (e.g., this very blog post), the
exact same keystrokes, \, m, d, produce
 — 
instead of the literal
characters. Same convenience; same muscle memory; equivalent, context-specific
result.
Footnotes
That is, SMS/RCS. I am given to understand that the use of terms like “text message” or “texting” for these services is mostly a U.S. regionalism. ↩︎
I’m not overly concerned with the exact appearance of this website, so long as it looks close enough everywhere. So, rather than force you(r browser) to (silently) download web fonts — with the exception of Font Awesome for the icons on my About page, which dependency I mean to address one of these days — my current design lists a series of fallback fonts for each style, at least one of which is likely to be installed on each of the major platforms. ↩︎
Or, if not, you could look into system-wide “text expander” software, such as AutoHotkey. ↩︎
Aside from insert-mode mappings like this, Vim has another, separate as-you-type substitution feature called abbreviations. These are useful for things like automatically correcting common typos or expanding a handful of characters into a longer string. On the face of it, abbreviations seem like a more natural fit for this kind of typographical assistance; but Vim’s abbreviations are intentionally sensitive to word boundaries, including punctuation, in a way that makes them less suitable than I would have liked for inserting punctuation. ↩︎