Emacs: perl-mode vs cperl-mode

By Xah Lee. Date: . Last updated: .

In emacs, there are 2 modes for Perl: perl-mode and cperl-mode. Both are included in emacs 23. perl-mode is the simpler of the two. This page is a comparisonn of their syntax coloring features.

By default, perl-mode is loaded when you open a Perl script.

Syntax Coloring Comparison

emacs perl mode 2022-06-08 YF6yy
emacs perl mode 2022-06-08 YF6yy
emacs cperl mode 2022-06-08 7hDwM
emacs cperl mode 2022-06-08 7hDwM

In emacs, the global variable “font-lock-maximum-decoration” controlls how much coloring you want. The syntax coloring in the above pages have “font-lock-maximum-decoration” set at 2.

If you find cperl's coloring too wild, you can set the value to 1. (just Alt+x set-variable)

or put this in your Emacs Init File:

(setq font-lock-maximum-decoration 2)

Alt+x describe-variable to see full doc of this variable. Note: not all modes support font-lock-maximum-decoration . cperl-mode does.

Feature Comparison

cperl-mode offers much more features than perl-mode.

perl-mode Doc String

perl-mode is an interactive compiled Lisp function in `perl-mode.el'.

(perl-mode)

Major mode for editing Perl code.
Expression and list commands understand all Perl brackets.
Tab indents for Perl code.
Comments are delimited with # ... \n.
Paragraphs are separated by blank lines only.
Delete converts tabs to spaces as it moves back.
key             binding
---             -------

TAB             perl-indent-command
  (that binding is currently shadowed by another mode)
ESC             Prefix Command
: .. ;          perl-electric-terminator
{               perl-electric-terminator
}               perl-electric-terminator
DEL             backward-delete-char-untabify

C-M-a           perl-beginning-of-function
C-M-e           perl-end-of-function
C-M-h           perl-mark-function
C-M-q           perl-indent-exp

Variables controlling indentation style:
…

cperl-mode Doc String

cperl-mode is an interactive compiled Lisp function in
`cperl-mode.el'.

It is bound to <menu-bar> <file> <lang-modes> <perl>.

(cperl-mode)

Major mode for editing Perl code.
Expression and list commands understand all C brackets.
Tab indents for Perl code.
Paragraphs are separated by blank lines only.
Delete converts tabs to spaces as it moves back.

Various characters in Perl almost always come in pairs: {}, (), [],
sometimes <>.  When the user types the first, she gets the second as
well, with optional special formatting done on {}.  (Disabled by
default.)  You can always quote (with C-q) the left
"paren" to avoid the expansion.  The processing of < is special,
since most the time you mean "less".  CPerl mode tries to guess
whether you want to type pair <>, and inserts is if it
appropriate.  You can set `cperl-electric-parens-string' to the string that
contains the parenths from the above list you want to be electrical.
Electricity of parenths is controlled by `cperl-electric-parens'.
You may also set `cperl-electric-parens-mark' to have electric parens
look for active mark and "embrace" a region if possible.'

CPerl mode provides expansion of the Perl control constructs:

   if, else, elsif, unless, while, until, continue, do,
   for, foreach, formy and foreachmy.

and POD directives (Disabled by default, see `cperl-electric-keywords'.)

The user types the keyword immediately followed by a space, which
causes the construct to be expanded, and the point is positioned where
she is most likely to want to be.  eg. when the user types a space
following "if" the following appears in the buffer: if () { or if ()
} { } and the cursor is between the parentheses.  The user can then
type some boolean expression within the parens.  Having done that,
typing C-c C-j places you - appropriately indented - on a
new line between the braces (if you typed C-c C-j in a POD
directive line, then appropriate number of new lines is inserted).

If CPerl decides that you want to insert "English" style construct like

            bite if angry;

it will not do any expansion.  See also help on variable
`cperl-extra-newline-before-brace'.  (Note that one can switch the
help message on expansion by setting `cperl-message-electric-keyword'
to nil.)

C-c C-j is a convenience replacement for typing carriage
return.  It places you in the next line with proper indentation, or if
you type it inside the inline block of control construct, like

            foreach (@lines) {print; print}

and you are on a boundary of a statement inside braces, it will
transform the construct into a multiline and will place you into an
appropriately indented blank line.  If you need a usual
`newline-and-indent' behavior, it is on C-j,
see documentation on `cperl-electric-linefeed'.

Use C-c C-t to change a construction of the form

            if (A) { B }

into

            B if A;

key             binding
---             -------

C-c             Prefix Command
TAB             cperl-indent-command
  (that binding is currently shadowed by another mode)
