#+TITLE: checkers/spell #+DATE: February 20, 2017 #+SINCE: v2.0 #+STARTUP: inlineimages nofold * Table of Contents :TOC_3:noexport: - [[#description][Description]] - [[#maintainers][Maintainers]] - [[#module-flags][Module Flags]] - [[#plugins][Plugins]] - [[#prerequisites][Prerequisites]] - [[#aspell][Aspell]] - [[#hunspell][Hunspell]] - [[#enchant][Enchant]] - [[#features][Features]] - [[#configuration][Configuration]] - [[#changing-how-quickly-spell-fu-spellchecks-after-changes][Changing how quickly spell-fu spellchecks after changes]] - [[#spell-fu-users][Spell-fu users]] - [[#flyspell-users][Flyspell users]] - [[#reducing-false-positives-by-disabling-spelling-on-certain-faces][Reducing false positives by disabling spelling on certain faces]] - [[#spell-fu-users-1][Spell-fu users]] - [[#flyspell-users-1][Flyspell users]] - [[#adding-or-removing-words-to-your-personal-dictionary][Adding or removing words to your personal dictionary]] - [[#troubleshooting][Troubleshooting]] * Description 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. ** Maintainers This module has no dedicated maintainers. ** Module Flags + =+flyspell= Use =flyspell= instead of =spell-fu=. It's significantly slower, but supports multiple languages and dictionaries. + =+aspell= Use =aspell= as a backend for correcting words. + =+hunspell= Use =hunspell= 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). ** Plugins + if =+flyspell= + [[https://github.com/d12frosted/flyspell-correct][flyspell-correct]] + [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-ivy-interface][flyspell-correct-ivy]] (=completion/ivy=) + [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-helm-interface][flyspell-correct-helm]] (=completion/helm=) + [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-popup-interface][flyspell-correct-popup]] (if *neither* =completion/ivy=, =completion/helm= or =completion/selectrum=) + [[https://github.com/rolandwalker/flyspell-lazy][flyspell-lazy]] + else + [[https://gitlab.com/ideasman42/emacs-spell-fu][spell-fu]] * Prerequisites 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 =+flyspell=, you will need aspell (and a dictionary) installed whether or not you have =+hunspell= or =+enchant= enabled. This is because =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. * Features + 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 (=ivy= or =helm=). When using =+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. * Configuration Dictionary is set by =ispell-dictionary= variable. Can be changed locally with the function =ispell-change-dictionary=. ** Changing how quickly spell-fu spellchecks after changes *** Spell-fu users Adjust ~spell-fu-idle-delay~ to change how long Emacs waits to spellcheck after recent changes. #+BEGIN_SRC elisp (after! spell-fu (setq spell-fu-idle-delay 0.5)) ; default is 0.25 #+END_SRC *** Flyspell users Lazy spellcheck is provided by =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 elisp (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 elisp (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 elisp (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 elisp (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 (doom-enlist (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 =zg= and =zw=, respectively. =+flyspell= users can also add/remove words from the ~flyspell-correct~ popup interface (there will be extra options on the list of corrections for "save word to dictionary"). * TODO Troubleshooting