Neutering spellcheck on MacOS

Monday, June 10, 2024

Comments: (live)

Tagged: macos, apple, spellcheck

I hate the red squiggle underline.

I know many people love it and many people rely on it. It's become a software standard, and for good reason. But I, personally, find it distracting and unhelpful. I spell pretty gud! So I always turn the feature off.

The problem is, there's no system-wide way to turn off the red squiggle on MacOS.

You can turn it off on a per-app basis. It's usually a menu item called "Check Spelling While Typing". (Under "Edit / Spelling and Grammar". Sometimes you have to right-click in the text window to get that menu.) Many apps, like Slack, have a custom preference that does the same thing. So I turn it off for every app, and...

...the off switch doesn't always stay off.

For many apps it works great. Pages? Safari? Slack? BBEdit, where I'm typing this? No problem! Turn the preference off once, it stays off forever. (Or at least until I buy a new Mac, but that's once every several years.)

But for many apps, it just doesn't stick. I am very happy with Mona, the Mastodon client; but the "Check Spelling" preference resets on every single message you type. In the Zoom desktop client, it resets on every new call's chat pane. Even TextEdit, Apple's native text editor, loses track of the preference when I reopen a document. And then the red squiggles reappear.

For a while I had the "Check Spelling While Typing" menu item bound to a keystroke (cmd-opt-semicolon). So I could switch off the red squiggles in a given window with one power chord. Sadly, with recent versions of some apps (Mona, Zoom) this no longer works. Contextual menu items are no longer bindable with Mac's keyboard shortcut mechanism. (Not sure whether this is the fault of the apps, or SwiftUI, or MacOS. Doesn't matter though.)

So I've gotten pretty upset with the red squiggles. I'm not the only one.

If you search for the problem, you see a lot of people telling you how to turn off the "Correct Spelling Automatically" preference. (Example: this post.) That is a system-wide preference, and I turned it off years ago. But it's not the same thing. That preference is for auto-correction of spelling errors. I want to turn off the underlining of spelling errors.

Well, this week the problem got on my last nerve and I figured out a real and system-wide solution, which is abominable:

I created a spelling dictionary that accepts every English word as correct and told MacOS to use it exclusively.

Here it is!

How to install this (on MacOS)

Go to the release page, download "Source code (zip)", and double-click it to unpack.

Move abplus-dict.dic and abplus-dict.aff to your ~/Library/Spelling folder.

By default, the Library folder (in your home directory) is hidden. To get there, hold down the Option key while selecting "Finder > Go", and then select "Library". See this Apple docs page for more info.

Once you have installed abplus-dict.dic and abplus-dict.aff:

  • Open System Settings.
  • Select "Keyboard".
  • Press the "Edit..." button next to "Input Sources".
  • Open the dropdown menu for "Spelling". (It's set to "Automatic by Language" by default.)
  • Scroll all the way down to the bottom of the menu and select "Set Up..."
  • In the dialogue box, check "abplus-dict (Library)" and uncheck every other checkbox. (It refuses to uncheck every box; you have to leave at least one checked.)
  • Hit "Done".
  • Open the dropdown menu for "Spelling" again. Scroll down and select "abplus-dict (Library)". Not the "Set Up..." entry, but the one above it.
  • Hit "Done".
  • Quit System Settings.
  • Quit and restart any apps you have open to pick up the new spellcheck setting.

Congratulations. The "Check Spelling While Typing" setting is now irrelevant, because MacOS believes that every word is spelled correctly.

Other OSes

I have no idea. Windows has a system-wide preference that works (under "Settings > Time & Language > Typing") so I've never thought about replacing its dictionary.

The caveats

This should work for every Latin-script language. I've only tested it in English, though. And I've only been using it for a few days, so I might have missed some important cases. Suggestions welcome.

The dictionary includes all letters in the Basic Latin, Latin-1, and Latin Extended A/B blocks. (Up through U+024F.) I did not include Latin Extended Additional, IPA symbols, or other letter-like forms. So if you type "məssy" or "ḑḁḡḡḙṛ", that will still get a red squiggle.

I observe that Greek, Cyrillic, and other scripts do not get marked. (Even though I didn't include those letters.) I don't really understand MacOS's rules for when spellcheck is applied, but I guess that case works out non-squiggly.

Note that if you delete abplus-dict.dic and abplus-dict.aff from your ~/Library/Spelling folder, MacOS will silently revert to the default spellchecker.

I am abusing the heck out of the dictionary format, so it's possible that the spell-check process takes more memory or CPU than it's supposed to. It seems fine? I haven't noticed any problems? But I don't know.

How it works

The dictionary format is in theory documented here (neovim) and/or here (hunspell). I say "in theory" because neither is all that clearly written. I had to look at both, plus a bunch of examples (thank you wooorm!), plus some of the hunspell test cases, to sort out what I needed.

In the end I didn't need too much.

The abplus-dict.dic file lists every Latin-script character, all 450 of them, as one-letter words. Each of them has the s flag.

The abplus-dict.aff file defines the s flag:


This means that words with that flag can compound arbitrarily, even when they're only one letter long. Problem solved.

We also ignore apostrophes and dashes inside words:

IGNORE '_-–—“‘”’

The spellchecker wants to be fussy about the difference between they're and the'yre. This line tells it to not be. I'm not sure the other punctuation marks need to be listed, but it can't hurt.

Is this a good idea?

Don't ask me. If abplus-dict turns out to be the Speling Tormnent Nexis, I apologize.

Comments from Mastodon (live)

Please wait...