Flyspell-region is really, really slow on the Mac. You can literally watch it check a word, pause, check a word, pause…
There are a few interesting things about this:
- If you flyspell a large region, then it is very quick. Only small regions take a long time.
- It’s fast if you run it from the terminal.
So, what’s going on?
First, if the region is under a certain number of characters (see flyspell-large-region in flyspell.el, set to 1000 in the base version), Emacs will run flyspell-small-region instead of flyspell-large-region.
Second, flyspell-small-region is slow — much slower than flyspell-large-region. Look at the code for flyspell-small-region:
(defun flyspell-small-region (beg end) "Flyspell text between BEG and END." (save-excursion (if (> beg end) (let ((old beg)) (setq beg end) (setq end old))) (goto-char beg) (let ((count 0)) (while (< (point) end) (if (and flyspell-issue-message-flag (= count 100)) (progn (message "Spell Checking...%d%%" (* 100 (/ (float (- (point) beg)) (- end beg)))) (setq count 0)) (setq count (+ 1 count))) (flyspell-word) (sit-for 0) (let ((cur (point))) (forward-word 1) (if (and (< (point) end) (> (point) (+ cur 1))) (backward-char 1))))) (backward-char 1) (if flyspell-issue-message-flag (message "Spell Checking completed.")) (flyspell-word)))
The slow thing here is actually not the spell checking, it’s the sit-for call right after it. sit-for checks for input, but a side effect is that it forces a display refresh — which is fast in the terminal version of Emacs but slow in the GUI.
So, there are a couple ways of fixing this:
- Customize Ispell / Processes / Flyspell / Large Region and set it to a really small number so things always go through the large region processing.
- Edit flyspell-small-region and comment out the sit-for line (or, better, move it into the conditional above to be called at the same time the percentage is shown).
- Remove it completely with an advice hook
To remove it completely with advice, use something like this:
(defadvice flyspell-region (around fast-flyspell-region) (flet ( (sit-for (x) t) ) ad-do-it)) (ad-activate 'flyspell-region)
Suddenly, flyspell-region is not so slow anymore.