【问题标题】:Can I customize the indentation of ternary operators in emacs' cperl-mode?emacs 的 cperl-mode 可以自定义三元运算符的缩进吗?
【发布时间】:2011-02-16 02:05:11
【问题描述】:

在 emacs cperl-mode 中,三元运算符没有特殊处理。如果你将它们分成多行,cperl-mode 会像缩进任何后续语句一样简单地缩进每一行,如下所示:

$result = ($foo == $bar)  ? 'result1' :
    ($foo == $baz)  ? 'result2' :
        ($foo == $qux)  ? 'result3' :
            ($foo == $quux) ? 'result4' : 
                'fail_result';

这不是很可读。有什么方法可以说服像这样的 cperl-mode 缩进?

$result = ($foo == $bar)  ? 'result1' :
          ($foo == $baz)  ? 'result2' :
          ($foo == $qux)  ? 'result3' :
          ($foo == $quux) ? 'result4' : 
                            'fail_result';

顺便说一下,来自this question的代码示例。

编辑

cperl-mode 的三元运算符缩进似乎有一个错误。以下面的例子为例,它是使用 Emacs 23.1.1,cperl-mode 版本 5.23 缩进的:

my $result = ($foo == $bar)  ? 'result1' :
  ($foo == $baz)  ? 'result2' :
  ($foo == $qux)  ? 'result3' :
  ($foo == $quux) ? 'result4' :
  'fail_result';

{
  my $result = ($foo == $bar)  ? 'result1' :
    ($foo == $baz)  ? 'result2' :
      ($foo == $qux)  ? 'result3' :
        ($foo == $quux) ? 'result4' :
          'fail_result';
}

请注意,在任何大括号之外,我基本上都得到了我想要的缩进。但是在大括号内,三元运算符缩进很糟糕。有解决办法吗?

【问题讨论】:

  • +1 好问题,我自己也一直在想这个问题。
  • 明确地说,我希望能够使用 emacs 的内置缩进工具来做到这一点,以便使用 TAB 做正确的事情。但如果做不到这一点,欢迎使用其他解决方案。

标签: perl emacs indentation ternary-operator cperl-mode


【解决方案1】:

您使用的是什么版本的 cperl-mode 和 Emacs?在 GNU Emacs 23.1, cperl-version 5.23 中,没有初始化文件,我得到:

$result = ($foo == $bar)  ? 'result1' :
  ($foo == $baz)  ? 'result2' :
  ($foo == $qux)  ? 'result3' :
  ($foo == $quux) ? 'result4' :
  fail_result;

如果我想让它们排在第一个之下,我会添加一组额外的括号:

$result = (($foo == $bar)  ? 'result1' :
           ($foo == $baz)  ? 'result2' :
           ($foo == $qux)  ? 'result3' :
           ($foo == $quux) ? 'result4' :
           fail_result);

我很确定要实现您要求的缩进(fail_result'result' 字符串对齐)需要对 cperl-mode 的缩进引擎进行一些重要的更改。不过,欢迎您尝试。 :-)

【讨论】:

  • 嗯。我想我在 cperl-mode 的缩进中发现了一个错误。我将用详细信息编辑我的问题。
  • 等一下,额外的一组父母不会强制列表上下文吗? stackoverflow.com/questions/2886751/…
  • @Ryan Thompson:不。要获得列表上下文,您必须将括号放在 $result 周围,而不是在您分配给 $result 的表达式周围。
  • 我意识到分配将在标量上下文中发生,但额外的一对括号仍可能最终创建一个单元素列表,从而将数字 1 分配给 $result
  • @Ryan Thompson:不。赋值运算符右侧的括号不会创建列表上下文。 $x = ((((func)))); 完全等同于 $x = func;。要获取列表上下文,请将括号放在赋值的左侧:($x) = func; 在列表上下文中调用 func
【解决方案2】:

我不知道 Cperl 模式下的自动缩进,但M-1 M-S-| perltidy(如果您安装了Perl::Tidy)会很好地整理标记区域(包括三元语句)。默认情况下,它看起来与您的示例不完全相同,但我相信您可以自定义它以在其 .perltidyrc 中执行您想要的操作。

顺便说一句,我自己并没有弄清楚 - 我在某处读过它 - 我以为是 PBP 但我刚刚检查过,似乎不是那样,但无论如何我一直都在使用它并发现它非常有用.

编辑:它在cperl page in the emacs wiki

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    相关资源
    最近更新 更多