How to make flyspell bypass some words by context?
Asked Answered
B

3

10

I use Emacs for writing most of my writings. I write using reStructuredText, and then transform them to LaTeX after some preprocessing since I write my citations á-la LaTeX. This is an excerpt of one of my texts (in Spanish):

En \cite[pp.~XXVIII--XXIX]{Crnkovic2002} se brindan algunos riesgos
que se pueden asumir con el desarrollo basado en componentes, los

This text is processed by some custom scripts that deals with the \cite part so rst2latex can do its job.

When I activate flyspell-mode it signals most of the citation keys as spelling errors.

How can I tell flyspell not to spellcheck things within \cite commands.

Furthermore, how can I combine rst-mode and flyspell, so that rst-mode would keep flyspell from spellchecking the following?

  • reST comments
  • reST code literal
  • reST directive parameters and arguments
  • reST raw directive contents

Any ideas?

Blackguardly answered 12/1, 2011 at 17:31 Comment(0)
H
11

You can set the variable ispell-parser to the value 'tex so that flyspell will ignore (la)tex sequences. To do so, you can either set it manually in each buffer like so:

M-: (setq 'ispell-parser 'tex)

or you write a little function that will do that for you. Put the following in your .emacs file:

(defun flyspell-ignore-tex ()
  (interactive)
  (set (make-variable-buffer-local 'ispell-parser) 'tex))

Then you can still invoke it manually, using

M-x flyspell-ignore-tex

or you could add a hook that calls that function automatically whenever you edit a file of a certain type. You would do the latter by adding the newly defined function to your auto-mode-alist. Say your filenames typically end with ".rst", then add this line to your .emacs file:

(add-to-list 'auto-mode-alist '("\\.rst$" . flyspell-ignore-tex))

As for the second part of your question: making flyspell-mode ignore larger regions, such as, e.g., reST comments, is not easily achievable. It becomes clear when you think about the way flyspell works: it checks text on a word-by-word basis. For that, flyspell-word only looks at one word at a time which it sends to an ispell process running in the background. The ispell process does the dictionary lookup and returns whether or not the current word is correct. If flyspell-word had to check every single time whether or not the current word is part of a comment or other region that should not be checked, it would be rather slow, because that would include quite a bit of searching through the buffer.

Now of course, one could approach this a little bit smarter and first find the non-comment regions etc. and then do the word-by-word checking only in those parts that are outside of those regions - but unfortunately, that's not the way flyspell is implemented.

If you can do without the "fly" part, however, ispell-mode has a mechanism to customize which regions of a buffer can be skipped. This is done via the variable ispell-skip-region-alist. But although flyspell-mode works off ispell-mode, for the reasons outlined above that variable is not used by flyspell-mode.

Hallux answered 12/1, 2011 at 21:39 Comment(5)
Thomas, thanks a lot! I have used ispell-mode in the past, but flyspell suits me better at the moment. Nevertheless, after reading the ispell-skip-region-alist doc, I think I would have to program a function to detect the end of the comment. I'm not that familiar with Emacs Lisp yet. Anyway the ispell-parser way is still helpfull. Maybe I could check how its used and create my own ispell-parser tweek when I can.Blackguardly
Manu, you probably won't have to program a lisp function to detect the beginning and end of a comment. Typically a regular expression should be enough, one that matches the beginning and one that matches the end. You put both of them in parenthesis and add it to the ispell-skip-region-alist (I tried it out yesterday, it's actually not that difficult) and there's a good chance that rst-mode already contains the regexps you're looking for somewhere.Hallux
In reStructuredText the end of the code section is detected when the indentation level is decreased. So regexp would't help. Best regards, Manu.Blackguardly
Although for \cite it may help.Blackguardly
What should I do if I am using aspell instead like ((setq ispell-program-name "aspell"))? @HalluxHousewares
A
4

You can also use flyspell-generic-check-word-predicate as I explained in this question at Super User.

Affixation answered 11/10, 2011 at 21:2 Comment(0)
S
1

(aspell's tex filter may do exactly what you want - but if you want a more general solution)

Although I am using the code below to persuade flyspell to not flag certain words with numbers in them, you can use this sort of hook to match certain context.

looking-at starts at the position you want - so you may want to search backwards for start/end of whatever context you care about.

(when "another attempt to accept certain words flyspell/ispell/aspell flags as incorrect"
  (defun flyspell-ignore-WordNumber99-stuff/ag (beg end info)
    (save-excursion
      (goto-char beg)
      (cond
    ((or
       (looking-at "\\bWord1\\b")
       (looking-at "\\bWord99Foo\\b")
       )
      t)
    (t nil)
    )
      )
    )
  )

(add-hook 'flyspell-incorrect-hook 'flyspell-ignore-WordNumber99-stuff/ag)
Stanfordstang answered 19/6, 2014 at 2:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.