Emacs 突出显示:如何处理因特殊字符的异常使用而混乱的突出显示?

Emacs highlighting: how to deal with highlighting messed up by unusual usage of special characters?

问题:

在 Emacs 配置模式中(例如 conf-xdefaults-modeconf-space-mode),一些特殊字符以不寻常的方式使用,例如当它们定义键绑定时。这弄乱了缓冲区其余部分的突出显示。

示例:

游侠 rc.conf 文件使用 conf-space-mode,这极大地提高了其可读性。但行如:

map #  console shell -p%space
map "<any>  tag_toggle tag=%any

弄乱了突出显示,因为 # 通常定义注释,然后是 font-lock-comment-face 直到行尾,而 " 定义字符串的开头,然后是font-lock-string-face 直到遇到结束引号。

转义这些字符不是一个选项,因为它会阻止它们定义键绑定。

可能的解决方案:

我能想到的最佳解决方案是 fiddle 为这些配置模式设置字体锁定,以删除那些特殊字符后的突出显示。但是我会在合适的时候在这些字符之后放宽适当的突出显示。

一个妥协可能是在 # 之后继续突出显示,因为这只会弄乱一行,并且这些配置文件中有很多注释,同时删除单引号和双引号后的突出显示,因为那些弄乱了缓冲区和字符串的其余部分在配置文件中并不常见。

问题:

处理这些情况的正确方法是什么?

有没有办法在缓冲区中的某个点重置突出显示?或者插入一个会影响突出显示(修复它)而不影响代码的字符?或者有没有办法 "escape" 某些字符仅用于突出显示而不影响代码?

简单的方法

接受它但保持约束可能是最简单的方法。在这里,我采用了 ranger 的默认 rc.conf 并重新安排了一些 font-lock 错误。

让我们暂时忽略蓝色 "map"。我们有两个可见的字体锁定错误。 map #... 字体锁定为注释,map "... 字体锁定为缓冲区末尾的字符串。第一个错误是自我约束。注释在行尾结束。我们通过添加注释来约束第二个错误。 (我不知道 ranger 是否会接受行中间的注释,所以我在这里只使用行首注释。)

第二个错误现在限制在一行,但又弹出了几个错误。快速调整这些我们得到。

这是我可以忍受的东西,因为我不是整天都在 conf 文件中(而不是源代码。)如果我们的新 "comments" 可以是,那就更好了包含在同一行。

艰难的道路

您需要使用 Emacs font-lock-add-keywords。让我们回到第一张图片中的蓝色 map。它呈现蓝色是因为 conf-space-mode 认为应该在 font-lock-type-face 中呈现一个字符串,后跟任意数量的白色 space,然后是左大括号(触发它的实际正则表达式是 ^[_space__tab_]*\(.+?\)[_space__tab_\n]*{[^{}]*?$ 其中 _space__tab_ 是实际的 space 和制表符。)

我们可以通过评估

以简单的方式覆盖它
(font-lock-remove-keywords
 'conf-space-mode
 '(("^\<\(map\)\>" 1 font-lock-variable-name-face)))

并使用 C-x C-v RET 重新加载缓冲区。现在,每当单词 "map" 出现在行首时,它就会呈现为 font-lock-variable-name-face(在我们的示例中为黄色。)

您可以通过向 init 文件添加挂钩来使此更改永久生效。

(add-hook 'conf-space-mode-hook (lambda ()
  (font-lock-remove-keywords
   nil
   '(("^\<\(map\)\>" 1 font-lock-variable-name-face)))))

此方法似乎不适用于您的评论 (#) 和字符串 (' ") 分隔符,因为它们在语法 [=66= 中定义].修改语法 table 以提供特殊情况可能比它值得的更多努力。