23

Imagine an org buffer in Emacs like:

* Title

Some text describing the title and the codew (sic) and whatnot.

#+BEGIN_SRC emacs_lisp
(setq backup-by-copying t)
#+END_SRC

I want flyspell to check the org buffer (and catch the spelling error in it) but ignore the content between the #+BEGIN_SRC and #+END_SRC marks. How does one go about that?

5
  • 2
    It looks like someone will need to write up some code using the flyspell-generic-check-word-predicate, if that hasn't already been invented. Here is a related thread for flyspell using the flyspell-generic-check-word-predicate: superuser.com/a/345461/206164 ; and, here is a semi-related thread for ispell using ispell-skip-region-alist, but not relating to flyspell: emacs.stackexchange.com/a/2103/2287
    – lawlist
    Commented Feb 18, 2015 at 6:54
  • can emacs.stackexchange.com/a/2103/2609 help?
    – Name
    Commented Feb 18, 2015 at 12:48
  • This question is a dupe of that one emacs.stackexchange.com/questions/450/…
    – grettke
    Commented Feb 18, 2015 at 16:53
  • 1
    @grettke: Seems like a dupe, but it's not. Changing the settings for Ispell does not actually solve the problem in Flyspell. At least not when I tried it.
    – Brian Z
    Commented Feb 19, 2015 at 7:25
  • It works out of the box in v8.3 when you require ox.
    – rasmus
    Commented Feb 19, 2015 at 16:15

1 Answer 1

15
;; NO spell check for embedded snippets
(defadvice org-mode-flyspell-verify (after org-mode-flyspell-verify-hack activate)
  (let* ((rlt ad-return-value)
         (begin-regexp "^[ \t]*#\\+begin_\\(src\\|html\\|latex\\|example\\|quote\\)")
         (end-regexp "^[ \t]*#\\+end_\\(src\\|html\\|latex\\|example\\|quote\\)")
         (case-fold-search t)
         b e)
    (when ad-return-value
      (save-excursion
        (setq b (re-search-backward begin-regexp nil t))
        (if b (setq e (re-search-forward end-regexp nil t))))
      (if (and b e (< (point) e)) (setq rlt nil)))
    (setq ad-return-value rlt)))

Please note ispell-skip-region-alist is NOT used by flyspell.

Test on Emacs24.3, 24.4, 24.5, 25.1 with builtin org-mode

Most users turn on flyspell by default. So above code is enough.

But I don't enable flyspell-mode in org file. I prefer manually M-x flyspell-buffer again and again. So I need (flyspell-mode 1) (flyspell-mode -1) in org-mode-hook. Yes, turn on then turn off flyspell-mode. The purpose is to make sure the org-mode's default predicate is loaded.

Please note flyspell-incorrect-hook is not the good place for per major mode configuration because it's shared by all major modes. So the heavy weight configuration code in one major mode could impact other major modes if the per major mode code is placed in flyspell-incorrect-hook.

flyspell has already provided flyspell-generic-check-word-predicate which is "Function providing per-mode customization over which words are flyspelled". It's buffer local variable so it safe to use out of box.

Screenshot of its definition from flyspell.el:

enter image description here

Besides, the predicate is more flexible than the hook because the predicate is tested at first. So if the predicate claims a word is not a typo, the hook will not be executed. Here is the screenshot of flyspell-word definition,

enter image description here

Actually, the default value of flyspell-generic-check-word-predicate in org-mode is org-mode-flyspell-verify.

The reason I advice org-mode-flyspell-verify is I'm lazy. I could change the value of the predicate to my own function which calls org-mode-flyspell-verify instead,

(defun org-mode-hook-setup ()
  (setq flyspell-generic-check-word-predicate
        (lambda ()
          (let* ((rlt (org-mode-flyspell-verify)))
            ;; do whatever on rlt below this line
            (message "rlt=%s" rlt)
            rlt))))
(add-hook 'org-mode-hook 'org-mode-hook-setup)
1
  • I suggest adding quote to the regexp, such as: ` (begin-regexp "^[ \t]*#\\+begin_\(src\\|html\\|latex\\|quote\)") (end-regexp "^[ \t]*#\\+end_\(src\\|html\\|latex\\|quote\)")` Commented Jun 26, 2015 at 1:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.