【问题标题】:How can I make emacs' cperl-mode indent all statement continuations by only one level?如何使 emacs 的 cperl-mode 将所有语句继续缩进一个级别?
【发布时间】:2010-08-27 08:24:18
【问题描述】:

在 emacs 的 cperl 模式中,从前一行开始的语句会被缩进一级:

my $var
  = (1+1)
  * (2+2)
  / (3+3);

但是,如果语句不是从零缩进开始的,因为它在一个块内,那么如果你把你的语句分成第三行,你会得到 另一个 级别的缩进,依此类推:

sub break_my_indentation {
  my $var
    = (1+1)
      * (2+2)
        / (3+3);
  return "Indentation is broken.";
}

有什么办法可以解决这个问题,让语句在块内的缩进方式与在块外的缩进方式相同?我希望第二个示例看起来像这样:

sub fix_my_indentation {
  my $var
    = (1+1)
    * (2+2)
    / (3+3);
  return "Indentation is fixed.";
}

【问题讨论】:

  • 感谢@Schwern 提出这个问题。我仍然有兴趣找到它的答案。
  • 不管怎样,我在其他模式下也看到过这个问题,其中行继续缩进仅在行从第 0 列开始时才能正常工作。

标签: emacs indentation auto-indent cperl-mode


【解决方案1】:

我确认你描述的行为是存在的,但是,通过阅读源代码并在调试器下运行,并不明显有一个 customization 可以让你得到你的行为(我) 想要。

因此我认为这是cperl-mode 中的一个错误。

解决方法是:

=== modified file 'lisp/progmodes/cperl-mode.el'
--- lisp/progmodes/cperl-mode.el    2012-12-01 05:09:12 +0000
+++ lisp/progmodes/cperl-mode.el    2012-12-26 16:29:19 +0000
@@ -3120,7 +3121,9 @@ and closing parentheses and brackets."
     ((eq 'continuation (elt i 0))
      ;; [continuation statement-start char-after is-block is-brace]
      (goto-char (elt i 1))     ; statement-start
-     (+ (if (memq (elt i 2) (append "}])" nil)) ; char-after
+     (+ (if (or (memq (elt i 2) (append "}])" nil)) ; char-after
+                     (eq 'continuation ; do not repeat cperl-close-paren-offset
+                         (elt (cperl-sniff-for-indent parse-data) 0)))
         0          ; Closing parenth
           cperl-continued-statement-offset)
         (if (or (elt i 3)      ; is-block

请测试这个补丁;如果您对它感到满意,我会添加一个自定义来启用它。

【讨论】:

  • 这似乎修复了这个错误。谢谢!
  • 我可以确认修复它,谢谢!我要把它推到上游cperl-mode
  • @Schwern:我对 emacs bzr 有写权限,所以我打算自己提交。
  • @sds 太好了!如果您想走得更远,您能否考虑合并jrockway's perl 5.10 and Moose patches 以支持诸如say、given、when 和method 之类的东西?
  • @Schwern:我宁愿把这个留给 cperl 维护者。
【解决方案2】:

cperl-mode默认没有这个问题。默认情况下,缩进如下:

my $var
  = (1+1)
  * (2+2)
  / (3+3);

您的自定义设置阻止了cperl-mode 正确缩进。缩进配置见cperl-indent-rules-alist变量。

【讨论】:

  • 嗯。如果语句从缩进级别零开始,它就像你说的那样工作。但是,如果语句在块或其他内容中开始,那么它会按照我所说的进行。我会更新问题。
【解决方案3】:

正如@jerome-radix 建议的那样,默认情况下cperl-mode 不会发生您遇到的问题。问题当然可以在cperl-indent-rules-alist 中找到,但还有很多其他地方可以查看。

您使用的是什么版本的模式? C-h v cperl-version RET

在调试此类问题时,您需要从一些基本的事情开始,看看您是否可以重现错误。首先让大家知道你运行的是什么M-x emacs-version。然后通过运行emacs -q 消除您自己的自定义,以避免在启动时加载您的 init 文件:

--no-init-file, -q          load neither ~/.emacs nor default.el

如果您在关闭自己的 init 文件的情况下仍然可以重现问题,那么更进一步,在系统级别使用 emacs -Q 将其关闭:

--quick, -Q                 equivalent to:
                              -q --no-site-file --no-site-lisp --no-splash

【讨论】:

  • 你必须把它放在块中才能看到问题。
  • 是的,我逐字复制了您的块示例,我没有遇到问题。事实上,当我用错误的缩进手动输入它然后运行indent-region 它会正确地重新缩进所有内容,这就是为什么我建议您提供有关您的配置的更多详细信息,因为包括我在内的其他人无法重现该问题。
  • 我以为我用 emacs -Q 试过了,但还是有问题,但那是几年前的事了,所以我有机会再重复一次实验。
  • 啊,我没有注意到日期...我刚刚看到@Schwern 最近发布的赏金,所以似乎其他人也遇到了问题。
  • 好的,我在 Ubuntu 12.04 上启用了this PPA。我已经尝试过来自 PPA 的 emacs23 版本 23.3+1-1ubuntu9.1(来自主 Ubuntu 存储库)和 emacs24 版本 24.2+1-1~ppa1~precise7 和 emacs-snapshot 版本 2:20121224-1~ppa1~precise1,当使用 -Q 运行时,这三个版本都出现了这个错误。跨度>
猜你喜欢
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 2011-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多