Skip to content

Distraction-free words correction with flyspell via selected interface.

License

Notifications You must be signed in to change notification settings

d12frosted/flyspell-correct

Repository files navigation

Banner

flyspell-correct

https://github.com/d12frosted/flyspell-correct/workflows/CI/badge.svg

flyspell-correcthttp://melpa.org/packages/flyspell-correct-badge.svghttps://stable.melpa.org/packages/flyspell-correct-badge.svg
flyspell-correct-ivyhttp://melpa.org/packages/flyspell-correct-ivy-badge.svghttps://stable.melpa.org/packages/flyspell-correct-ivy-badge.svg
flyspell-correct-helmhttp://melpa.org/packages/flyspell-correct-helm-badge.svghttps://stable.melpa.org/packages/flyspell-correct-helm-badge.svg
flyspell-correct-popuphttp://melpa.org/packages/flyspell-correct-popup-badge.svghttps://stable.melpa.org/packages/flyspell-correct-popup-badge.svg
flyspell-correct-avy-menuhttp://melpa.org/packages/flyspell-correct-avy-menu-badge.svghttps://stable.melpa.org/packages/flyspell-correct-avy-menu-badge.svg

Correcting misspelled words with flyspell using favourite interface.

flyspell-correct provides several functions to start the correction process:

  • flyspell-correct-wrapper - by default jumps to the first misspelled word before the point and prompts for correction and gets you back. Calling it with C-u gives ability to correct multiple misspelled words in one run. C-u C-u changes direction. C-u C-u C-u changes direction and enables multiple corrections.
  • flyspell-correct-at-point - to correct word at point.
  • flyspell-correct-previous to correct any visible word before the point.
  • flyspell-correct-next to correct any visible word after the point.

In most cases flyspell-correct-wrapper is the most convenient, so don’t forget to bind it.

(define-key flyspell-mode-map (kbd "C-;") #'flyspell-correct-wrapper)

Most interfaces also allow you to save the new word to your dictionary, accept this spelling in current buffer or for a whole session, or even skip this word (useful in a rapid flow).

flyspell-correct comes with default interface, which uses completing-read. If you use Ivy, Helm or Ido as completion system you probably want to replace the default interface with the specialized interface. All additional interfaces come in separate packages:

Table of contents

Rapid mode

A so called ‘rapid mode’ means that you can correct multiple words in a single invocation of flyspell-correct-wrapper following current direction (usually, backwards). In order to enable it, one should call flyspell-correct-wrapper with universal argument - C-u. For example, C-u C-; will enable it.

flyspell-correct-completing-read interface

In order to use flyspell-correct-completing-read interface you have to install flyspell-correct package in any preferred way and then add following snippet to relevant part of your init.el file.

(require 'flyspell-correct)
(define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper)

Or via use-package.

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

If you do not want any binding, just replace :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)) with :defer t to use lazy loading.

In order to select the (s)ave, (a)ccept, sto(p) or s(k)ip actions, you can enter the shortcut key @s, @a, @p or @k. The actions will be automatically submitted. Furthermore suggestions can be quickly submitted by entering the numeric index in front of the suggestion. Besides the quick keys the usual completing-read interface is available, which may be enhanced and allow scrolling through candidates if you have a completion UI like Icomplete-vertical, Selectrum or Vertico installed.

flyspell-correct-ivy interface

In order to use flyspell-correct-ivy interface you have to install flyspell-correct-ivy package in any preferred way and then add following snippet to relevant part of your init.el file.

(require 'flyspell-correct-ivy)
(define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper)

Or via use-package.

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-ivy
  :after flyspell-correct)

If you do not want any binding, just replace :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)) with :defer t to use lazy loading.

Note that in order to access actions in ivy interface you need to press M-o. More on ivy mini buffer key bindings you can read in official documentation.

flyspell-correct-avy-menu interface

In order to use flyspell-correct-avy-menu interface you have to install flyspell-correct-avy-menu package in any preferred way and then add following snippet to relevant part of your init.el file.

(require 'flyspell-correct-avy-menu)
(define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper)

Or via use-package.

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-avy-menu
  :after flyspell-correct)

If you do not want any binding, just replace :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)) with :defer t to use lazy loading.

flyspell-correct-ido interface

In order to use flyspell-correct interface you have to install flyspell-correct-ido package in any preferred way and then add following snippet to relevant part of your init.el file.

