如何为 major-mode 定义自己的 flyspell 模式

发布于 2023-02-25 21:52:00 字数 2409 浏览 91 评论 0

flyspell 可以为我们提供实时的命令拼写检查。但是 Emacs 的各种 major-mode 都有各自的语法规则,flyspell 可能会错误地把语法关键字当成是单词进行检测,这时就需要我们告诉 flyspell 哪些内容是需要检查的,那些内容是不需要检查的。

通过阅读 flyspell 的源代码,可以看出它是通过 flyspell-generic-check-word-predicate 来判断是否需要对单词进行拼写检查的。这个变量的 doc-string 是这样描述的

  Automatically becomes buffer-local when set.
  This variable may be risky if used as a file-local variable.

Documentation:
Function providing per-mode customization over which words are flyspelled.
Returns t to continue checking, nil otherwise.
Flyspell mode sets this variable to whatever is the ‘flyspell-mode-predicate’
property of the major mode name.

从中可以看出,我们只需要为写好一个判断函数,判断当前位置的单词是否需要进行拼写检查,然后将这个判断函数设置为某个 major-modeflyspell-mode-predicate 就行了。

这里有个诀窍,判断函数一般可以通过 text-property 的 face 来判断是否需要进行拼写检查。 比如 flyspell-prog-mode 就是通过 text-property 的 face 来判断哪些内容是属于字符串或注释的,像下面这样:

(defvar flyspell-prog-text-faces
  '(font-lock-string-face font-lock-comment-face font-lock-doc-face)
  "Faces corresponding to text in programming-mode buffers.")

(defun flyspell-generic-progmode-verify ()
  "Used for `flyspell-generic-check-word-predicate' in programming modes."
  ;; (point) is next char after the word. Must check one char before.
  (let ((f (get-text-property (- (point) 1) 'face)))
    (memq f flyspell-prog-text-faces)))

;;;###autoload
(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))

类似的,我们也可以为其他 major-mode 定义哪些内容需要进行单词拼写检测。比如下面的代码可以忽略对 outline 大纲标题的单词拼写

(defvar flyspell-outline-ignore-faces
  '(outline-1 outline-2 outline-3 outline-4 outline-5 outline-5 outline-7 outline-8)
  "Faces corresponding to text in outline-mode buffers.")

(defun flyspell-outline-verify ()
  "Used for `flyspell-generic-check-word-predicate' in outline modes."
  ;; (point) is next char after the word. Must check one char before.
  (let ((f (get-text-property (- (point) 1) 'face)))
    (not (memq f flyspell-outline-ignore-faces))))

(put 'outline-mode 'flyspell-mode-predicate 'web-mode-flyspell-verify)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

拍不死你

暂无简介

文章
评论
603 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文