如何制作emacs';cperl模式仅将所有语句连续性缩进一级?

如何制作emacs';cperl模式仅将所有语句连续性缩进一级?,emacs,indentation,auto-indent,cperl-mode,Emacs,Indentation,Auto Indent,Cperl Mode,在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."; } 有没有办法解

在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.";
}

cperl模式
默认情况下不存在此问题。默认情况下,它缩进如下:

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

您有一个自定义项,可防止
cperl模式
正确缩进。有关缩进的配置,请参见
cperl缩进规则列表
变量。

正如@jerome radix所建议的,默认情况下,
cperl模式
不会出现您遇到的问题。这个问题当然可以通过
cperl缩进规则列表中的
来解决,但是还有许多其他地方需要研究

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

在调试此类问题时,您需要从两个基本问题开始,看看是否可以重现错误。首先让每个人都知道您正在运行哪个M-x emacs版本。然后通过运行
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

我确认您描述的行为是存在的,但是,从阅读源代码和在调试器下运行来看,没有明显的定制可以为您(和我)提供所需的行为

因此,我认为这是cperl模式下的一个bug

解决办法是:

=== 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

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

Hmm。如果语句从缩进级别0开始,它将按照您所说的那样工作。然而,如果语句是从一个块或某个地方开始的,那么它就按照我说的去做。我会更新这个问题。谢谢你给这个问题一个提振,@Schwern。我仍然对找到答案感兴趣。值得一提的是,我在其他模式中也看到过这个问题,行继续缩进只有在第0列开始时才能正常工作。你必须把它放在块中才能看到问题。是的,我将复制的块逐字逐句放在exmaple中,我没有遇到这个问题。事实上,当我用不正确的缩进手动输入它,然后运行
indent region
时,它会正确地重新缩进所有内容,这就是为什么我建议您提供有关您的配置的更多详细信息,因为包括我在内的其他人都无法重现该问题。我以为我用emacs-Q尝试过,但仍然存在问题,但那是几年前的事了,所以我有机会再重复一次实验。啊,我没有注意到日期。。。我刚刚看到@Schwern发布的最近的悬赏,所以似乎其他人也有这个问题。好的,我在Ubuntu 12.04上,启用了。我试过使用PPA中的emacs23版本
23.3+1-1ubuntu9.1
(来自主要的Ubuntu repo),emacs24版本
24.2+1-1~ppa1~precise7
和emacs快照版本
2:20121224-1~ppa1~precise1
,这三个版本在使用
-Q
运行时都会出现此错误。这似乎可以修复此错误。谢谢我可以确认修复了它,谢谢!我将把它推到上游。@Schwern:我有对emacs bzr的写权限,所以我计划自己提交。@sds太好了!如果您想更进一步,您是否可以考虑合并以支持诸如say、given、when和method之类的东西?@Schwern:我宁愿将此留给cperl维护人员。