Using a “better” mode will make indentation easier – CPerlMode instead of plain PerlMode.
You can force all attempts to invoke perl-mode to invoke cperl-mode instead via the following:
(fset 'perl-mode 'cperl-mode)
== Using perltidy
Most Perl indenting solutions revolve around customizing the settings of a particular mode. However, in some cases you need to normalize indententation of code in a team of heterogenous editor users. In other words I use perltidy at my work to indent perl code, and here is the elisp code I wrote to do it: PerlTidyElisp. – wjt
Basic indentation can be changed using the variable cperl-indent-level:
(setq cperl-indent-level 4)
Note that the variable cperl-indent-alist has a doc string that says it is not being used.
Version 5.0 of CPerlMode offers many improvements over older versions. For one, parenthetical blocks such as
(
'one',
'two',
'three'
)can be configured to be indented correctly. Get it at:
(Can we expand on how to do this? I’d also like to see how to prevent cperl-mode from indenting like this
function_call(
$arg1,
$arg2,
another_function_call(
$arg3and instead indent like this
function_call(
$arg1,
$arg2,
another_function_call(
$arg3Michael, I believe that with a recent CPerl you just need to
(custom-set-variables
'(cperl-indent-parens-as-block t))– AaronHarsh?
I tried Aaron’s solution under 5.0, and it does exactly what you want, Michael. However you might also want
'(cperl-close-paren-offset -2)
(or whatever your indent level is) so that the close parens are unindented far enough.
– JeremyMuhlich?
I’m happy with the following:
(setq cperl-indent-level 4
cperl-close-paren-offset -4
cperl-continued-statement-offset 4
cperl-indent-parens-as-block t
cperl-tab-always-indent t)which give me:
function_call(
$arg1,
$arg2,
another_function_call(
$arg3
)
);How do you solve this indenting problem? Notice the staircasing inside the “if()” after the first “print” and how the join and being outside the curly bracket doesnt have this problem. This occurs with cperl-mode, not perl-mode on every system I have access to.
if(one() &&
two())
{
print
one(),
two();
print
join("",
one(),
two());
}
print
one(),
two(); Thanks
I didn’t realize that it worked as long as you’re on the top-level! Until now my solution has been to enclose the buffer in parenthesis (like your join call). – Alex
I have a problem with continuated indentation, I have
(setq
cperl-close-paren-offset -4
cperl-continued-statement-offset 4
cperl-indent-level 4
cperl-indent-parens-as-block t
cperl-tabs-always-indent t)At top level, all the continuations are identically indented
my $test = "a string"
. "just"
. " for"
. "test";But under a {}
{
my $test = "a string"
. "just"
. " for"
. "test";
}Is this a bug ?
I found default string indentation for concatenated strings very irritating but solved it by setting cperl-continued-statement-offset to 0. I’m not sure this is the best solution but at least now the result is readable. – Peter
Rather than hacking into the source, I think it’s better to just redefine that small function that you commented out to do the right thing; i.e. in .emacs, add:
;;load cperl, then work around indent issue
(load-library "cperl-mode")
(defun cperl-backward-to-start-of-continued-exp (lim)
(if (memq (preceding-char) (append ")]}\"'`" nil))
(forward-sexp -1))
(beginning-of-line)
(if (or (<= (point) lim) (< 0 cperl-continued-statement-offset))
(goto-char (1+ lim)))
(skip-chars-forward " \t"))– SteveSanbeg?
The above bit from SteveSanbeg? works great except that it screws up indents on continuing – pushing them far over to the right. Does anybody have a fix?
Does anybody have an idea about how to influence the indentation of subs as arguments? I often run into situations like this:
$img_ebox->signal_connect ('button-press-event', sub {
my $bt = $_[1]->button;
$mnu->popup(undef,undef,undef,undef,$bt, 0) if $bt == 3;
});where cperl-mode pushes the body of the sub so far to the right that it is almost impossible to limit the line length to 80 chars.
– PeterD?
John; yes, it looks like just commenting a few parts out doesn’t work. I’ve looked at it a bit more, and wrote a simple version of that function from scratch, which so far seems to work pretty well:
;;load cperl, then work around indent issue (load-library "cperl-mode") (defun cperl-backward-to-start-of-continued-exp (lim) (goto-char (1+ lim)) (forward-sexp) (beginning-of-line) (skip-chars-forward " \t") )
Peter; it looks like the more args you put on a line, the farther it indents; i.e.
$img_ebox->signal_connect (
'button-press-event',
sub {
my $bt = $_[1]->button;
$mnu->popup(undef,undef,undef,undef,$bt, 0) if $bt == 3;
});--SteveSanbeg?
Above one by SteveSanbeg? works fine and portable except the continued statement inside parentheses goes left from the opening parenthesis, so I made my hack into a function and also added a part to prevent continuation inside parentheses from being indented. This indents much like CC Mode.
Edit: Updated to my latest settings.
(setq
after-load-alist
(append
after-load-alist
'((cperl-mode
(defun cperl-backward-to-start-of-continued-exp (lim)
(goto-char containing-sexp)
(let ((sexp-start (following-char)))
(forward-char)
(skip-chars-forward " \t\n")
(if (and (> (current-column) cperl-continued-statement-offset)
(memq sexp-start (append "([" nil)))
(backward-char cperl-continued-statement-offset)))))
)))--KukiYomanai?
Is there customization to have auto-indent like this:
$something->create('sphere', sub {
my ($c, @args) = @_;
...
});?
Answering to myself (using up-to-date https://github.com/jrockway/cperl-mode)
(set-q cperl-indent-subs-specially nil)