ISO Emacs [C]Perl 模式将散列引用着色为散列

ISO Emacs [C]Perl-mode colorize hash references like hashes

我仍然使用 Perl,一些新代码,并维护旧代码。我使用 emacs 和 cperl 模式。我喜欢语法着色。

起初(很多年前)我不喜欢 cperl-mode 对数组和散列的特殊着色,但它越来越吸引我了。有时我更喜欢使用散列而不是散列引用,只是为了获得特殊的颜色。这听起来可能还不错——但如果我承认偶尔使用全局 %hash 或 $hash{key} 而不是对象成员 $hashref->{key},只是为了着色,那么,这很糟糕。 IE。语法着色让我想要遵循糟糕的编程习惯。

所以,我的问题是:有没有人有 emacs/elisp 配置代码来获取 cperl-mode 或 perl-mode 以与 $ 相同或相似的方式为 $hashref->{key} 之类的哈希引用着色哈希{键}?

让我用粗体表示可能被着色的地方:

我已经在 emacs 中对着色(面部)进行了广泛的自定义 - 例如着色以区分 DEBUG 代码与非调试代码,TEST 与非测试代码,等等 - 但我还没有设法在 cperl 模式下使用这种语法着色。 (后续:我最终让 font-lock-add-keywords 起作用了,如下面我对自己问题的回答所示。)

在下面的示例中,您可以看到 $hashref->{key} 没有着色,而 $hash{key} 是。

与数组引用类似,也许还有其他引用。

我知道着色 refs 只适用于像 $hashref->{key} 这样的 derefs,而不适用于像 $hashref1 = $hashref2 这样的其他东西。我想我可以接受。

您可以将 cperl-highlight-variables-indiscriminately 设置为 t(通过对其进行自定义)以使标量变量不仅在声明时着色,而且始终着色。

@ref$ref 使用相同的颜色会造成混淆,因为它们是不同的变量类型(和不同的变量);同样,对 $ref 使用标量颜色而对 $ref->[0] 使用数组颜色会令人困惑,因为它们是相同的变量。

另外,Perl 就是 Perl,你会在这里使用所有三种颜色吗?

if (ref $ref eq 'ARRAY') {
    return $ref->[0]
} elsif (ref $ref eq 'HASH') {
    return $ref->{key}
}

不扩展 cperl-mode 就无法为所欲为。 cperl-mode 不理解引用。没有参考 "face" 供您自定义,也没有 "thing" 可应用该面孔。如果您想像散列一样呈现散列引用(就像您的示例一样),我将从修改 cperl-mode.elt-font-lock-keywords-1 定义中的 the second regex 开始。那应该处理散列和数组引用。当心 cperl-highlight-variables-indiscriminately 覆盖您的更改。如果你想做一些更高级的事情,比如 "reference face",你必须

  1. 定义一张脸
  2. 添加要自定义的面孔(如果需要)
  3. hack t-font-lock-keywords-1 并将面部应用于正则表达式匹配

当然,向上游发送功能请求可能更容易。 cperl-mode 很古老,绝对可以进行一些现代化改造。

我不喜欢回答我自己的问题,但建议的野鹅追逐答案让我很恼火,足以弄清楚我的尝试做错了什么。

(我讨厌当我要求 X,有人回答 Y,然后 diss X。特别是当 X 是可行的,就像这里一样。)

这是我的 .emacs 中的工作代码:

(defun ag-extend-cperl-font-lock-keywords ()
  (interactive)
  (font-lock-add-keywords
    'cperl-mode
    '(
       (
         "\($[a-zA-Z_][a-zA-Z_0-9]*->\){"
         1 'cperl-hash-face t
         )
       (
         "\($[a-zA-Z_][a-zA-Z_0-9]*->\)\["
         1 'cperl-array-face t
         )
       (
         "\($[a-zA-Z_][a-zA-Z_0-9]*->\)("
         1 'font-lock-function-name-face t
         )
       )
    t
    )
  )

(ag-extend-cperl-font-lock-keywords)

给予

只是为了笑,@choroba 的多种类型示例:

我还没有决定是否应该为 hashrefs、arrayrefs 和 coderefs 创建单独的面孔。现在,只使用与非参考对象相同的面孔。包括 -> 作为彩色文本的一部分提供了非参考和参考之间的一些区别。

我还没有决定是否要扩展到其他各种 Perl 语法。 来自 https://perldoc.perl.org/perlref.html:

但现在我有了 font-lock-add-keywords 调用,我可以在闲暇时修复这些细节。