flyspell、emacs 和 aspell 似乎存在分歧

flyspell、emacs 和 aspell 似乎存在分歧

我在 .emacs 文件中对 aspell 使用以下配置

(setq ispell-program-name "/opt/local/bin/aspell")
(setq ispell-list-command "list")
(setq ispell-extra-args '("--dont-tex-check-comments"))

我的 ~/.aspell.conf 包含以下行

add-tex-command bibliographystyle p

尝试这个乳胶文件:

\documentclass{article}
\begin{document}
\bibliographystyle{plainnat}
\end{document}

emacs flyspell 模式向我显示 plainnat 错误。

在此处输入图片描述

当我使用以下命令从命令行调用 aspell 时

aspell --dont-tex-check-comments -c ~/test.tex

它没有显示任何错误。Flyspell 似乎不使用 aspell 或 aspell 配置。我该如何改变这种情况,以便我只需维护一个配置来满足我的拼写检查需求,而不需要为 flyspell 额外配置?

答案1

Flyspell 使用特定于模式的函数来flyspell-generic-check-word-predicate识别突出显示拼写错误时要忽略的区域。这比普通的自定义稍微复杂一些。

据我了解,有三个步骤。首先,将flyspell-mode-predicate的属性设置LaTeX-mode为自定义函数的名称。其次,定义一个函数,t当鼠标指针位于要忽略的单词上时,该函数将返回。第三,将钩子添加到LaTeX-mode定义flyspell-generic-check-word-predicate,以便在进入 LaTeX 模式时使用此新函数。

(顺序并不重要,只要在打开乳胶文件之前完成所有三个步骤即可。)

如果您不了解 elisp,那么这对您来说可能没有多大意义。将以下内容添加到您的 .emacs 文件并重新启动 Emacs 应该可以解决问题。如果您想添加要忽略的其他区域,则要处理的部分是表单(save-excursion ... )

(put 'LaTeX-mode 'flyspell-mode-predicate 'auctex-mode-flyspell-verify)
(defun auctex-mode-flyspell-verify ()
  "Function used for `flyspell-generic-check-word-predicate' in auctex mode."
  (save-excursion
    (forward-word -2)
    (not (looking-at "bibliographystyle{"))))

(add-hook 'LaTeX-mode-hook
  (lambda () (setq flyspell-generic-check-word-predicate    
    'auctex-mode-flyspell-verify)))            

答案2

更简单的解决方案是自定义变量flyspell-tex-command-regexp。默认值为

\(\(begin\|end\)[   ]*{\|\(cite[a-z*]*\|label\|ref\|eqref\|usepackage\|documentclass\)[     ]*\(\[[^]]*\]\)?{[^{}]*\)

只需附加\|bibliographystyle(阅读“或 bibliographystyle”),如下所示:

\(\(begin\|end\)[   ]*{\|\(cite[a-z*]*\|label\|ref\|eqref\|usepackage\|documentclass\|bibliographystyle\)[  ]*\(\[[^]]*\]\)?{[^{}]*\)

您可以bibliographystyle用您可能想要忽略其输入的其他命令来替换,例如newenvironment

答案3

这更像是一个长篇评论,而不是真正的答案。

这种行为比你描述的更令人困惑。我使用了你的文件,但在注释中添加了一个拼写错误的单词,并使用一个带有拼写错误的单词作为参数的“假” TeX 命令

\documentclass{article}
\begin{document}
\bibliographystyle{plainnat}
\bdfg{rwt}
\end{document}
% qwrx

我看到的行为:

  • 使用aspell -c test.tex这个选项会导致“plainnat”和“rwt”出错,但“qwrx”不会出错。我猜我的 aspell 不需要这个--dont-tex-check-comments选项。
  • 在 emacs 中使用ispell-buffer仅会出现“rwt”错误。
  • 在 emacs 中使用flyspell-buffer“plainnat”、“rwt”和“qwrx”会出现错误。
  • 在 emacs 中将点放在“qwrx”或“plainnat”上,然后使用ispell-wordflyspell-word会出现错误。
  • 在 emacs 中将点放在“bibliographystyle”或“bdfg”上,然后使用ispell-word会出现错误,但使用flyspell-word不会出现错误。
  • ispell-kill-ispell在运行命令之前,以上所有内容都经过了验证,以确保您从全新的 ispell 进程开始。但是,如果您使用 来对缓冲区进行拼写检查ispell-buffer,将“(a)ccept” “rwt” 作为此会话的 OK 词,然后运行flyspell-buffer​​,flyspell 将不再抱怨“rwt”

我认为,发生的情况是,这两种模式都不ispell会将flyspell整个缓冲区作为一个单元发送给 aspell,并要求它对其进行拼写检查 [1]。相反,这两种模式一次一个单词地浏览文件,并将每个单词发送给 aspell。虽然flyspell最终会调用该函数ispell-word来实际调用 aspell [2],但对哪些单词进行拼写检查的逻辑是不同的flyspellvs中ispell,两者都包含与 TeX/LaTeX 相关的逻辑,但逻辑并不相同。

因此 aspell 永远没有机会应用有关 TeX 命令及其参数的自定义规则,因为它没有意识到单词“plainnat”是 TeX 命令的一部分。

我使用的是 emacs 24.3、AUCTeX(尽管我不认为 AUCTeX 能真正改变这种行为)和 aspell 3.1.20。Cygwin。

[1] 这在 Tyler 的回答中是隐含的,但我认为值得非常明确地指出这一点,因为除非您理解这一点,否则 emacs 在这里的行为没有任何意义!

[2] 这可能解释了我最后一点中的行为。

相关内容