Quickstart (require 'flyspell-lazy) (flyspell-lazy-mode 1) (flyspell-mode 1) ; or (flyspell-prog-mode) Explanation Emacs' built-in `flyspell-mode' has performance issues on some platforms. Specifically, keyboard responsiveness may be significantly degraded on OS X. See this bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=2056 This package reduces the amount of work done by flyspell. Instead of checking *instantly* as you type, spelling will be checked when Emacs has been idle for a short time. (Vanilla `flyspell-mode' does not use idle timers but a subtle combination of hooks and `sit-for'.) This package also forces `flyspell-mode' off completely for certain buffers. To use this library, add the following to your ~/.emacs (require 'flyspell-lazy) (flyspell-lazy-mode 1) Then use `flyspell-mode' as you normally would. This package does not load flyspell for you. `flyspell-lazy-mode' will invoke spellcheck less frequently than vanilla `flyspell-mode', though this can be changed somewhat via `customize'. See Also M-x customize-group RET flyspell-lazy RET M-x customize-group RET flyspell RET M-x customize-group RET ispell RET Notes If you are using "aspell" instead of "ispell" on the backend, the following setting may improve performance: (add-to-list 'ispell-extra-args "--sug-mode=ultra") If you see the cursor flicker over the region during spellcheck, make sure that `flyspell-large-region' is set to 1 (this library tries to do that for you), and try adding the following to your ~/.emacs (defadvice flyspell-small-region (around flyspell-small-region-no-sit-for activate) (flyspell-lazy--with-mocked-function 'sit-for t ad-do-it)) Compatibility and Requirements GNU Emacs version 24.4-devel : yes, at the time of writing GNU Emacs version 24.3 : yes GNU Emacs version 23.3 : yes GNU Emacs version 22.2 : yes, with some limitations GNU Emacs version 21.x and lower : unknown No external dependencies Bugs The longer the delay before checking, the more inaccurate the coordinates in `flyspell-changes'. These are static integers; they don't move with updates in the buffer. To mitigate this effect, a second idle timer checks all visible text (at a much longer interval). Flyspell-lazy-matches-last-text is not reliable - in debug mode it can be seen that it sometimes toggles between two states at every press of spacebar. This may be related to generating the additional span around the point. Flyspell-lazy-refine-changes is sometimes mistakenly scrubbing all pending spans. Check the case where one char is deleted inside a word. TODO Let flyspell-issue-message-flag and flyspell-issue-welcome-flag to nil wherever needed to improve performance. Consider using while-no-input macro. Figure out if flyspell-lazy affects suggestions -- must an update be forced on the word before running suggestions? Force re-check of text after removing comments renders the text code again under flyspell-prog-mode. Optionally add aspell extra args noted in doc. Make flyspell-lazy-single-ispell actually work. Currently, see a new "starting ispell" message for every buffer opened, in spite of flyspell-lazy-single-ispell setting. This comes from flyspell-mode calling flyspell-mode-on. What would be the ramifications of using a single ispell process? Only loss of per-buffer dictionaries? Enforce using a single ispell process on regions larger than flyspell-large-region. Strip symbols from text - see flyspell-lazy-strip-symbols. Heuristic to detect regular expressions and avoid checking them as strings. Use buffer-undo-list instead of flyspell-changes, then can also remove flyspell's after-change hook. Use the hints set in prog-mode to avoid checks in the per-word and refine stages. Hints for commented-out code to avoid checking. ; License Simplified BSD License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. This software is provided by Roland Walker "AS IS" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall Roland Walker or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Roland Walker.