4

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

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

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

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

  • cperl-mode 现在可以: $hash {key}
  • 我想要什么: $hash-> {key}

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

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

cperl 模式语法着色的示例

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

我意识到着色引用仅适用于 $hashref->{key} 之类的 deref,而不适用于 $hashref1 = $hashref2 之类的其他内容。我认为我可以忍受这一点。

4

3 回答 3

4

您可以设置cperl-highlight-variables-indiscriminatelyt(通过自定义它)以使标量变量不仅在声明时而且始终着色。 在此处输入图像描述

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

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

if (ref $ref eq 'ARRAY') {
    return $ref->[0]
} elsif (ref $ref eq 'HASH') {
    return $ref->{key}
}
于 2018-05-30T17:08:47.463 回答
4

我不喜欢回答我自己的问题,但是野鹅追逐的答案让我很恼火,以至于我想知道我的尝试做错了什么。

(当我要求 X 时,我讨厌它,有人回答 Y,然后反对 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 调用,我可以在闲暇时修复这些细节。

于 2018-05-31T00:31:45.160 回答
1

如果不扩展,您将无法做您想做的事情cperl-modecperl-mode不明白参考。没有可供您自定义的参考“面”,也没有可以应用该面的“事物”。如果您想呈现像哈希一样的哈希引用(例如您的示例),我将从修改in 定义中的第二个正则表达式开始。那应该照顾哈希和数组引用。谨防覆盖您的更改。如果你想做一些更高级的事情,比如有一张“参考脸”,你就必须t-font-lock-keywords-1cperl-mode.elcperl-highlight-variables-indiscriminately

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

当然,向上游发送功能请求可能更容易。cperl-mode是古老的,绝对可以使用一些现代化。

于 2018-05-31T00:21:46.347 回答