3

I've been playing with flyspell lately and with my recently established setup for spell-check, I wanted to enable it for all modes. I found that flyspell-mode and flyspell-prog-mode are best for text-mode and prog-mode respectively and found in an answer to a similar question that it can be done as:

(add-hook 'text-mode-hook 'flyspell-mode) (add-hook 'prog-mode-hook 'flyspell-prog-mode) 

I've done the same thing but have noticed that for both the cases, flyspell-mode gets enabled and the flyspell-prog-mode doesn't get enabled at all. My code can be found here and it's the exact same as suggested.

Any help would be appreciated.

1 Answer 1

4

To help answer this question, we can perform the following steps:

  1. Load the flyspell.el library by typing M: aka M-x eval-expression, and then (require 'flyspell)

  2. Locate the source code for the function flyspell-prog-mode by typing:

    M-x find-function RET flyspell-prog-mode RET

Step two leads us to the source code of the function flyspell-prog-mode, which looks like this in Emacs 26:

(defun flyspell-prog-mode () "Turn on `flyspell-mode' for comments and strings." (interactive) (setq flyspell-generic-check-word-predicate #'flyspell-generic-progmode-verify) (setq-local flyspell--prev-meta-tab-binding (or (local-key-binding "\M-\t" t) (global-key-binding "\M-\t" t))) (flyspell-mode 1) (run-hooks 'flyspell-prog-mode-hook)) 

Based upon our review of the source code, we now know that flsypell-mode is activated when calling flyspell-prog-mode, which is the second to the last line that reads: (flyspell-mode 1). And, we see that two variables are expressly set when calling flyspell-prog-mode; i.e., flyspell-generic-check-word-predicate and flyspell--prev-meta-tab-binding. We observe that flyspell--prev-meta-tab-binding is set on a buffer-local basis with setq-local.

We see that flyspell-generic-check-word-predicate is set with setq and we wonder to ourselves whether that variable is buffer-local already or whether the value is being modified on a global basis. To satisfy our curiosity, we look up the variable with C-h v aka M-x describe-variable. We read the *Help* buffer and see that this variable was already buffer-local and we surmise that this is the reason why setq was used when setting the aforementioned variable in the function flyspell-prog-mode -- the *Help* buffer states in relevant part: "Automatically becomes buffer-local when set."

CONCLUSION:  flyspell-prog-mode is not really a mode per se; i.e., it is not a minor-mode and it is not a major-mode. Instead, it is just flyspell-mode plus the setting of two variables on a buffer-local basis; i.e., flyspell-generic-check-word-predicate and flyspell--prev-meta-tab-binding. flyspell-generic-check-word-predicate is set with the value of a function named flyspell-generic-progmode-verify. flyspell--prev-meta-tab-binding is a keyboard shortcut. The hook flyspell-prog-mode-hook has no default value, but we could add anything that is appropriate; e.g., (add-hook 'flyspell-prog-mode-hook (lambda () (message "Turned on flyspell-prog-mode ...")))

3
  • I had a suspicion but that shows the proof! However, as per the description, flyspell-prog-mode is supposed to only run spell-check on comments and strings in a program buffer, but I see that it's trying to run it for language keywords like defvar and progn as well for my Lisp files. Do you think I missed something? Commented Dec 13, 2019 at 15:46
  • I am unable to duplicate the results you are seeing. I open Emacs 26 on OSX without any user-configuration and evaluate the following snippet: (progn (require 'flyspell) (setq ispell-program-name "/absolute/path/to/the/executable/of/aspell") (find-library "flyspell") (flyspell-prog-mode)) Then, I use isearch by typing C-s and then enter the word defvar and am transported to the first occurrence which is just before flyspell-mode-map, and then I press RET to exit ispell and leave the cursor right where it is. When I place the cursor anywhere on the word defvar, no error. Commented Dec 14, 2019 at 1:29
  • I have the same result (i.e., no spelling error detected) when I use the following snippet in a .emacs file without any additional user-configuration: (require 'flyspell) (add-hook 'prog-mode-hook 'flyspell-prog-mode) (setq ispell-program-name "/absolute/path/to/the/executable/of/aspell") (add-hook 'emacs-startup-hook (lambda () (with-current-buffer (find-library "flyspell") (re-search-forward "defvar" nil t)))) If there are other buffers that have focus, then switch to the flyspell.el buffer and maneuver the cursor over the word defvar -- I see no misspelling indicated. Commented Dec 14, 2019 at 1:46

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.