Search code examples
emacsindentationauto-indentcperl-mode

How can I make emacs' cperl-mode indent all statement continuations by only one level?


In emacs' cperl-mode, lines that continute a statement from a previous line are indented by one level:

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

However, if the statement does not begin at zero indentation because it is inside a block, then if you break your statement onto a third line, you get another level of indentation, and so on:

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

Is there any way to fix this so that statements are indented the same way inside blocks as they are outside? I would like the second example to look like this:

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

Solution

  • I confirm that the behavior you describe is present, but, from reading the sources and running under the debugger, it is not obvious that there is a customization which gets you the behavior you (and I) want.

    Therefore I think this is a bug in cperl-mode.

    The fix is:

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

    Please test this patch; if you are happy with it, I will add a customization to enable it.