Syntax highlight for perl in Emacs is broken, is there a fix?

1.5k Views Asked by At

I'm a perl programmer and a new emacs user. I'm under Windows, using cperl-mode for editing perl. Emacs version is 24.2.1. Here's a screenshot with some sample code:


(source: breqwas.net)

  1. Obvious bug: it highlights arrays, hashes and non-quoted literal values in ( a => "b" ) style lists inside comments
  2. One more bug: it highligts the first word in a regular expression as an array because of non-default quote symbol
  3. Not a bug, but looks weird: it highlights arrays and hashes any time when they are used (even in comments, huh), but scalars are highlighted only when declared
  4. Not a bug, but looks weird: same story with functions: highlighted when declared, not when called
  5. Not a bug, but looks weird: why do "print", "say" and "system" have different colors?

I could keep going, but I hope that explains the word "broken" pretty well.

Then I learned the magic C-u C-x = key combination, which shows, among other stuff, the text properties for the text under the cursor, hoping to make a better coloring scheme of my own. At this point it started making even less sense.

"print" has cperl-nonoverridable-face. "die" has font-lock-keyword-face. Meanwhile, both are functions and can be (and often are) overrided. "system" has font-lock-type-face. Why? Function declarations have font-lock-function-name-face - that's OK, but so do the arguments of "use". Why? Function calls and scalars don't have face property at all and can't be highlighted. Why? Etc, Etc. Again, I could keep going.

Is there a way to fix all that? Is there some config where I can remap lexical units to some other font-faces, or some other way to make the syntax highlight less crazy?

To avoid the "perl is unparsible" talk, here's a screenshot of the editor I'm migrating from, with the very same code: http://breqwas.net/dropbox/perlsyn_pn.png. Looks much more reasonable.


Upd: By now (3 weeks after asking this question here) I did not find a cure. All perl programmers who use emacs I know just ignore these problems. No better perl highlighters for emacs seem to exist. Reading cperl-mode docs provides some explanations (the choice of faces for various elements seems less crazy now), but does not provide any answers. I wrote an email to cperl-mode maintainer with these questions and some more digging I did, but got no reply.

Yep, you got that right: seems like emacs community was not able to make a good perl syntax highligting in 25 years that perl is around. That's a sad story.

2

There are 2 best solutions below

0
On

You might want to try perl-mode instead of cperl-mode. If you find missing features in it we might be able to port them from cperl-mode without too much trouble. perl-mode's highlighting is less gaudy than cperl-mode's but it does fix some of the problems you point out.

As for "highlighted when declared, not when called" this is because Emacs usually highlights in this way. I find there is zero benefit to highlighting variable and function uses. I kept the highlighting of variable uses in perl-mode mostly because it was there before and I didn't want to deal with disgruntled users. Also, in the case of Perl, it's probably easier to highlight variable declarations and uses identically as does perl-mode whereas cperl-mode has to do extra work to distinguish those two cases.

0
On

Another syntax highlighting snafu to watch out for with Emacs cperl-mode relates to POD comments used to comment out blocks of code. Here's a screenshot to demo:

cperl-mode syntax highlighting bug demo

It's VERY easy to miss commented out code that uses POD directives without blank line padding as in my 'not recommended' example above. It just does not hit your eye as a comment when viewing it in Emacs, especially if the commented block is large and spans multiple screen pages so that the '=cut' lines aren't even in view.

It's worth noting that vim's Perl mode correctly highlights the POD without requiring blank line padding per the POD spec, though I would caution vim users to avoid relying on that feature and use blank line padding and '=begin comment ...=end comment' directives as shown above and as recommended.

It would be nice if Perl had a simpler multi-line comment syntax a la '/* ... */' rather than the POD mechanism that is subject to abuse. Perhaps we'll get this in Perl 6 some day?

Another way do multi-line comments in Emacs (for any language) is via the 'string-rectangle' built-in: C-x r t then type '# '. To uncomment a block, either do it manually or write a simple macro.