TransWikia.com

How to make emacs automatically spell check all visible text?

Emacs Asked on November 22, 2021

When flyspell is enabled it doesn’t show spelling errors on all visible text (like most text editors that support spell checking).

When moving the cursor over text, misspelled words become underlined.

While running flyspell-buffer works, it’s a manual operation and can be slow on large files.

Is there a way to run the spell checker on visible text, updating after scrolling?
Perhaps using delays so it doesn’t make scrolling lag.

2 Answers

There are minor modes that do just this, although they don't use flyspell.

spell-fu

Example use:

(use-package spell-fu)
(global-spell-fu-mode)

wcheck-mode

Example use:

(use-package wcheck-mode
  :commands (wcheck-mode)
  :init
  (custom-set-faces
    '(wcheck-default-face ((t (:underline (:color: "red" :style wave)))))
    )

  (setq wcheck-language-data
    '
    (
      ("American English"
        (program . "/usr/bin/enchant-2")
        (args "-l" "-d" "en_US")
        (action-program . "/usr/bin/enchant-2")
        (action-args "-a" "-d" "en_US")
        (action-parser . enchant-suggestions-menu)
        (read-or-skip-faces
          ;; Only check comments & strings.
          ((emacs-lisp-mode c-mode)
            read font-lock-comment-face
            read font-lock-string-face
            )
          (nil))
        )
      )
    )
  (setq wcheck-language "American English")
  )

speck-mode

Example use:

(load "speck")
(setq-default speck-syntactic t)  ;; Only check comments and strings.
(setq-default speck-engine 'Aspell)
(setq-default speck-delay 0.1)
(setq-default speck-pause 0.1)

(custom-set-faces
  '(speck-guess ((t (:underline (:color: "red" :style wave)))))
  '(speck-miss ((t (:underline (:color: "orange" :style wave)))))
  '(speck-doublet ((t (:underline (:color: "brown" :style wave)))))
  '(speck-mouse ((t (:underline (:color: "yellow" :style wave)))))
  '(speck-query ((t (:underline (:color: "or" :style wave)))))
  )
(setq speck-personal-dictionary-file ispell-personal-dictionary)

Answered by ideasman42 on November 22, 2021

For reference: The example below runs the spell checker on a timer, however it gives many messages:

Blocking call to accept-process-output with quit inhibited!!

.. Which I worked around by temporarily disabling logging, however this is far from ideal.

On the other hand, in practice I've found this to be usable.


(defvar-local flyspell-visible-last-window-range nil)

(defun flyspell-visible--overlay-refresh-from-timer ()
  (when (equal flyspell-visible--delay-buffer (current-buffer))
    (let*
      (
        (sta (window-start))
        (end (window-end))
        (range (list sta end))
        )
      (when (not (equal range flyspell-visible-last-window-range))
        (setq inhibit-redisplay t)

        (let
          ((log-max message-log-max))
          ;; don't log
          (setq message-log-max nil)
          (flyspell-region sta end)
          (setq message-log-max log-max)
          (message nil)
          )
        (setq-local flyspell-visible-last-window-range range)
        (setq inhibit-redisplay nil)
        )
      )
    )
  )

;; Timer
(defvar flyspell-visible--delay-timer nil)
(defvar flyspell-visible--delay-buffer nil)

(defun flyspell-visible-turn-on ()
  "Enable spell checking on a timer"
  (when (timerp flyspell-visible--delay-timer)
    (cancel-timer flyspell-visible--delay-timer))
  ;; Delay for spelling - should be ok, only runs when scroll changes.
  (setq flyspell-visible--delay-buffer (current-buffer))
  (setq flyspell-visible--delay-timer
    (run-with-idle-timer 1.0 t 'flyspell-visible--overlay-refresh-from-timer))
  )

(defun flyspell-visible-turn-off ()
  (when (timerp flyspell-visible--delay-timer)
    (cancel-timer flyspell-visible--delay-timer))
  (setq flyspell-visible--delay-timer nil)
  (setq flyspell-visible--delay-buffer nil)
  (setq flyspell-visible-last-window-range nil)
  )

Answered by ideasman42 on November 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP