【问题标题】:How to test `font-lock-keywords` values for Emacs Lisp code如何测试 Emacs Lisp 代码的“font-lock-keywords”值
【发布时间】:2014-01-14 22:46:57
【问题描述】:

我提出这个问题是因为我认为这个问题和可能的答案都可能对编写定义 font-lock-keywords 的 Lisp 代码的 Emacs 用户有所帮助。我提供了一个我认为有帮助的答案。我也对其他答案感兴趣。

该变量的值是一个表达式列表,每个表达式都可以指定一个或多个要匹配的模式或执行匹配的函数,以及一个或多个用于突出显示匹配文本的面孔。 font-lock-keywords 值的可能性很多且复杂。 (描述这个的文档是 Elisp 手册,节点 Search-based Fontification。)

在大多数情况下,列表包含多个元素,这意味着多个正则表达式模式。这些可以以不同的方式进行交互。有些可以阻止其他人生效,或者他们可以改变其他人的效果。例如,我的库 Dired+ 在 Dired 模式下定义了 font-lock-keywords,其中包含 31 个条目(正则表达式),其中许多是交互的。

如何使所有这些保持直截了当?在定义或修改此类列表时如何调试它?您可以注释掉除一个列表项之外的所有项目,以便在单独时查看其效果。然后重复另一个。然后也许将几个加在一起,也许以不同的顺序。我想有多种可能性,但你是做什么的?

(好吧,我知道大多数 Elisp 编码人员不会编写超级复杂的 font-lock-keywords 定义。但即使对于简单的定义,这也会变得复杂。也许如果这个过程更容易,那么用户就不会不必要地将自己限制在一个或两个条目。)

【问题讨论】:

  • 几周前我问过自己同样的问题,写了几个字体锁定包,但没有找到好的答案。因此,我开始编写一个交互式字体锁定调试器,您可以在其中单步执行字体锁定关键字,并将调试器和源缓冲区中的匹配可视化。我还没有完成它,但我会在适当的时候发布它。在等待的时候,你可以看看我的字体锁定关键字回归测试系统:github.com/Lindydancer/faceup

标签: regex emacs elisp syntax-highlighting font-lock


【解决方案1】:

你可以使用我新发布的Font Lock Studio。以下内容来自自述文件:

font-lock-studio - 字体锁定关键字的交互式调试器

Font Lock Studio 是一个用于字体锁定的交互式调试器 关键字(Emacs 语法高亮规则)。

简介

Font Lock Studio 让您单步 Font Lock 关键字 -- 匹配器、突出显示和锚定规则,以便您可以看到 当缓冲区字体化时发生。您可以设置 breakpoints on 或 内部规则并运行直到被击中。在规则内时, 匹配使用背景颜色的调色板可视化。这 explainer 可以用纯文本的英文描述规则。紧的 与 Edebug 的集成允许您进入 Lisp 表达式 是字体锁定关键字的一部分。

使用调试器时,会显示一个接口缓冲区,它 包含所有关键字,用于导航和 匹配数据的可视化。

启动 Font Lock Studio 时,cmets 和 strings 预着色,因为它们是早期句法阶段的一部分 (Font Lock Studio 不支持)。

键入“M-x font-lock-studio RET”启动调试器。按? 或查看可用命令的菜单。

示例

对于使用html-mode 的缓冲区,接口缓冲区看起来 下列的。其他主要模式通常具有越来越复杂的 规则。左侧的箭头表示当前的活动位置。 源缓冲区中的相应箭头放置在当前 搜索位置。

        ========================
        === Font Lock Studio ===
        ========================
    --------------------------------------------------
=>  "<\\([!?][_:[:alpha:]][-_.:[:alnum:]]*\\)"
      (1 font-lock-keyword-face)
    --------------------------------------------------
    "</?\\([_[:alpha:]][-_.[:alnum:]]*\\)\\(?::\\([_:[:alpha:]]
    [-_.:[:alnum:]]*\\)\\)?"
      (1
       (if
           (match-end 2)
           sgml-namespace-face font-lock-function-name-face))
      (2 font-lock-function-name-face nil t)
    --------------------------------------------------
    "\\(?:^\\|[ \t]\\)\\([_[:alpha:]][-_.[:alnum:]]*\\)\\(?::
    \\([_:[:alpha:]][-_.:[:alnum:]]*\\)\\)?=[\"']"
      (1
       (if
           (match-end 2)
           sgml-namespace-face font-lock-variable-name-face))
      (2 font-lock-variable-name-face nil t)
    --------------------------------------------------
    "[&%][_:[:alpha:]][-_.:[:alnum:]]*;?"
      (0 font-lock-variable-name-face)
    --------------------------------------------------
    "<\\(b\\(?:ig\\|link\\)\\|cite\\|em\\|h[1-6]\\|rev\\|s\\(?:
    mall\\|trong\\)\\|t\\(?:itle\\|t\\)\\|var\\|[bisu]\\)
    \\([ \t][^>]*\\)?>\\([^<]+\\)</\\1>"
      (3
       (cdr
        (assoc-string
         (match-string 1)
         sgml-tag-face-alist t))
       prepend)
    ==================================================
    Public state:
      Debug on error     : YES
      Debug on quit      : YES
      Explain rules      : YES
      Show compiled code : NO

按空格单步浏览所有关键字。 “n”会去 下一个关键字,“b”将设置断点,“g”将运行到 结束(或到下一个断点)和“q”将退出。

特点

步进

您可以单独进入退出字体锁定 关键字。完全支持锚定规则。此外,你 可以运行到结尾或下一个断点。

断点

您可以在部分关键字上设置断点,例如匹配器 (例如正则表达式)、突出显示规则或锚定突出​​显示内部 规则。

如果您想单步执行或运行而不在断点处停止,请添加前缀 带有C-u的命令。

请注意,在锚定规则中,您可以设置断点 整个规则或单个部分。在前一种情况下,只有 外括号突出显示。

比赛数据可视化

在关键字或锚定突出​​显示的匹配器之后 执行后,匹配数据(无论搜索到什么)都被可视化了 在源缓冲区、正则表达式和 在相应的突出显示规则或规则之上。如果是正则表达式的一部分 或者一个亮点不匹配,它没有着色,这可以用于 使用后缀正则表达式运算符? 时会发生示例。

请注意,内部匹配组优先于外部组。 这可能导致突出显示规则获得颜色的情况 不会出现在正则表达式或源缓冲区中。为了 例如,匹配器“\(abc\)”将被着色为 匹配 1,而高亮规则 `(0 a-face)' 获取颜色 匹配 0。

规范化关键字

界面中呈现的关键字已经规范化。为了 例如,而不是

     ("xyz" . font-lock-type-face)

关键字

      ("xyz" (0 font-lock-type-face))

显示。详情请见font-lock-studio-normalize-keywords

解释器

解释器呼应了当前的人类可读描述 Font Lock 关键字的一部分。这有助于你理解 规则中所有nil:s 和t:s 的实际含义。

使用自动解释器时,Font Lock Studio 会回显 每个命令后的说明。

Edebug -- Emacs Lisp 调试器

与 Edebug 的紧密集成允许您单步执行表达式 嵌入在接口缓冲区的关键字中,它允许您 在源文件中检测调用函数以进行调试。

跟随模式感知

源缓冲区中的搜索位置由 覆盖箭头并通过更新点。如果源缓冲区是 在多个并排窗口中可见,并且跟随模式是 启用后,搜索位置将显示在合适的窗口中 最小化滚动。

【讨论】:

  • 听起来很有用,而且代码看起来不错。你显然投入了很多工作。 (还没有尝试过。)您可能想在文件头中提及它与哪些 Emacs 版本兼容。通过实验,我可以看到 24.3 之前的 Emacs 将无法工作,例如,因为 user-error。如果您更改了一些这样无端的新奇事物,那么您无疑可以轻松地使其与多个 Emacs 版本一起使用——如果您愿意的话。无论如何,它看起来是一个受欢迎的补充。也许考虑在EmacsWiki 上添加提及它(例如,为它创建一个页面)。
  • 啊,我看到你确实解决了文件头中的 Emacs 版本问题。
  • 仅供参考,我在文件自己的缓冲区中使用 Emacs 24.3 短暂尝试过。我用SPC 踩过一次,然后它移动到lambda。我第二次使用SPC,Emacs 崩溃了。由于是 Emacs 24.3,因此没有生成文件 emacs_backtrace.txt。无论如何,我会再玩一些。 Emacs 崩溃不是代码的错,而是某个地方的 Emacs 错误。
  • 仅供参考(我将在此之后退出):我用最近的 Emacs 开发快照(24.4 之前)尝试了同样的事情,没有崩溃:lambda 被替换为 Unicode 符号(根据我的字体锁定关键字),没有问题。
  • 目前看起来非常好。我会接受这是最好的答案。我想看到的一件事(是否已经可能?)是能够同时显示它为所有此类匹配的关键字的给定实例显示的内容。 IOW:显示给定关键字(或其任何部分)的所有匹配项的突出显示。到目前为止,它似乎一次只显示一次命中 --- 非常像调试器。如果这不可能,那么这似乎是对我给出的 icicle-font-lock-keywords 答案的补充
【解决方案2】:

为了解决这个问题,我编写了一个Iciclesmulti-commandicicle-font-lock-keywords。它允许您执行以下操作:

  • 在单独的 font-lock-keywords 条目(模式)之间循环,单独应用它们以查看每个单独的效果。

  • 选择单个条目并分别应用它们,以查看相同的内容。

  • 选择一组条目并应用它,条目出现在font-lock-keywords 中的顺序相同。您可以对任意数量的集执行此操作。

  • 累积多组词条的效果,按照你选择的顺序。

  • Revert,查看所有条目一起的效果,即所有font-lock-keywords

您可以按任何顺序在一次命令调用中完成所有这些操作。

M-o 是 Facemenu 和字体锁定的前缀键,所以我在 Icicle 模式下将这个命令放在键 M-o I 上。

【讨论】:

  • emacswiki.org/emacs/Icicles_-_Libraries查看如何下载时,看不到存档。
  • @AndreasRöhler - 抱歉,我不明白你的意思。有几种方法可以获取 Icicles 文件,包括从 MELPA 获取。您尝试了什么,遇到了什么问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
相关资源
最近更新 更多