Jump back to previous typo.

We recently looked at using flyspell to quickly fix the most recent typo with C-;. Sometimes flyspell can’t find a correction for the word you want, so you need to fix it by hand.

Flyspell offers the function flyspell-goto-next-error which moves the point forward to the next error, and is bound to C-, (although this keybinding is taken over in org-mode). However, I only want to move back to the previous error, but flyspell offers no function for this. This is easily fixed with a very slightly modified version of the code from this answer by hatschipuh on stackexchange.

This code jumps you to the end of the most recent misspelled word.

;; move point to previous error
;; based on code by hatschipuh at
;; http://emacs.stackexchange.com/a/14912/2017
(defun flyspell-goto-previous-error (arg)
  "Go to arg previous spelling error."
  (interactive "p")
  (while (not (= 0 arg))
    (let ((pos (point))
          (min (point-min)))
      (if (and (eq (current-buffer) flyspell-old-buffer-error)
               (eq pos flyspell-old-pos-error))
          (progn
            (if (= flyspell-old-pos-error min)
                ;; goto beginning of buffer
                (progn
                  (message "Restarting from end of buffer")
                  (goto-char (point-max)))
              (backward-word 1))
            (setq pos (point))))
      ;; seek the next error
      (while (and (> pos min)
                  (let ((ovs (overlays-at pos))
                        (r '()))
                    (while (and (not r) (consp ovs))
                      (if (flyspell-overlay-p (car ovs))
                          (setq r t)
                        (setq ovs (cdr ovs))))
                    (not r)))
        (backward-word 1)
        (setq pos (point)))
      ;; save the current location for next invocation
      (setq arg (1- arg))
      (setq flyspell-old-pos-error pos)
      (setq flyspell-old-buffer-error (current-buffer))
      (goto-char pos)
      (if (= pos min)
          (progn
            (message "No more miss-spelled word!")
            (setq arg 0))
        (forward-word)))))

I bind this to C-, to replace flyspell-goto-next-error. See this stackexchange question for methods to ensure your keybinding overrides the bindings by major modes like org.

  • Pingback: Move Back to Last Misspelling | Irreal()

  • Cézar Antáres

    Hi, thanks for explaining how to achieve this, however I have a question, what modification do I need to do in order to place the cursor at the beginning of the misspelled word instead of after it? This is because I use evil and is very handy for me just do “ciw” to fix the word. Thanks.

    • Just remove the final `(forward-word)` function call at the end of that code.

      • Cézar Antáres

        Thanks, worked perfectly!