如何在Emacs中为所有文件和主要模式启用flyspell-mode?

20

如何在Emacs启动时自动为每个文件和每个主要模式启用flyspell-mode?

此外,是否有一个XML词典不会将XML标记标记为拼写错误单词?


如果您仍然活跃,将您的接受答案更改为https://dev59.com/s2w15IYBdhLWcg3wD3Zk#20078310可能会有所帮助,因为它显然是您问题的正确答案,并且可能是人们看到的第一个答案。 - Shon
5个回答

28

这个问题的答案对我有用:

如何默认启用自动拼写检查?

此外,与其他先前的答案相比,它似乎更为普遍。将以下行添加到您的.emacsinit.el

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

这对我来说完美运行,在Text WS、Markdown WS、Tex WS和Python WS上进行了测试,表现如预期。 - Sam Lanning

17

你可能并不想在所有模式下启用flyspell-mode,而是希望在主要处理文本的模式(text-mode、message-mode等)中启用flyspell-mode,在编程模式(C/C++、Java、Ruby、Lisp等)中启用flyspell-prog-mode。两种模式的区别在于前者检查所有单词,而flyspell-prog-mode仅检查注释和字符串中的单词(从而避免检查代码,因为代码通常不是单词)。

无论哪种方式,都没有一个单一的位置可以在所有文件/缓冲区中启用flyspell,因为它始终被编写为局部缓冲区。一个近似的方法是

(defun turn-on-flyspell () (flyspell-mode 1))
(add-hook 'find-file-hooks 'turn-on-flyspell)

这并不能涵盖没有关联文件的缓冲区,而且我不建议使用它,因为它无法区分编程模式和非编程模式 - 而我认为这很有用。

由于无法知道某些模式是否是编程模式,您需要手动添加所有您关心的编程模式的自定义内容,例如:

(mapcar (lambda (mode-hook) (add-hook mode-hook 'flyspell-prog-mode))
        '(c-mode-common-hook tcl-mode-hook emacs-lisp-mode-hook 
          ruby-mode-hook java-mode-hook))

注意:这两段代码可能不兼容。

关于 XML,flyspell已经针对sgml-modehtml-modenxml-mode进行了定制,以不检查标记拼写(自 Emacs 23.2 起)。如果您使用的是较旧版本的 Emacs(回溯到21.1),则可以将以下内容添加到您的 .emacs 文件中,以获取对 nxml-mode 的支持:

(put 'nxml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)

我正在使用nXml-mode。因此,如果我想要例如flyspell自动打开所有markdown文件,我可以使用类似这样的东西吗?(add-hook 'markdown-mode-hook' flyspell-mode) - mart1n
在 Emacs 24 中包含的 flyspell 版本中,以下行也被包括在内,以禁用 nxml 模式下 xml 标签的检查:(put 'nxml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify) - zev
我正在使用Emacs 23。但是,(add-hook 'markdown-mode-hook 'flyspell-mode) 这样做可以正确地为所有的markdown文件启用flyspell-mode吗? - mart1n
markdown-mode 是一种不同于 nxml-mode 的模式,所以不会有任何作用(我相信)你所询问的那个钩子。 - Trey Jackson
是的,但我会打开 flyspell-prog-mode。并且还要添加一行(put 'nxml-mode'flyspell-mode-predicate' sgml-mode-flyspell-verify) - 因为这对XML进行了一些额外的调整(这正是您想要的)。 - Trey Jackson
显示剩余2条评论

3
你可以将以下代码添加到你的Emacs初始化文件中:
(flyspell-all-modes)
函数说明如下:
使用Flyspell在所有主要模式下。适用于现有缓冲区和随后创建的缓冲区。如果启用,会关闭'flyspell-text-modes'。
注意:显然上述函数仅包含在Emacs 24版本的flyspell中。如果您无法使用该版本,则应使用Trey建议的"半全局"启用flyspell的解决方案。要在NXML中禁用XML标记检查,可以将以下行添加到Emacs初始化文件中:
(put 'nxml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)

注意:这行代码已经包含在Emacs 24中的flyspell.el文件中。

这个定义在哪里?我在最新的flyspell.el(1.70)http://www-sop.inria.fr/members/Manuel.Serrano/flyspell/flyspell.html和Emacs 23.2附带的版本中都没有看到。 - Trey Jackson
另外,我的问题是,我没有看到这样的选项在任何地方有记录。 - mart1n
它在 Emacs 24 中包含的 flyspell.el 文件中。 - zev
2
嘿,使用尚未正式发布的Emacs版本并不公平。 :P - Trey Jackson
2
实际上,我在Emacs 24.093中没有找到这个函数。 - RNA

1

我无法确定具体时间,但是 flyspell-mode 现在可以很好地知道它所处的模式并做出相应的反应。这是我的 use-package 实现,带有 company-completion 接口。

 (use-package flyspell :demand t
   :config
   (use-package 
     flyspell-correct-helm) 
   (defun flyspellCompletion() 
     (flyspell-mode 1) 
     (set (make-local-variable 'company-backends) 
          (copy-tree company-backends)) 
     (add-to-list 'company-backends 'company-ispell)) 
   (defun flyspell-most-modes() 
     (add-hook 'text-mode-hook 'flyspellCompletion) 
     (add-hook 'prog-mode-hook 'flyspellCompletion)
     (dolist (hook '(change-log-mode-hook log-edit-mode-hook)) 
       (add-hook hook (lambda () 
                        (flyspell-mode -1))))) 
   (flyspell-most-modes) 
   :bind (:map flyspell-mode-map
               ("C-." . flyspell-correct-wrapper)))

0
我在2021年10月使用Debian 11.1上的Emacs 27.1。我编写了一个函数,根据缓冲区的主要模式类型执行正确的操作,并将其挂钩到find-file-hook,该钩子对每个访问的文件运行。我将此作为其他答案的补充而不是替代品提供。原因如下:
  • 我发现flyspell-mode(无论是通过键绑定还是作为模式挂钩调用)并没有自动识别模式/缓冲区/文件类型,这与@RichieHH的答案相反。
  • 我发现flyspell-all-modes不存在,这与@zev的说法不符。
  • 我发现添加到text-mode-hookprog-mode-hook的建议,如@b4hand所述,只能解决部分问题,对于我打开的许多随机文件,它们以基本模式打开,Flyspell仍然关闭。
一个潜在的缺陷是,它无法运行与任何文件没有关联的缓冲区。显然没有好的方法来挂钩 "创建任何缓冲区"。不过如果被多次调用,函数应该发现 Flyspell 已经启用,并且不执行任何操作,所以您仍可以添加多个钩子而不会产生负面影响。因此,如果您愿意,可以将钩子添加到 text-mode-hook 和 prog-mode-hook 中。
(add-hook 'find-file-hook 'flyspell-on-for-buffer-type)

(defun flyspell-on-for-buffer-type ()
  (interactive)
  ;; if flyspell mode is not already on, turn it on
  (if (not (symbol-value flyspell-mode))
      (if (derived-mode-p 'prog-mode)
      (progn
        (message "Flyspell on (code)")
        (flyspell-prog-mode))
    (progn
      (message "Flyspell on (text)")
      (flyspell-mode 1)))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接