24.7.2 基于搜索的字体高亮

直接控制基于搜索的字体高亮的变量是 font-lock-keywords,该变量通常通过 font-lock-defaults 中的 keywords 元素指定。

Variable: font-lock-keywords

该变量的值为需要高亮的关键字列表。Lisp 程序不应直接设置此变量。通常情况下,该值由字体锁定模式根据 font-lock-defaults 中的 keywords 元素自动设置。 也可以通过函数 font-lock-add-keywordsfont-lock-remove-keywords 修改其值(see 自定义基于搜索的字体高亮)。

font-lock-keywords 中的每个元素都指定了如何查找特定文本 以及如何对其进行高亮。字体锁定模式会依次处理 font-lock-keywords 中的各个元素,并对每个元素查找并处理所有匹配项。 通常,一段文本一旦已经完成高亮,就不会被同一段落中后续的匹配覆盖; 但你可以通过 subexp-highlighter 中的 override 元素指定不同行为。

font-lock-keywords 中的每个元素应采用以下形式之一:

regexp

使用 font-lock-keyword-face 高亮 regexp 的所有匹配项。例如:

;; Highlight occurrences of the word ‘foo
;; using font-lock-keyword-face.
"\\<foo\\>"

编写此类正则表达式时需谨慎;拙劣的匹配模式会显著降低运行速度! 函数 regexp-opt(see Regular Expression Functions)可用于生成匹配多个关键字的最优正则表达式。

function

通过调用 function 查找文本,并使用 font-lock-keyword-face 高亮其找到的匹配项。

调用 function 时会传入一个参数,即搜索的边界位置; 函数应从当前点开始搜索,且不超出该边界。 若搜索成功则返回非 nil,并设置匹配数据以描述找到的匹配项。 返回 nil 表示搜索失败。

字体高亮会以相同边界、在前一次调用结束的位置反复调用 function,直到 function 失败为止。 失败时,function 无需以特定方式重置当前点。

(matcher . subexp)

在这类元素中,matcher 为正则表达式或函数(同上)。 其 CDR 部分 subexp 指定应高亮 matcher 的哪个子表达式 (而非 matcher 匹配的整个文本)。

;; Highlight the ‘bar’ in each occurrence of ‘fubar’,
;; using font-lock-keyword-face.
("fu\\(bar\\)" . 1)
(matcher . facespec)

在这类元素中,facespec 是一个表达式,其值指定用于高亮的外观。 最简单的情况下,facespec 是一个 Lisp 变量(符号),其值为外观名称。

;; Highlight occurrences of ‘fubar’,
;; using the face which is the value of fubar-face.
("fubar" . fubar-face)

不过,facespec 也可以求值为如下形式的列表:

(subexp
(face face prop1 val1 prop2 val2...))

用于为匹配的文本指定外观 face 以及各种附加文本属性。 如果这样做,务必将通过该方式设置的其他文本属性名加入 font-lock-extra-managed-props 的值中,以便这些属性在不再适用时也能被清除。 或者,你可以将变量 font-lock-unfontify-region-function 设置为一个负责清除这些属性的函数。See 字体锁定其他变量

(matcher . subexp-highlighter)

在这类元素中,subexp-highlighter 是一个列表, 用于指定如何高亮 matcher 找到的匹配项。 其形式为:

(subexp facespec [override [laxmatch]])

CAR 部分 subexp 是一个整数,指定高亮匹配项中的哪个子表达式 (0 表示整个匹配文本)。第二个子元素 facespec 是一个表达式,其值指定外观,同上所述。

subexp-highlighter 中的最后两个值 overridelaxmatch 是可选标志。若 overridet, 则该元素可以覆盖 font-lock-keywords 中先前元素已设置的高亮。 若为 keep,则仅对尚未被其他元素高亮的字符进行高亮。 若为 prepend,则 facespec 指定的外观会添加到 font-lock-face 属性的开头。若为 append, 则外观添加到 font-lock-face 属性的末尾。

laxmatch 为非 nil,表示当 matcher 中不存在编号为 subexp 的子表达式时不报错。 显然,对应子表达式的高亮不会生效,但其他子表达式 (以及其他正则表达式)的高亮仍会继续。若 laxmatchnil 且指定子表达式缺失,则会抛出错误并终止基于搜索的高亮。

以下是此类元素的若干示例及其作用:

;; 高亮 ‘foo’ 或 ‘bar’ 的出现,使用
;; foo-bar-face,即使它们已被高亮。
;; foo-bar-face 应为值为外观的变量。
("foo\\|bar" 0 foo-bar-face t)

;; 高亮函数 fubar-match 找到的每个匹配项中的第一个子表达式,
;; 使用 fubar-face 的值所表示的外观。
(fubar-match 1 fubar-face)
(matcher . anchored-highlighter)

在这类元素中,anchored-highlighter 指定如何高亮 matcher 匹配项之后的文本。因此 matcher 找到的匹配项会作为锚点,供 anchored-highlighter 中定义的后续搜索使用。anchored-highlighter 是如下形式的列表:

(anchored-matcher pre-form post-form subexp-highlighters...)

其中,anchored-matchermatcher 类似, 可以是正则表达式或函数。在找到 matcher 的匹配项后, 当前点位于匹配项末尾。随后,字体锁定模式求值 pre-form, 接着搜索 anchored-matcher 的匹配项并使用 subexp-highlighters 进行高亮。subexp-highlighter 的定义同上。最后,字体锁定模式求值 post-form

pre-formpost-form 可用于在使用 anchored-matcher 之前进行初始化、之后进行清理。 典型用法是在开始 anchored-matcher 之前, 通过 pre-form 将当前点移动到 matcher 匹配项的相对位置。post-form 则可用于在恢复 matcher 搜索之前移回原位。

字体锁定模式在求值 pre-form 后, 不会在行尾之外搜索 anchored-matcher。 但如果 pre-form 求值后返回的缓冲区位置大于当前点位置, 则以该返回位置作为搜索边界。通常不建议返回超出行尾的位置; 也就是说,anchored-matcher 的搜索不应跨行。

例如:

;; Highlight occurrences of the word ‘item’ following
;; an occurrence of the word ‘anchor’ (on the same line)
;; in the value of item-face.
("\\<anchor\\>" "\\<item\\>" nil nil (0 item-face))

此处 pre-formpost-form 均为 nil。 因此对 ‘item’ 的搜索从 ‘anchor’ 匹配项的末尾开始,而后续 ‘anchor’ 的搜索 则从 ‘item’ 搜索结束的位置继续。

(matcher highlighters…)

这类元素为单个 matcher 指定多个 highlighter 列表。 highlighter 列表可以是上述 subexp-highlighteranchored-highlighter 类型。

例如:

;; Highlight occurrences of the word ‘anchor’ in the value
;; of anchor-face, and subsequent occurrences of the word
;; item’ (on the same line) in the value of item-face.
("\\<anchor\\>" (0 anchor-face)
                ("\\<item\\>" nil nil (0 item-face)))
(eval . form)

此处 form 是一个表达式,会在缓冲区首次使用此 font-lock-keywords 值时求值。 其结果应为本表格中所列形式之一。

警告: 不要设计跨行匹配文本的 font-lock-keywords 元素;此类方式无法可靠工作。 详情参见 see 多行字体锁定结构

你可以在 font-lock-defaults 中使用 case-fold 指定 font-lock-keywords-case-fold-search 的值, 该变量决定基于搜索的高亮是否忽略大小写。

Variable: font-lock-keywords-case-fold-search

nil 表示为 font-lock-keywords 进行的正则表达式匹配应忽略大小写。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike