42.12.2 定义文本视觉样式

定义文本视觉样式的常规方式是使用 defface 宏。该宏将文本视觉样式名称(符号)与默认 文本视觉样式规范(face spec) 关联。文本视觉样式规范用于指定文本视觉样式在不同终端上的属性;例如可在高色深终端指定一种前景色,在低色深终端指定另一种。

有人会试图创建值为文本视觉样式名称的变量。绝大多数情况下这并不必要;标准做法是用 defface 定义样式后直接使用其名称。

注意:一旦通过 defface 定义了文本视觉样式,除重启 Emacs 外无法安全取消定义。

Macro: defface face spec doc [keyword value]…

该宏将 face 声明为命名文本视觉样式,其默认规范由 spec 给出。无需引用符号 face,且名称不应以 ‘-face’ 结尾(冗余)。参数 doc 为文本视觉样式的文档字符串。额外的 keyword 参数含义与 defgroupdefcustom 相同(see 通用项关键字)。

face 已有默认规范,此宏不执行任何操作。

默认规范决定无自定义生效时文本视觉样式的外观(see 自定义设置)。若 face 已被自定义(通过自定义主题或初始化文件加载的设置),则外观由自定义规范决定并覆盖默认规范 spec。但后续移除自定义后,外观会再次由默认规范决定。

例外情况:在 Emacs Lisp 模式中使用 C-M-xeval-defun)或 C-x C-eeval-last-sexp)执行 defface 表单时,这些命令的特殊机制会覆盖该样式上的所有自定义规范,使其严格反映 defface 定义。

参数 spec文本视觉样式规范(face spec),说明样式在不同终端上的表现。它应为 alist,元素格式为:

(display . plist)

display 指定终端类型(见下文)。plist 为文本视觉样式属性及其值的属性列表,指定样式在该类终端上的表现。为兼容旧版,元素也可写作 (display plist)

spec 元素中的 display 决定匹配哪些终端。若多个元素匹配同一终端,使用第一个匹配项。display 有三种可能:

default

该元素不匹配任何终端;而是指定适用于所有终端的默认值。若使用该元素,必须为 spec 的第一个元素。后续每个元素均可覆盖部分或全部默认值。

t

该元素匹配所有终端。因此 spec 中后续元素永远不会生效。通常 t 用于 spec 的最后一个(或唯一一个)元素。

a list

display 为列表,每个元素格式为 (characteristic value…)。其中 characteristic 为终端分类方式,valuedisplay 适用的分类。characteristic 可选值:

type

终端使用的窗口系统类型—graphic(任意图形显示器)、xpc(MS-DOS 控制台)、w32(Windows 9X/NT/2K/XP)、haikupgtk(纯 GTK)、androidtty(非图形显示器)。See window-system.

class

终端支持的颜色类型—colorgrayscalemono

background

背景类型—lightdark

min-colors

整数,表示终端应支持的最小颜色数。当终端 display-color-cells 值大于等于该整数时匹配。

supports

终端是否支持 value… 指定的文本视觉样式属性(see 文本视觉样式属性)。See Display Face Attribute Testing 了解具体测试方式。

display 某元素为某 characteristic 指定多个 value,任一值均可匹配。若 display 包含多个元素,每个元素应指定不同 characteristic;此时终端的每个特征必须匹配 display 中为其指定的某个 value

例如,标准文本视觉样式 highlight 的定义如下:

(defface highlight
  '((((class color) (min-colors 88) (background light))
     :background "darkseagreen2")
    (((class color) (min-colors 88) (background dark))
     :background "darkolivegreen")
    (((class color) (min-colors 16) (background light))
     :background "darkseagreen2")
    (((class color) (min-colors 16) (background dark))
     :background "darkolivegreen")
    (((class color) (min-colors 8))
     :background "green" :foreground "black")
    (t :inverse-video t))
  "Basic face for highlighting."
  :group 'basic-faces)

内部实现中,Emacs 将每个文本视觉样式的默认规范保存在其 face-defface-spec 符号属性中(see 符号属性)。saved-face 属性存储用户通过自定义缓冲区保存的规范;customized-face 存储当前会话已自定义但未保存的规范;theme-face 存储 alist,将活跃自定义设置与主题关联到该样式的规范。文本视觉样式的文档字符串保存在 face-documentation 属性中。

通常文本视觉样式仅通过 defface 声明一次,后续外观修改通过自定义框架(如自定义界面或 custom-set-faces 函数;see 应用自定义设置)或文本视觉样式重映射(see 文本视觉样式重映射)实现。极少数需要从 Lisp 直接修改样式规范时,可使用 face-spec-set 函数。

Function: face-spec-set face spec &optional spec-type

此函数将 spec 应用为 face 的文本视觉样式规范。spec 应为 defface 文档中所述的规范格式。

face 尚未定义,该函数会将其定义为有效名称,并(重新)计算其在现有框架上的属性。

可选参数 spec-type 决定设置哪类规范。省略或为 nil / face-override-spec 时,设置 覆盖规范(override spec),优先级高于其他所有类型规范。这在自定义代码外调用该函数时很有用。若为 customized-facesaved-face,分别设置会话自定义规范或保存的自定义规范。若为 face-defface-spec,设置默认规范(与 defface 相同)。若为 reset,清除该样式上所有自定义规范与覆盖规范(此时 spec 值被忽略)。其他 spec-type 值对规范的作用保留为内部使用,但函数仍会定义 face 并重新计算其属性。