C-j             newline-and-indent
ESC             Prefix Command
(               cperl-electric-paren
)               cperl-electric-rparen
:               cperl-electric-terminator
;               cperl-electric-semi
<               cperl-electric-paren
[               cperl-electric-paren
]               cperl-electric-rparen
{               cperl-electric-lbrace
}               cperl-electric-brace
DEL             cperl-electric-backspace

C-M-q           cperl-indent-exp
C-M-\           cperl-indent-region
C-M-|           cperl-lineup

C-c C-a         cperl-toggle-auto-newline
C-c C-b         cperl-find-bad-style
C-c C-d         cperl-here-doc-spell
C-c C-e         cperl-toggle-electric
C-c C-f         auto-fill-mode
C-c C-h         Prefix Command
C-c C-j         cperl-linefeed
C-c C-k         cperl-toggle-abbrev
C-c C-n         cperl-narrow-to-here-doc
C-c C-p         cperl-pod-spell
C-c C-t         cperl-invert-if-unless
C-c C-v         cperl-next-interpolated-REx
C-c C-w         cperl-toggle-construct-fix
C-c C-x         cperl-next-interpolated-REx-0
C-c C-y         cperl-next-interpolated-REx-1

C-c C-h F       cperl-info-on-command
C-c C-h P       cperl-perldoc-at-point
C-c C-h a       cperl-toggle-autohelp
C-c C-h f       cperl-info-on-current-command
C-c C-h p       cperl-perldoc
C-c C-h v       cperl-get-help

Setting the variable `cperl-font-lock' to t switches on font-lock-mode
(even with older Emacsen), `cperl-electric-lbrace-space' to t switches
on electric space between $ and {, `cperl-electric-parens-string' is
the string that contains parentheses that should be electric in CPerl
(see also `cperl-electric-parens-mark' and `cperl-electric-parens'),
setting `cperl-electric-keywords' enables electric expansion of
control structures in CPerl.  `cperl-electric-linefeed' governs which
one of two linefeed behavior is preferable.  You can enable all these
options simultaneously (recommended mode of use) by setting
`cperl-hairy' to t.  In this case you can switch separate options off
by setting them to `null'.  Note that one may undo the extra
whitespace inserted by semis and braces in `auto-newline'-mode by
consequent DEL.

If your site has perl5 documentation in info format, you can use commands
C-c C-h f and C-c C-h F to access it.
These keys run commands `cperl-info-on-current-command' and
`cperl-info-on-command', which one is which is controlled by variable
`cperl-info-on-command-no-prompt' and `cperl-clobber-lisp-bindings'
(in turn affected by `cperl-hairy').

Even if you have no info-format documentation, short one-liner-style
help is available on C-c C-h v, and one can run perldoc or
man via menu.

It is possible to show this help automatically after some idle time.
This is regulated by variable `cperl-lazy-help-time'.  Default with
`cperl-hairy' (if the value of `cperl-lazy-help-time' is nil) is 5
secs idle time .  It is also possible to switch this on/off from the
menu, or via C-c C-h a.  Requires `run-with-idle-timer'.

Use C-M-| to vertically lineup some construction - put the
beginning of the region at the start of construction, and make region
span the needed amount of lines.

Variables `cperl-pod-here-scan', `cperl-pod-here-fontify',
`cperl-pod-face', `cperl-pod-head-face' control processing of POD and
here-docs sections.  With capable Emaxen results of scan are used
for indentation too, otherwise they are used for highlighting only.

Variables controlling indentation style:
…
DO NOT FORGET to read micro-docs (available from `Perl' menu)
or as help on variables `cperl-tips', `cperl-problems',
`cperl-praise', `cperl-speed'.

Setting-up cperl-mode as Default

If you always want cperl-mode to be loaded, put: (defalias 'perl-mode 'cperl-mode) in your emacs init file. This way, when you Alt+x perl-mode, it'll be cperl-mode.

Alternatively, you can put the following:

;; use cperl-mode instead of perl-mode
(setq auto-mode-alist (rassq-delete-all 'perl-mode auto-mode-alist))
(add-to-list 'auto-mode-alist '("\\.\\(p\\([lm]\\)\\)\\'" . cperl-mode))

(setq interpreter-mode-alist (rassq-delete-all 'perl-mode interpreter-mode-alist))
(add-to-list 'interpreter-mode-alist '("perl" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("perl5" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("miniperl" . cperl-mode))

This way, you can still call perl-mode if you do need it, or want to experiment with the two modes.

[see Learn Perl in 1 Hour]