2

I use mmm-mode in order to add python code in LaTeX. So i have something like this in my emacs config:

(use-package mmm-mode
  :ensure t
  :config
    (mmm-add-group 'latex-python
           '((latex-python-envs
            :submode python-mode
            :face mmm-default-submode-face
            :front "\\\\begin{\\(pycode\\|pyverbatim\\)}.*\n"
            :back "\\\\end{~1}\n"
            :save-matches 1)

       (latex-python-cmds
        :submode python-mode
        :face mmm-default-submode-face
        :front "\\\\pyc?{"
        :back "}")))
    (setq mmm-global-mode 'maybe)
    (mmm-add-mode-ext-class 'latex-mode nil 'latex-python))

It works, namely the python code is highlighted and formatted in the block between begin{pycode} end{pycode}

However, flyspell does not recognize the python mode in the block, so it thinks that errors are almost everywhere. The code is highlighted as erroneous. How to tell flyspell that the block has python code?

RCV
  • 105
  • 6
  • Note: Setting `ispell-skip-region-alist` or `ispell-tex-skip-alists` works for ispell but **not for flyspell**. – Tobias Aug 15 '18 at 13:09

1 Answers1

1

If the overlays for the Python blocks are already placed by mmm-mode you can skip misspelled words by detecting overlays with property mmm-mode equal to python-mode in flyspell-incorrect-hook.

Put the following elisp code in your init file. Restart and try.

(defun my-flyspell-latex-skip-python (b e corr)
  "Return t if in overlay with property mmm-mode value python.
Hook this function to `flyspell-incorrect-hook' buffer-locally in LaTeX buffers."
  (cl-loop for ol in (overlays-at b)
       if (eq (overlay-get ol 'mmm-mode) 'python-mode)
       return t
       finally return nil))

(defun my-flyspell-latex-skip-python-hook-fun ()
  "Do not flyspell python blocks in LaTeX documents.
Add this function to `LaTeX-mode-hook'."
  (add-hook 'flyspell-incorrect-hook #'my-flyspell-latex-skip-python nil t))

(add-hook 'LaTeX-mode-hook #'my-flyspell-latex-skip-python-hook-fun)

Tested with GNU Emacs 26.1 (build 1, x86_64-unknown-cygwin, GTK+ Version 3.22.28) of 2018-05-28 run by the command emacs -Q and with the following LaTeX-file.

Note that you need to run M-x package-initialize RET and the config code from the question and the elisp above must be evaluated before the test.

\documentclass{article}

\begin{document}
Some text. idfji jdfij 
\begin{pycode}
  for i in 1:n
    print "test %s" % "xyz ijk"
\end{pycode}

Some more text.
\begin{pyverbatim}
  for i in 1:n
    print "xyz ijk lmn"
\end{pyverbatim}

Some more text syhzdfja kljfi.

\end{document}

Test result:

Skip Python blocks when running flyspell.

Tobias
  • 32,569
  • 1
  • 34
  • 75
  • Thank you for your help. I get the following i the Message buffer: "Blocking call to accept-process-output with quit inhibited!!" and the hack doesnot work. – RCV Aug 15 '18 at 16:02
  • @RCV Could you test according to the above instructions? – Tobias Aug 15 '18 at 16:23
  • It works, but in my configuration it doesnot. In my config, flyspell starts automatically every time I open tex file. In that situation the hack doesnot work. If I restart flyspell, everything works perfectly. I am trying to find what is the problem. – RCV Aug 16 '18 at 17:35