joelkuiper.eu

Spell checking in Emacs

Rationale

While some people might find spelling and grammar checking tools redundant and even annoying, they offer me tremendous value. English is not my mother tongue and I was diagnosed with dyslexia at the age of 12. But even when disregarding all that, everyone gets tired or distracted sometimes. And while I am not claiming that automated spell checking can mitigate these problems fully, they do help.

Unfortunately spell checking tools seem to be limited to word processors. And the only reasonable one I have ever encountered was the one of Microsoft Word, since it also does some rudimentary grammatical checking. It has false positives, sure, but you can safely ignore those and just be content with the true positives it offers.

Recently I have started doing most of my (academic) writing in Emacs org-mode (and moving to LaTeX when necessary). So the quest began for a decent spell checker.

ispell and flyspell

Emacs comes bundled with ispell.el and flyspell. ispell.el acts as a facade for popular command line spelling utilities, such as ispell, aspell and hunspell (more on that later).

Ispell is a fast screen-oriented spelling checker that displays errors in the context of the original file, and suggests possible corrections. Some of the salient features of ispell include its multilingual support and integration with emacs. Ispell contains direct support for files formatted using LaTeX and [nt]roff. The integration into emacs supports additional formats, including hypertext files.

By default ispell does not highlight misspelled words, but simply offers you a way of checking the entire buffer with M-x ispell-buffer. To get a more classical spell checker you can use flyspell. Flyspell, as the name suggests, checks your spelling on the fly.

You can enable flyspell for text files by putting this in your .emacs or equivalent:

(dolist (hook '(text-mode-hook))
  (add-hook hook (lambda () (flyspell-mode 1))))

It also comes with flyspell-prog-mode which is useful when programming since it only checks comments and strings. It has a fairly low signal-to-noise ration if left unconfigured, but it can be useful if you believe comments should be sentences. I have enabled it for most of my day-to-day tools:

(dolist (mode '(emacs-lisp-mode-hook
                inferior-lisp-mode-hook
                clojure-mode-hook
                python-mode-hook
                js-mode-hook
                R-mode-hook))
  (add-hook mode
            '(lambda ()
               (flyspell-prog-mode))))

You can also add some of the recommended shortcuts:

(global-set-key (kbd "<f8>") 'ispell-word)
(defun flyspell-check-next-highlighted-word ()
  "Custom function to spell check next highlighted word"
  (interactive)
  (flyspell-goto-next-error)
  (ispell-word))
(global-set-key (kbd "M-<f8>") 'flyspell-check-next-highlighted-word)

Which allows you to press <f8> to check a word and M-<f8> to check the next one

The last annoyance is that on Mac OS X the right mouse button does not seem to trigger [mouse-2], so you cannot right click a word to get a suggestion. This can be fixed with:

(eval-after-load "flyspell"
  '(progn
     (define-key flyspell-mouse-map [down-mouse-3] #'flyspell-correct-word)
     (define-key flyspell-mouse-map [mouse-3] #'undefined)))

ispell is, however, ancient and more modern alternatives exist.

nil

Hunspell

Hunspell is a spell checker and morphological analyzer designed for languages with rich morphology and complex word compounding and character encoding, originally designed for the Hungarian language.

Hunspell is a more modern spell checker which is used by a variety of software tools such as Mac OS X, LibreOffice and Mozilla Firefox. To get hunspell to work on Mac OS X for Emacs, you have to (ironically), install it. The recommended way is through Homebrew with brew install hunspell. Unfortunately I could not find any of the default dictionaries so I stole the ones from OpenOffice. You can download the dictionaries from their website. Alternatively you can download the newer plug-ins for OpenOffice 3.x and 4.x, the oxt files are simply zip archives which, when extracted, contain the .aff and .dic files needed for Hunspell. Be sure to put these files somewhere in the path of Hunspell, you can check this with hunspell -D. I placed them in /Library/Spelling/ and symlinked en_US.{aff,dic} to default.{aff,dic}.

You can make ispell.el use Hunspell with

(when (executable-find "hunspell")
  (setq-default ispell-program-name "hunspell")
  (setq ispell-really-hunspell t))

This gives us a nice on-the-fly spell checker in emacs.

LanguageTool

For a long time I had given up on grammar checkers, since they did not seem to exist. Fortunately the kind people of LanguageTool decided to make one. It is an open source tool that provides style and grammar checking with a nice (Java) command-line tool.

And the good news is, somebody even decided to make a wrapper for Emacs. langtool.el is available on MELPA. You can either download LanguageTool directly from their site, or if you are on OS X you can use brew install languagetool.

You can enable it with

(require 'langtool)
(setq langtool-language-tool-jar "/PATH_TO/languagetool-commandline.jar"
      langtool-mother-tongue "nl"
      langtool-disabled-rules '("WHITESPACE_RULE"
                                "EN_UNPAIRED_BRACKETS"
                                "COMMA_PARENTHESIS_WHITESPACE"
                                "EN_QUOTES"))

Do not forget to change the path to languagetool-commandline.jar. I have taken the liberty of setting my mother tongue to Dutch. This offers, albeit limited, False Friends detection. Furthermore I have disabled some rules that are extremely annoying when working in org-mode, such as the detection of repeated spaces (needed for indentation). You can easily extend this list by using browsing the rules.

Executing langtool-check-buffer and langtool-correct-buffer looks like:

nil

stylecheck.rb

A more pedantic style checker is style-check.rb but I have yet to find, or make, Emacs integration for it. Another option would be to port some of the rules to LanguageTool, but for now it is more of an afterthought anyway.

Remember that writing can be, or even should be, fun. Do not be afraid to fall and stumble, or even break the rules from time to time. With that closing thought I leave you with Stephen Fry: