首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
293 阅读
2
从零开始配置 vim(15)——状态栏配置
171 阅读
3
nvim番外之将配置的插件管理器更新为lazy
160 阅读
4
2018总结与2019规划
149 阅读
5
PDF标准详解(五)——图形状态
126 阅读
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
登录
Search
标签搜索
c++
c
学习笔记
emacs
elisp
windows
文本操作术
编辑器
NeoVim
Vim
win32
读书笔记
VimScript
linux
文本编辑器
投资理财
Java
反汇编
OLEDB
数据库编程
Masimaro
累计撰写
446
篇文章
累计收到
33
条评论
首页
栏目
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
页面
归档
友情链接
关于
搜索到
1
篇与
的结果
2026-10-08
《elisp 每日一练》—— 关键字高亮
在节前的一篇文章中,我们探讨了fontlock 的基本机制。它主要起到一个桥梁的作用,将语法块和face样式做一个绑定,未来在扫描时发现语法块符合匹配时就采用对应的样式显示文本。背景知识符号与 face 绑定在前面我们已经使用过face,我们知道要设置文本的显示样式,修改修改它的属性,而文本属性中有 face、font-lock-face、mouse-face 和 cursor 等等各种face。那么face 到底是什么?以及如何设置、修改一个face 呢?首先我在之前介绍Emacs基础语法的文章中提到,elisp中的符号这一概念。符号是一个容器,你可以将它想象成一个柜子,里面有若干个格子。每个格子可以存储不同的内容。对于elisp 来说,符号可以存储具体的值, 这种情况是它最像变量的一种情况了。(set 'num 10) num ;; ==> 10我们使用 setq 定义变量时执行的就是类似于 set 指令。setq 的全称是 set quote,它在一个符号存储值的格子中放入一个值。另一种情况,格子可以放下函数定义,这个时候我们通过(sym) 调用函数,实际上就是在查找 sym 符号中函数格子里面的放入的内容。它还可以放置一个 plist 属性列表,这个属性列表我们可以存储它的文档信息,也可以存储一个face表。我们可以通过 defface 定义一个face(defface v '((t :foreground "red")) "My face named v.")但是此时产生的效果与 setq 不同,setq 是创建一个符号,并在符号 value 槽中添加一个值。但是符号中并没有名为 face 的槽,defface 是在 外部的 face 映射表中添加了一条记录,由符号 v 作为键,而我们定义的这个face 样式表作为值。在后续查询的时候实际上是通过在表中查找对应符号名是否绑定了face条目。我们可以使用 face-attribute 来查询。通过 set-face-attribute 来修改。这里我们只需要记住face 本身并没有绑定到一个变量上或者符号上,我们将face绑定到具体符号上,并不会影响符号之前保存的内容。至于更详细的内容,读者可以自行查阅相关文档。Emacs 内置的 font-lock-face首先,我们在上一篇的例子中定义了名为 my-c-block-comment-face 的变量,作为注释的face。Emacs提供了一系列内置的准的 Font Lock Face。为了使我们开发的mode能轻松适配其他的theme,我们应该尽量使用Emacs自定的这些变量名。而如果我们要开发新的theme,也可以只修改这些变量的值。我们列举一些常用的:font-lock-keyword-face 关键字,例如 this、class、return 等等font-lock-type-face 数据类型或者类名font-lock-variable-name-face 变量名font-lock-function-name-face 函数名或者方法名font-lock-constant-face 常量或者字面量font-lock-builtin-face 语言内置函数或者指令font-lock-comment-face 注释以 font-lock-keyword-face 为例,我们来看看该如何使用它们。我们查看它的定义发现,它被定义在Emacs的 font-lock.el 文件中:(defvar font-lock-keyword-face 'font-lock-keyword-face "Face name to use for keywords.")我们发现这个变量被定义为了同名的符号。对它求值我们得到这个符号本身。对于c/c++ 我们可以这样定义关键字到具体face 的映射关系("\\<\\(if\\|else\\|while\\|for\\|return\\)\\>" . font-lock-keyword-face)这里我们定义了 if、else、while、for、return 关键字对应的face。因为使用Emacs定义了 font-lock-keyword-face 变量实际返回的是同名的符号,所以它实际上对应着我们在在上一篇文章中定义的规则:("/\\*\\(?:.\\|\n\\)*?\\*/" 0 'my-c-block-comment-face t)Emacs 在实际渲染是,查询到这些关键字都被映射到一个名为 font-lock-keyword-face 的符号上,它会查找外部face映射表中是否有对应符号的face。如果有则采用face中的定义来渲染。Emacs已经为它提供了默认的face(defface font-lock-keyword-face '((((class grayscale) (background light)) :foreground "LightGray" :weight bold) (((class grayscale) (background dark)) :foreground "DimGray" :weight bold) (((class color) (min-colors 88) (background light)) :foreground "Purple") (((class color) (min-colors 88) (background dark)) :foreground "Cyan1") (((class color) (min-colors 16) (background light)) :foreground "Purple") (((class color) (min-colors 16) (background dark)) :foreground "Cyan") (((class color) (min-colors 8)) :foreground "cyan" :weight bold) (t :weight bold)) "Font Lock mode face used to highlight keywords." :group 'font-lock-faces)所以我们如果想要修改显示效果,只需要通过 defface 来进行绑定,或者通过 set-face-attribute 设置。练习本次的练习,我们尝试通过上面介绍的变量定义一个简单的c语言的语法高亮:以关键字的形式显示 if、else、while、for、return、break、continue显示简单类型的语法高亮, int、float、double、char、void、bool高亮显示常量, true、false、null、NULL显示注释的高亮, 行注释和块注释,都是同一种样式(defvar my-simplec-font-lock-keywords `( ("\\<\\(if\\|else\\|while\\|for\\|return\\)\\>" . font-lock-keyword-face) ("\\<\\(int\\|float\\|double\\|char\\|void\\|bool\\)\\>" . font-lock-type-face) ("\\<\\(true\\|false\\|null\\|NULL\\)\\>" . font-lock-constant-face) ("/\\*\\(?:.\\|\n\\)*?\\*/" 0 font-lock-comment-face) ("//.*$" 0 font-lock-comment-face) ) "MySimpleC 的 Font Lock 正则匹配与 Face 绑定规则。") (define-derived-mode my-simplec-mode prog-mode "MySimpleC" "配置简单的 Font Lock 关键字代码高亮" (setq-local font-lock-defaults '(my-simplec-font-lock-keywords nil nil)))总结今天我们讨论了symbol 和 face 的绑定关系,symbol 本身可以绑定一个值、一个函数和一个plist 结构,但是无法绑定face,通过 defface 实际上是在外部建立了一个symbol 和 face 映射。在需要使用face时会查找这张表。另外Emacs中提供了一系列默认的 font lock face变量,它们的值是同名的 symbol,我们直接使用它来进行语法层面的关联。如果开发theme可以修改这些符号绑定的 face 即可
2026年10月08日
1 阅读
0 评论
0 点赞