(require 'flyspell-correct)
(require 'flyspell-correct-ido)
(define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper)

Or via use-package.

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-ido
  :after flyspell-correct)

If you do not want any binding, just replace :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)) with :defer t to use lazy loading.

flyspell-correct-helm interface

In order to use flyspell-correct-helm interface you have to install flyspell-correct-helm package in any preferred way and then add following snippet to relevant part of your init.el file.

(require 'flyspell-correct-helm)
(define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper)

Or via use-package.

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-helm
  :after flyspell-correct)

If you do not want any binding, just replace :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)) with :defer t to use lazy loading.

flyspell-correct-popup interface

In order to use flyspell-correct-popup interface you have to install flyspell-correct-popup package in any preferred way and then add following snippet to relevant part of your init.el file.

(require 'flyspell-correct-popup)
(define-key flyspell-mode-map (kbd "C-;") 'flyspell-correct-wrapper)

Or via use-package.

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-popup
  :after flyspell-correct)

If you do not want any binding, just replace :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)) with :defer t to use lazy loading.

There are some cool usability suggestions by @alphapapa shared in d12frosted/flyspell-correct#30 that you might want to use. Enjoy!

Deprecations

Deprecations in v0.5

Unfortunately, the following functions are renamed.

  • flyspell-correct-next-word-generic -> flyspell-correct-next
  • flyspell-correct-previous-word-generic -> flyspell-correct-previous
  • flyspell-correct-word-generic -> flyspell-correct-at-point

Please make sure to update to new names.

Custom interfaces

One can easily implement custom interface for flyspell-correct. It has to be a function accepting two arguments:

  • candidates for correction (list of strings)
  • misspelled word (string)

Result must be either a string (replacement word) or a cons of a command and a string (replacement word), where the command is one of the following:

  • skip - do nothing to misspelled word, in rapid mode used for jumping to the next (or previous) misspelled word
  • break - do nothing to misspelled word, break from rapid mode
  • stop - do nothing to misspelled word, break from rapid mode (if enabled) and leave the point at the misspelled word
  • save - replace misspelled word with replacement word and save it to the personal dictionary
  • session - replace misspelled word with replacement word and save it to the session dictionary (correction will be discarded upon quitting Emacs)
  • buffer - replace misspelled word with replacement word and save it to the buffer dictionary (added to the bottom of buffer)

Check any existing interface for reference.

Highlighting

The word that is being currently corrected (e.g. you are selecting the correction for misspelled word) is highlighted with flyspell-correct-highlight-face. If you wish to disable extra highlighting, just set the value of flyspell-correct-highlight to nil.

(setq flyspell-correct-highlight nil)

Auto correction mode

/Take my advice and don’t use this functionality unless you find flyspell-correct-wrapper function useless for your purposes. You can find more info in this comment.

This package also provides auto correction minor mode called flyspell-correct-auto-mode. When enabled it will automatically invoke flyspell-correct-previous-word-generic after certain delay configured by flyspell-correct-auto-delay when there is at least one incorrect word.

(add-hook 'flyspell-mode-hook #'flyspell-correct-auto-mode)

One can also configure interface specially for flyspell-correct-previous-word-generic called by flyspell-correct-auto-mode by setting value of flyspell-correct-auto-mode-interface.

Reasoning

There are already packages like helm-flyspell and flyspell-popup. So why would anyone create yet another similar package? The reason is simple - to support another interface or completion system. flyspell-correct started because ivy was missing similar to helm-flyspell package. But I didn’t want to create a package just for ivy. The reasoning is simple - all those packages should have similar functionality but different interface. Adding something new to one of these packages ideally should be reflected in all others. So I decided to create generic package that works with any interfaces. It’s not about one package containing all possible interfaces, but about a package giving you functionality with an interface of your choice.

And over the time, flyspell-correct got some killer features (like quick access to misspelled words from anywhere), rapid mode and some others.

Screenshots

Ivy interface

images/screenshot-ivy-1.png

images/screenshot-ivy-2.png

Avy Menu interface

images/screenshot-avy-menu.png

Popup interface

images/screenshot-popup.png

Helm interface

images/screenshot-helm.png

Ido interface

images/screenshot-ido.png

completing-read interface

images/screenshot-completing-read.png

Acknowledgements

This package is available thanks to these people:

Additional thanks to all contributors: