checkers/spell: add +flyspell flag
spell-fu lacks support for multiple dictionaries, affix expansion, and many non-English dictionaries, so I've added back flyspell support to the spell module, but opt-in, because it is still the significantly slower option and spell-fu may support them one day. If not, tlikonen/wcheck-mode is another alternative to consider. Fixes #3813
This commit is contained in:
parent
97471f11db
commit
e3750dbf66
8 changed files with 313 additions and 111 deletions
|
@ -9,17 +9,23 @@
|
||||||
- [[#module-flags][Module Flags]]
|
- [[#module-flags][Module Flags]]
|
||||||
- [[#plugins][Plugins]]
|
- [[#plugins][Plugins]]
|
||||||
- [[#prerequisites][Prerequisites]]
|
- [[#prerequisites][Prerequisites]]
|
||||||
|
- [[#aspell][Aspell]]
|
||||||
|
- [[#hunspell][Hunspell]]
|
||||||
- [[#features][Features]]
|
- [[#features][Features]]
|
||||||
- [[#configuration][Configuration]]
|
- [[#configuration][Configuration]]
|
||||||
- [[#changing-how-quickly-spell-fu-spellchecks-after-changes][Changing how quickly spell-fu spellchecks after changes]]
|
- [[#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]]
|
- [[#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]]
|
- [[#adding-or-removing-words-to-your-personal-dictionary][Adding or removing words to your personal dictionary]]
|
||||||
- [[#troubleshooting][Troubleshooting]]
|
- [[#troubleshooting][Troubleshooting]]
|
||||||
|
|
||||||
* Description
|
* Description
|
||||||
This modules provides spellchecking powered by =aspell= or =hunspell=.
|
This modules provides spellchecking powered by =aspell= or =hunspell=.
|
||||||
|
|
||||||
Spellcheck is automatically loaded in all ~text-mode~ derivatives, which
|
Spellcheck is automatically loaded in many ~text-mode~ derivatives, which
|
||||||
includes ~org-mode~, ~markdown-mode~, the Git Commit buffer (from magit),
|
includes ~org-mode~, ~markdown-mode~, the Git Commit buffer (from magit),
|
||||||
~mu4e-compose-mode~, and others.
|
~mu4e-compose-mode~, and others.
|
||||||
|
|
||||||
|
@ -27,63 +33,137 @@ includes ~org-mode~, ~markdown-mode~, the Git Commit buffer (from magit),
|
||||||
This module has no dedicated maintainers.
|
This module has no dedicated maintainers.
|
||||||
|
|
||||||
** Module Flags
|
** 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.
|
+ =+aspell= Use =aspell= as a backend for correcting words.
|
||||||
+ =+hunspell= Use =hunspell= as a backend for correcting words.
|
+ =+hunspell= Use =hunspell= as a backend for correcting words.
|
||||||
+ =+everywhere= Use spellcheck in prog-mode and conf-mode derivatives as well as
|
+ =+everywhere= Spell check in programming modes as well (in comments).
|
||||||
text-mode. Basically, enable =spell-fu-mode= everywhere.
|
|
||||||
|
|
||||||
** Plugins
|
** Plugins
|
||||||
+ [[https://gitlab.com/ideasman42/emacs-spell-fu][spell-fu]]
|
+ 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= or =completion/helm=)
|
||||||
|
+ [[https://github.com/rolandwalker/flyspell-lazy][flyspell-lazy]]
|
||||||
|
+ else
|
||||||
|
+ [[https://gitlab.com/ideasman42/emacs-spell-fu][spell-fu]]
|
||||||
|
|
||||||
* Prerequisites
|
* Prerequisites
|
||||||
This module requires =aspell= to be installed, whether or not you intend to use
|
This module requires one of =aspell= or =hunspell= installed on your system and
|
||||||
=hunspell= as the word correction backend. =spell-fu= does not yet support
|
in your ~PATH~. They also need dictionaries for your language(s).
|
||||||
generating the word list with a custom command or =hunspell=, but =hunspell= can
|
|
||||||
still be used to provide correction suggestions when invoking ~ispell-word~.
|
|
||||||
|
|
||||||
You will need =hunspell= installed (via your OS package manager) to use it as a
|
#+begin_quote
|
||||||
correction backend.
|
If you *are not* using =+flyspell=, you will need aspell (and a dictionary)
|
||||||
|
installed whether or not you have =+hunspell= 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~
|
||||||
|
+ Arch Linux: ~pacman -S aspell aspell-en~
|
||||||
|
+ NixOS:
|
||||||
|
#+BEGIN_SRC nix
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
aspell
|
||||||
|
aspellDicts.en
|
||||||
|
aspellDicts.en-computers
|
||||||
|
aspellDicts.en-science
|
||||||
|
];
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** TODO Hunspell
|
||||||
|
|
||||||
* Features
|
* Features
|
||||||
+ Spellchecking based on =aspell=.
|
+ Spell checking and correction using =aspell= or =hunspell=.
|
||||||
+ Spell correction using =aspell= or =hunspell= (through ~M-x ispell-word~).
|
|
||||||
+ Ignores source code inside org or markdown files.
|
+ 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-fu-mode~ is activated for as many major modes
|
When using =+everywhere=, spell checking is performed for as many major modes as
|
||||||
as possible, and not only ~text-mode~ derivatives. =spell-fu= will only spell
|
possible, and not only ~text-mode~ derivatives. e.g. in comments for programming
|
||||||
check comments in programming major modes.
|
major modes.
|
||||||
|
|
||||||
* Configuration
|
* Configuration
|
||||||
Dictionary is set by =ispell-dictionary= variable. Can be changed locally with
|
Dictionary is set by =ispell-dictionary= variable. Can be changed locally with
|
||||||
the function =ispell-change-dictionary=.
|
the function =ispell-change-dictionary=.
|
||||||
|
|
||||||
** Changing how quickly spell-fu spellchecks after changes
|
** Changing how quickly spell-fu spellchecks after changes
|
||||||
Adjust ~spell-fu-idle-delay~ to change how long spell-fu waits to spellcheck
|
*** Spell-fu users
|
||||||
after recent changes (its default value as ~0.25~).
|
Adjust ~spell-fu-idle-delay~ to change how long Emacs waits to spellcheck after
|
||||||
|
recent changes.
|
||||||
#+BEGIN_SRC elisp
|
#+BEGIN_SRC elisp
|
||||||
(after! spell-fu
|
(after! spell-fu
|
||||||
(setq spell-fu-idle-delay 0.5))
|
(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
|
#+END_SRC
|
||||||
|
|
||||||
** Reducing false positives by disabling spelling on certain faces
|
** Reducing false positives by disabling spelling on certain faces
|
||||||
Exclude what faces to not preform spellchecking on by setting
|
*** Spell-fu users
|
||||||
~spell-fu-faces-exclude~ in a buffer-local hook:
|
Users can exclude what faces to preform spellchecking on by adjusting
|
||||||
|
~+spell-excluded-faces-alist~ in a buffer-local hook:
|
||||||
|
|
||||||
#+BEGIN_SRC elisp
|
#+BEGIN_SRC elisp
|
||||||
(setq-hook! 'markdown-mode-hook
|
(setf (alist-get 'markdown-mode +spell-excluded-faces-alist)
|
||||||
spell-fu-faces-exclude '(markdown-code-face
|
'(markdown-code-face
|
||||||
markdown-reference-face
|
markdown-reference-face
|
||||||
markdown-link-face
|
markdown-link-face
|
||||||
markdown-url-face
|
markdown-url-face
|
||||||
markdown-markup-face
|
markdown-markup-face
|
||||||
markdown-html-attr-value-face
|
markdown-html-attr-value-face
|
||||||
markdown-html-attr-name-face
|
markdown-html-attr-name-face
|
||||||
markdown-html-tag-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
|
#+END_SRC
|
||||||
|
|
||||||
** Adding or removing words to your personal dictionary
|
** Adding or removing words to your personal dictionary
|
||||||
Use ~M-x spell-fu-word-add~ and ~M-x spell-fu-word-remove~ to whitelist words
|
Spell-fu users can call ~M-x spell-fu-word-add~ and ~M-x spell-fu-word-remove~
|
||||||
that you know are not misspellings.
|
to whitelist words that you know are not misspellings. These are on =zq= and
|
||||||
|
=zw=, respectively, for users with Evil enabled.
|
||||||
|
|
||||||
|
Neither ispell nor =+flyspell= support managing personal dictionaries within
|
||||||
|
Emacs.
|
||||||
|
|
||||||
* TODO Troubleshooting
|
* TODO Troubleshooting
|
||||||
|
|
28
modules/checkers/spell/autoload/flyspell.el
Normal file
28
modules/checkers/spell/autoload/flyspell.el
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
;;; checkers/spell/autoload/flyspell.el -*- lexical-binding: t; -*-
|
||||||
|
;;;###if (featurep! +flyspell)
|
||||||
|
|
||||||
|
;;;###autodef
|
||||||
|
(defalias 'flyspell-mode! #'flyspell-mode)
|
||||||
|
|
||||||
|
(defvar +spell--flyspell-predicate-alist nil
|
||||||
|
"TODO")
|
||||||
|
|
||||||
|
;;;###autodef
|
||||||
|
(defun set-flyspell-predicate! (modes predicate)
|
||||||
|
"TODO"
|
||||||
|
(declare (indent defun))
|
||||||
|
(dolist (mode (doom-enlist modes) +spell--flyspell-predicate-alist)
|
||||||
|
(add-to-list '+spell--flyspell-predicate-alist (cons mode predicate))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +spell-init-flyspell-predicate-h ()
|
||||||
|
"TODO"
|
||||||
|
(when-let (pred (assq major-mode +spell--flyspell-predicate-alist))
|
||||||
|
(setq-local flyspell-generic-check-word-predicate (cdr pred))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +spell-correction-at-point-p (&optional point)
|
||||||
|
"TODO"
|
||||||
|
(cl-loop for ov in (overlays-at (or point (point)))
|
||||||
|
if (overlay-get ov 'flyspell-overlay)
|
||||||
|
return t))
|
|
@ -1,4 +1,5 @@
|
||||||
;;; checkers/spell/autoload/ivy.el -*- lexical-binding: t; -*-
|
;;; checkers/spell/autoload/spell-fu.el -*- lexical-binding: t; -*-
|
||||||
|
;;;###if (not (featurep! +flyspell))
|
||||||
|
|
||||||
(defun +spell--correct (replace poss word orig-pt start end)
|
(defun +spell--correct (replace poss word orig-pt start end)
|
||||||
(cond ((eq replace 'ignore)
|
(cond ((eq replace 'ignore)
|
||||||
|
@ -66,8 +67,6 @@
|
||||||
(let ((word (thing-at-point 'word t))
|
(let ((word (thing-at-point 'word t))
|
||||||
(orig-pt (point))
|
(orig-pt (point))
|
||||||
poss ispell-filter)
|
poss ispell-filter)
|
||||||
(save-current-buffer
|
|
||||||
(ispell-accept-buffer-local-defs))
|
|
||||||
(ispell-send-string "%\n")
|
(ispell-send-string "%\n")
|
||||||
(ispell-send-string (concat "^" word "\n"))
|
(ispell-send-string (concat "^" word "\n"))
|
||||||
(while (progn (accept-process-output ispell-process)
|
(while (progn (accept-process-output ispell-process)
|
|
@ -1,50 +1,11 @@
|
||||||
;;; checkers/spell/config.el -*- lexical-binding: t; -*-
|
;;; checkers/spell/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(defvar +spell-correct-interface
|
|
||||||
(cond ((featurep! :completion ivy)
|
|
||||||
#'+spell-correct-ivy-fn)
|
|
||||||
((featurep! :completion helm)
|
|
||||||
#'+spell-correct-helm-fn)
|
|
||||||
(#'+spell-correct-generic-fn))
|
|
||||||
"Function to use to display corrections.")
|
|
||||||
|
|
||||||
(defvar +spell-excluded-faces-alist
|
|
||||||
'((markdown-mode
|
|
||||||
. (markdown-code-face
|
|
||||||
markdown-html-attr-name-face
|
|
||||||
markdown-html-attr-value-face
|
|
||||||
markdown-html-tag-name-face
|
|
||||||
markdown-link-face
|
|
||||||
markdown-markup-face
|
|
||||||
markdown-reference-face
|
|
||||||
markdown-url-face))
|
|
||||||
(org-mode
|
|
||||||
. (org-block
|
|
||||||
org-block-begin-line
|
|
||||||
org-block-end-line
|
|
||||||
org-code
|
|
||||||
org-date
|
|
||||||
org-formula
|
|
||||||
org-latex-and-related
|
|
||||||
org-link
|
|
||||||
org-meta-line
|
|
||||||
org-property-value
|
|
||||||
org-ref-cite-face
|
|
||||||
org-special-keyword
|
|
||||||
org-tag
|
|
||||||
org-todo
|
|
||||||
org-todo-keyword-done
|
|
||||||
org-todo-keyword-habt
|
|
||||||
org-todo-keyword-kill
|
|
||||||
org-todo-keyword-outd
|
|
||||||
org-todo-keyword-todo
|
|
||||||
org-todo-keyword-wait
|
|
||||||
org-verbatim)))
|
|
||||||
"Faces in certain major modes that spell-fu will not spellcheck.")
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Packages
|
;;; Ispell
|
||||||
|
|
||||||
|
;; `elisp-mode' is loaded at startup. In order to lazy load its config we need
|
||||||
|
;; to pretend it isn't loaded
|
||||||
|
(delq! 'ispell features)
|
||||||
|
|
||||||
(global-set-key [remap ispell-word] #'+spell/correct)
|
(global-set-key [remap ispell-word] #'+spell/correct)
|
||||||
|
|
||||||
|
@ -100,30 +61,156 @@
|
||||||
(_ (doom-log "Spell checker not found. Either install `aspell' or `hunspell'"))))
|
(_ (doom-log "Spell checker not found. Either install `aspell' or `hunspell'"))))
|
||||||
|
|
||||||
|
|
||||||
(use-package! spell-fu
|
;;
|
||||||
:when (executable-find "aspell")
|
;;; Implementations
|
||||||
:hook (text-mode . spell-fu-mode)
|
|
||||||
:init
|
|
||||||
(setq spell-fu-directory (concat doom-etc-dir "spell-fu"))
|
|
||||||
(when (featurep! +everywhere)
|
|
||||||
(add-hook! '(yaml-mode-hook
|
|
||||||
conf-mode-hook
|
|
||||||
prog-mode-hook)
|
|
||||||
#'spell-fu-mode))
|
|
||||||
:config
|
|
||||||
(defadvice! +spell--create-word-dict-a (_word words-file _action)
|
|
||||||
:before #'spell-fu--word-add-or-remove
|
|
||||||
(unless (file-exists-p words-file)
|
|
||||||
(make-directory (file-name-directory words-file) t)
|
|
||||||
(with-temp-file words-file
|
|
||||||
(insert (format "personal_ws-1.1 %s 0\n" ispell-dictionary)))))
|
|
||||||
|
|
||||||
(add-hook! 'spell-fu-mode-hook
|
(if! (not (featurep! +flyspell))
|
||||||
(defun +spell-init-excluded-faces-h ()
|
|
||||||
"Set `spell-fu-faces-exclude' according to `+spell-excluded-faces-alist'."
|
|
||||||
(when-let (excluded (alist-get major-mode +spell-excluded-faces-alist))
|
|
||||||
(setq-local spell-fu-faces-exclude excluded))))
|
|
||||||
|
|
||||||
;; TODO custom `spell-fu-check-range' function to exclude URLs from links or
|
(use-package! spell-fu
|
||||||
;; org-src blocks more intelligently.
|
:when (executable-find "aspell")
|
||||||
)
|
:hook (text-mode . spell-fu-mode)
|
||||||
|
:general ([remap ispell-word] #'+spell/correct)
|
||||||
|
:init
|
||||||
|
(defvar +spell-correct-interface
|
||||||
|
(cond ((featurep! :completion ivy)
|
||||||
|
#'+spell-correct-ivy-fn)
|
||||||
|
((featurep! :completion helm)
|
||||||
|
#'+spell-correct-helm-fn)
|
||||||
|
(#'+spell-correct-generic-fn))
|
||||||
|
"Function to use to display corrections.")
|
||||||
|
|
||||||
|
(defvar +spell-excluded-faces-alist
|
||||||
|
'((markdown-mode
|
||||||
|
. (markdown-code-face
|
||||||
|
markdown-html-attr-name-face
|
||||||
|
markdown-html-attr-value-face
|
||||||
|
markdown-html-tag-name-face
|
||||||
|
markdown-link-face
|
||||||
|
markdown-markup-face
|
||||||
|
markdown-reference-face
|
||||||
|
markdown-url-face))
|
||||||
|
(org-mode
|
||||||
|
. (org-block
|
||||||
|
org-block-begin-line
|
||||||
|
org-block-end-line
|
||||||
|
org-code
|
||||||
|
org-date
|
||||||
|
org-formula
|
||||||
|
org-latex-and-related
|
||||||
|
org-link
|
||||||
|
org-meta-line
|
||||||
|
org-property-value
|
||||||
|
org-ref-cite-face
|
||||||
|
org-special-keyword
|
||||||
|
org-tag
|
||||||
|
org-todo
|
||||||
|
org-todo-keyword-done
|
||||||
|
org-todo-keyword-habt
|
||||||
|
org-todo-keyword-kill
|
||||||
|
org-todo-keyword-outd
|
||||||
|
org-todo-keyword-todo
|
||||||
|
org-todo-keyword-wait
|
||||||
|
org-verbatim)))
|
||||||
|
"Faces in certain major modes that spell-fu will not spellcheck.")
|
||||||
|
|
||||||
|
(setq spell-fu-directory (concat doom-etc-dir "spell-fu"))
|
||||||
|
(when (featurep! +everywhere)
|
||||||
|
(add-hook! '(yaml-mode-hook
|
||||||
|
conf-mode-hook
|
||||||
|
prog-mode-hook)
|
||||||
|
#'spell-fu-mode))
|
||||||
|
:config
|
||||||
|
(map! :after spell-fu
|
||||||
|
:map override
|
||||||
|
:n [return]
|
||||||
|
(cmds! (memq 'spell-fu-incorrect-face (face-at-point nil t))
|
||||||
|
#'+spell/correct))
|
||||||
|
|
||||||
|
(defadvice! +spell--create-word-dict-a (_word words-file _action)
|
||||||
|
:before #'spell-fu--word-add-or-remove
|
||||||
|
(unless (file-exists-p words-file)
|
||||||
|
(make-directory (file-name-directory words-file) t)
|
||||||
|
(with-temp-file words-file
|
||||||
|
(insert (format "personal_ws-1.1 %s 0\n" ispell-dictionary)))))
|
||||||
|
|
||||||
|
(add-hook! 'spell-fu-mode-hook
|
||||||
|
(defun +spell-init-excluded-faces-h ()
|
||||||
|
"Set `spell-fu-faces-exclude' according to `+spell-excluded-faces-alist'."
|
||||||
|
(when-let (excluded (alist-get major-mode +spell-excluded-faces-alist))
|
||||||
|
(setq-local spell-fu-faces-exclude excluded))))
|
||||||
|
|
||||||
|
;; TODO custom `spell-fu-check-range' function to reduce false positives
|
||||||
|
;; more intelligently, or modify `spell-fu-word-regexp' to include
|
||||||
|
;; non-latin charactersets.
|
||||||
|
)
|
||||||
|
|
||||||
|
(use-package! flyspell ; built-in
|
||||||
|
:defer t
|
||||||
|
:preface
|
||||||
|
;; `flyspell' is loaded at startup. In order to lazy load its config we need
|
||||||
|
;; to pretend it isn't loaded.
|
||||||
|
(defer-feature! flyspell flyspell-mode flyspell-prog-mode)
|
||||||
|
:init
|
||||||
|
(add-hook! '(org-mode-hook
|
||||||
|
markdown-mode-hook
|
||||||
|
TeX-mode-hook
|
||||||
|
rst-mode-hook
|
||||||
|
mu4e-compose-mode-hook
|
||||||
|
message-mode-hook
|
||||||
|
git-commit-mode-hook)
|
||||||
|
#'flyspell-mode)
|
||||||
|
|
||||||
|
(when (featurep! +everywhere)
|
||||||
|
(add-hook! '(yaml-mode-hook
|
||||||
|
conf-mode-hook
|
||||||
|
prog-mode-hook)
|
||||||
|
#'flyspell-prog-mode))
|
||||||
|
|
||||||
|
:config
|
||||||
|
(setq flyspell-issue-welcome-flag nil
|
||||||
|
;; Significantly speeds up flyspell, which would otherwise print
|
||||||
|
;; messages for every word when checking the entire buffer
|
||||||
|
flyspell-issue-message-flag nil)
|
||||||
|
|
||||||
|
(add-hook! 'flyspell-mode-hook
|
||||||
|
(defun +spell-inhibit-duplicate-detection-maybe-h ()
|
||||||
|
"Don't mark duplicates when style/grammar linters are present.
|
||||||
|
e.g. proselint and langtool."
|
||||||
|
(and (or (and (bound-and-true-p flycheck-mode)
|
||||||
|
(executable-find "proselint"))
|
||||||
|
(featurep 'langtool))
|
||||||
|
(setq-local flyspell-mark-duplications-flag nil))))
|
||||||
|
|
||||||
|
;; Ensure mode-local predicates declared with `set-flyspell-predicate!' are
|
||||||
|
;; used in their respective major modes.
|
||||||
|
(add-hook 'flyspell-mode-hook #'+spell-init-flyspell-predicate-h)
|
||||||
|
|
||||||
|
(let ((flyspell-correct
|
||||||
|
(cmds! (and (not (or mark-active (ignore-errors (evil-insert-state-p))))
|
||||||
|
(memq 'flyspell-incorrect (face-at-point nil t)))
|
||||||
|
#'flyspell-correct-at-point)))
|
||||||
|
(map! :map flyspell-mouse-map
|
||||||
|
"RET" flyspell-correct
|
||||||
|
[return] flyspell-correct
|
||||||
|
[mouse-1] #'flyspell-correct-at-point)))
|
||||||
|
|
||||||
|
|
||||||
|
(use-package! flyspell-correct
|
||||||
|
:commands flyspell-correct-previous
|
||||||
|
:general ([remap ispell-word] #'flyspell-correct-at-point)
|
||||||
|
:config
|
||||||
|
(cond ((and (featurep! :completion helm)
|
||||||
|
(require 'flyspell-correct-helm nil t)))
|
||||||
|
((and (featurep! :completion ivy)
|
||||||
|
(require 'flyspell-correct-ivy nil t)))
|
||||||
|
((require 'flyspell-correct-popup nil t)
|
||||||
|
(setq flyspell-popup-correct-delay 0.8)
|
||||||
|
(define-key popup-menu-keymap [escape] #'keyboard-quit))))
|
||||||
|
|
||||||
|
|
||||||
|
(use-package! flyspell-lazy
|
||||||
|
:after flyspell
|
||||||
|
:config
|
||||||
|
(setq flyspell-lazy-idle-seconds 1
|
||||||
|
flyspell-lazy-window-idle-seconds 3)
|
||||||
|
(flyspell-lazy-mode +1)))
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
;;; checkers/spell/doctor.el -*- lexical-binding: t; -*-
|
;;; checkers/spell/doctor.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(unless (executable-find "aspell")
|
(when (or (not (featurep! +flyspell))
|
||||||
(warn! "Couldn't find aspell executable; spell checker will not work"))
|
(featurep! +aspell))
|
||||||
|
(unless (executable-find "aspell")
|
||||||
|
(warn! "Couldn't find aspell executable; spell checker will not work")))
|
||||||
|
|
||||||
(when (featurep! +hunspell)
|
(when (featurep! +hunspell)
|
||||||
(unless (executable-find "hunspell")
|
(unless (executable-find "hunspell")
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
;; -*- no-byte-compile: t; -*-
|
;; -*- no-byte-compile: t; -*-
|
||||||
;;; checkers/spell/packages.el
|
;;; checkers/spell/packages.el
|
||||||
|
|
||||||
(package! spell-fu :pin "e94d01cdc822e02968971cde09276047a5d55772")
|
(if (not (featurep! +flyspell))
|
||||||
|
(package! spell-fu :pin "e94d01cdc822e02968971cde09276047a5d55772")
|
||||||
|
(package! flyspell-correct :pin "dea1290a371c540dde7b8d0eef7a12d92f7a0b83")
|
||||||
|
(cond ((featurep! :completion ivy)
|
||||||
|
(package! flyspell-correct-ivy))
|
||||||
|
((featurep! :completion helm)
|
||||||
|
(package! flyspell-correct-helm))
|
||||||
|
((package! flyspell-correct-popup)))
|
||||||
|
(package! flyspell-lazy :pin "3ebf68cc9eb10c972a2de8d7861cbabbbce69570"))
|
||||||
|
|
|
@ -53,6 +53,8 @@ capture, the end position, and the output buffer.")
|
||||||
(add-to-list 'org-src-lang-modes '("md" . markdown)))
|
(add-to-list 'org-src-lang-modes '("md" . markdown)))
|
||||||
|
|
||||||
:config
|
:config
|
||||||
|
(set-flyspell-predicate! '(markdown-mode gfm-mode)
|
||||||
|
#'+markdown-flyspell-word-p)
|
||||||
(set-lookup-handlers! '(markdown-mode gfm-mode)
|
(set-lookup-handlers! '(markdown-mode gfm-mode)
|
||||||
;; `markdown-follow-thing-at-point' may open an external program or a
|
;; `markdown-follow-thing-at-point' may open an external program or a
|
||||||
;; buffer. No good way to tell, so pretend it's async.
|
;; buffer. No good way to tell, so pretend it's async.
|
||||||
|
|
|
@ -20,10 +20,6 @@
|
||||||
(setq tuareg-opam-insinuate t)
|
(setq tuareg-opam-insinuate t)
|
||||||
(tuareg-opam-update-env (tuareg-opam-current-compiler))
|
(tuareg-opam-update-env (tuareg-opam-current-compiler))
|
||||||
|
|
||||||
;; Spell-check comments
|
|
||||||
(when (featurep! :checkers spell)
|
|
||||||
(add-hook 'tuareg-mode-local-vars-hook #'flyspell-prog-mode))
|
|
||||||
|
|
||||||
(setq-hook! 'tuareg-mode-hook
|
(setq-hook! 'tuareg-mode-hook
|
||||||
comment-line-break-function #'+ocaml/comment-indent-new-line)
|
comment-line-break-function #'+ocaml/comment-indent-new-line)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue