#+title: :checkers spell #+subtitle: Tasing you for misspelling mispelling #+created: February 20, 2017 #+since: 2.0.0 * Description :unfold: This modules provides spellchecking powered by =aspell=, =hunspell= or =enchant=. Spellcheck is automatically loaded in many ~text-mode~ derivatives, which includes ~org-mode~, ~markdown-mode~, the Git Commit buffer (from magit), ~mu4e-compose-mode~, and others. - Spell checking and correction using =aspell=, =hunspell= or =enchant=. - Ignores source code inside org or markdown files. - Lazily spellchecking recent changes only when idle. - Choosing suggestions using completion interfaces ([[doom-package:ivy]] or [[doom-package:helm]]). ** Maintainers /This module has no dedicated maintainers./ [[doom-contrib-maintainer:][Become a maintainer?]] ** Module flags - +aspell :: Use =aspell= as a backend for correcting words. - +enchant :: Use =enchant-2= as a backend for correcting words. - +everywhere :: Spell check in programming modes as well (in comments only). - +flyspell :: Use [[doom-package:flyspell]] instead of [[doom-package:spell-fu]]. It's significantly slower, but supports multiple languages and dictionaries. - +hunspell :: Use =hunspell= as a backend for correcting words. ** Packages - if [[doom-module:+flyspell]] - [[doom-package:flyspell-correct]] - [[doom-package:flyspell-correct-ivy]] if [[doom-module::completion ivy]] - [[doom-package:flyspell-correct-helm]] if [[doom-module::completion helm]] - [[doom-package:flyspell-correct-popup]] unless [[doom-module::completion ivy]], [[doom-module::completion helm]], or [[doom-module::completion vertico]] - [[doom-package:flyspell-lazy]] - else - [[doom-package:spell-fu]] ** Hacks /No hacks documented for this module./ ** TODO Changelog # This section will be machine generated. Don't edit it by hand. /This module does not have a changelog yet./ * Installation [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] This module requires one of =aspell=, =hunspell= or =enchant-2= installed on your system and in your =$PATH=. They also need dictionaries for your language(s). #+begin_quote 🚧 If you *are not* using [[doom-module:+flyspell]], you will need =aspell= (and a dictionary) installed whether or not you have [[doom-module:+hunspell]] or [[doom-module:+enchant]] enabled. This is because [[doom-package:spell-fu]] does not support generating the word list with anything other than =aspell= yet. #+end_quote ** Aspell - Ubuntu: ~$ apt-get install aspell aspell-en~ - macOS: ~$ brew install aspell~ - Arch Linux: ~$ pacman -S aspell aspell-en~ - NixOS: #+begin_src nix { environment.systemPackages = with pkgs; [ (aspellWithDicts (dicts: with dicts; [ en en-computers en-science ])) ]; } #+end_src ** Hunspell - Ubuntu: ~$ apt-get install hunspell~ - macOS: ~$ brew install hunspell~ - Arch Linux: ~$ pacman -S hunspell~ - NixOS: #+begin_src nix { environment.systemPackages = with pkgs; [ hunspell ]; } #+end_src ** Enchant - Ubuntu: ~$ apt-get install enchant-2~ - macOS: ~$ brew install enchant~ - Arch Linux: ~$ pacman -S enchant~ - NixOS: #+begin_src nix { environment.systemPackages = with pkgs; [ enchant ]; } #+end_src Enchant is just a wrapper for other spelling libraries and you will need to have at least one of the supported backends installed as well. * TODO Usage #+begin_quote 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] #+end_quote When using [[doom-module:+everywhere]], spell checking is performed for as many major modes as possible, and not only ~text-mode~ derivatives. e.g. in comments for programming major modes. * TODO Configuration #+begin_quote 🔨 /This module's configuration documentation is incomplete./ [[doom-contrib-module:][Complete it?]] #+end_quote Dictionary is set by ~ispell-dictionary~ variable. Can be changed locally with the function ~ispell-change-dictionary~. ** Changing how quickly spelling is checked after changes *** Spell-fu users Adjust ~spell-fu-idle-delay~ to change how long Emacs waits to spellcheck after recent changes: #+begin_src emacs-lisp (after! spell-fu (setq spell-fu-idle-delay 0.5)) ; default is 0.25 #+end_src *** Flyspell users Lazy spellcheck is provided by [[doom-package:flyspell-lazy]] package. ~flyspell-lazy-idle-seconds~ sets how many idle seconds until spellchecking recent changes (default as 1), while ~flyspell-lazy-window-idle-seconds~ sets how many seconds until the whole window is spellchecked (default as 3): #+begin_src emacs-lisp (after! flyspell (setq flyspell-lazy-idle-seconds 2)) #+end_src ** Reducing false positives by disabling spelling on certain faces *** Spell-fu users Users can exclude what faces to preform spellchecking on by adjusting ~+spell-excluded-faces-alist~ in a buffer-local hook: #+begin_src emacs-lisp (setf (alist-get 'markdown-mode +spell-excluded-faces-alist) '(markdown-code-face markdown-reference-face markdown-link-face markdown-url-face markdown-markup-face markdown-html-attr-value-face markdown-html-attr-name-face markdown-html-tag-name-face)) #+end_src *** Flyspell users Flyspell will run a series of predicate functions to determine if a word should be spell checked. You can add your own with ~set-flyspell-predicate!~: #+begin_src emacs-lisp (set-flyspell-predicate! '(markdown-mode gfm-mode) #'+markdown-flyspell-word-p) #+end_src Flyspell predicates take no arguments and must return a boolean to determine if the word at point should be spell checked. For example: #+begin_src emacs-lisp (defun +markdown-flyspell-word-p () "Return t if point is on a word that should be spell checked. Return nil if on a link url, markup, html, or references." (let ((faces (ensure-list (get-text-property (point) 'face)))) (or (and (memq 'font-lock-comment-face faces) (memq 'markdown-code-face faces)) (not (cl-loop with unsafe-faces = '(markdown-reference-face markdown-url-face markdown-markup-face markdown-comment-face markdown-html-attr-name-face markdown-html-attr-value-face markdown-html-tag-name-face markdown-code-face) for face in faces if (memq face unsafe-faces) return t))))) #+end_src ** Adding or removing words to your personal dictionary Use ~M-x +spell/add-word~ and ~M-x +spell/remove-word~ to whitelist words that you know are not misspellings. For evil users these are bound to [[kbd:][zg]] and [[kbd:][zw]], respectively. [[doom-module:+flyspell]] users can also add/remove words from the [[doom-package:flyspell-correct]] popup interface (there will be extra options on the list of corrections for "save word to dictionary"). * Troubleshooting [[doom-report:][Report an issue?]] ** spell-fu highlights every single word [[doom-package:spell-fu]] caches its word list. If it was activated before your dictionaries were installed, it will generate an empty word list, causing it to highlight all words as incorrect. Delete its cache files in =$EMACSDIR/.local/etc/spell-fu/= to fix this. ** Cannot add [word] to any active dictionary *** Aspell If ~M-x +spell/add-word~ results in the above error this mean that the personal dictionary file was not created for some reason. This can be fixed by creating the required file manually. Note: the personal dictionary is defined by ~ispell-personal-dictionary~, you may need to check it first with ~M-x describe-variable~. #+begin_example shell mkdir -p ~/.emacs.d/.local/etc/ispell echo personal_ws-1.1 en 0 > ~/.emacs.d/.local/etc/ispell/.pws #+end_example Where ~personal_ws-1.1 en 0~ is the required header format for the personal dictionary file. ~en~ is the language you're writing in and have a dict installed and ~0~ is the number of added words in the dictionary. If you are planning of updating the file with the list of words, update the number accordingly. After the file is created, restart emacs and adding words should work. * Frequently asked questions /This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]] * TODO Appendix #+begin_quote 🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]] #+end_quote