定义文本视觉样式的常规方式是使用 defface 宏。该宏将文本视觉样式名称(符号)与默认 文本视觉样式规范(face spec) 关联。文本视觉样式规范用于指定文本视觉样式在不同终端上的属性;例如可在高色深终端指定一种前景色,在低色深终端指定另一种。
有人会试图创建值为文本视觉样式名称的变量。绝大多数情况下这并不必要;标准做法是用 defface 定义样式后直接使用其名称。
注意:一旦通过 defface 定义了文本视觉样式,除重启 Emacs 外无法安全取消定义。
该宏将 face 声明为命名文本视觉样式,其默认规范由 spec 给出。无需引用符号 face,且名称不应以 ‘-face’ 结尾(冗余)。参数 doc 为文本视觉样式的文档字符串。额外的 keyword 参数含义与 defgroup 和 defcustom 相同(see 通用项关键字)。
若 face 已有默认规范,此宏不执行任何操作。
默认规范决定无自定义生效时文本视觉样式的外观(see 自定义设置)。若 face 已被自定义(通过自定义主题或初始化文件加载的设置),则外观由自定义规范决定并覆盖默认规范 spec。但后续移除自定义后,外观会再次由默认规范决定。
例外情况:在 Emacs Lisp 模式中使用 C-M-x(eval-defun)或 C-x C-e(eval-last-sexp)执行 defface 表单时,这些命令的特殊机制会覆盖该样式上的所有自定义规范,使其严格反映 defface 定义。
参数 spec 为 文本视觉样式规范(face spec),说明样式在不同终端上的表现。它应为 alist,元素格式为:
(display . plist)
display 指定终端类型(见下文)。plist 为文本视觉样式属性及其值的属性列表,指定样式在该类终端上的表现。为兼容旧版,元素也可写作 (display plist)。
spec 元素中的 display 决定匹配哪些终端。若多个元素匹配同一终端,使用第一个匹配项。display 有三种可能:
default该元素不匹配任何终端;而是指定适用于所有终端的默认值。若使用该元素,必须为 spec 的第一个元素。后续每个元素均可覆盖部分或全部默认值。
t该元素匹配所有终端。因此 spec 中后续元素永远不会生效。通常 t 用于 spec 的最后一个(或唯一一个)元素。
若 display 为列表,每个元素格式为 (characteristic value…)。其中 characteristic 为终端分类方式,value 为 display 适用的分类。characteristic 可选值:
type终端使用的窗口系统类型—graphic(任意图形显示器)、x、pc(MS-DOS 控制台)、w32(Windows 9X/NT/2K/XP)、haiku、pgtk(纯 GTK)、android 或 tty(非图形显示器)。See window-system.
class终端支持的颜色类型—color、grayscale 或 mono。
background背景类型—light 或 dark。
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 函数。
此函数将 spec 应用为 face 的文本视觉样式规范。spec 应为 defface 文档中所述的规范格式。
若 face 尚未定义,该函数会将其定义为有效名称,并(重新)计算其在现有框架上的属性。
可选参数 spec-type 决定设置哪类规范。省略或为 nil / face-override-spec 时,设置 覆盖规范(override spec),优先级高于其他所有类型规范。这在自定义代码外调用该函数时很有用。若为 customized-face 或 saved-face,分别设置会话自定义规范或保存的自定义规范。若为 face-defface-spec,设置默认规范(与 defface 相同)。若为 reset,清除该样式上所有自定义规范与覆盖规范(此时 spec 值被忽略)。其他 spec-type 值对规范的作用保留为内部使用,但函数仍会定义 face 并重新计算其属性。