3

My company uses a version of Perl where you can define by binary number using something like my $var = 'b010110110; etc. Problem is both perl-mode and cperl-mode interpret ' as the start of the string and will apply a string font lock to everything until the next '. This causes large sections of code are to appear as a string when they are not.

I have looked into how Emacs defines strings, and it does not have a string start or string end syntax class. Rather it just has a string quote character syntax class of which both " and ' are members of in Perl modes.

I have modified the syntax table to changed the ' character from the string quote character class to the punctuation character class. This fixes the problems of stringifying blocks of code but normal strings quoted with ' are no longer recognized.

I need a really smart person who can show me some code to modify the syntax highlighting of Perl so that strings are recognized as strings and binary notation is recognized as binary notation. How can I accomplish this?

6
  • 2
    syntax-propertize-function is a way to set up custom rules for applying text properties.
    – wasamasa
    Commented Nov 17, 2016 at 19:00
  • In perl you define a binary number using 0b as a prefix, see perldoc perlnumber. I am not sure why you need to use a single quote instead of 0b? Commented Nov 17, 2016 at 20:12
  • HåkonHægland I know that is how binary numbers are defined in Perl. But my companies Perl interpreter accepts 'b as well (probably because it is really old) and all of our Perl files use 'b. So I have to find someone to correct for this. I can't go through all our repo's and change it. Commented Nov 17, 2016 at 20:36
  • @wasamasa I did some digging based on you mentioning syntax-propertize-function and I was able to add addition rule to syntax-propertize-rules that makes things work correctly. Now the question is, how do I add it to my perl-mode? (I was hacking the source file directly) Is there a hook or something? Commented Nov 17, 2016 at 21:02
  • perl-mode-hook. Generally, every properly defined mode (read: via define-derived-mode) offers a variable named as the mode with -hook appended to it after its definition. Feel free to self-answer this question with the code involved!
    – wasamasa
    Commented Nov 17, 2016 at 21:58

1 Answer 1

2

So I did some more digging and I was able to find a solution, but not a very clean one. I copied the perl-syntax-propertize-function from perl-mode.el. I then added this to my .emacs and changed the name to my/perl-syntax-propertize-function and added the following code after syntax-propertize-rules

("\\('\\)b[^'a-z]" (1 "."))

I then added a perl-mode-hook after my function redefinition

(add-hook 'perl-mode-hook
        (lambda () (setq-local syntax-propertize-function #'my/perl-syntax-propertize-function)))

I reloaded my Emacs and everything worked like I wanted. I still hope that someone can come up with a cleaner solution.

6
  • I think this is the right solution. Of course, a minor tweak you can do is to call the original perl syntax propertize function, instead of copy-pasting it. Also, if this is proper perl, you could report this as a bug in Emacs and ask them to fix it centrally. Finally, I think your regexp might match too many things. Try to only match 'b[01]. Commented Nov 18, 2016 at 9:35
  • @Lindydancer, How can I call the original when I need to change it? I was trying to find some way to advise the function but no luck. Perhaps you know of a way? Because you're right, copy and pasting the original function seems like a waste since I only need to add one line. Commented Nov 18, 2016 at 14:53
  • In classic perl-mode, it is function named perl-syntax-propertize-function. You can call it from you function before (or after) you do your work. (In cperl-mode it is a lambda bound to the variable. You can save it for later and call it using funcall. In fact, this technique can be used for plain perl mode as well.) Commented Nov 18, 2016 at 16:13
  • This works because you can have multiple calls to syntax-propertize-rules. After all, it is only a macro that expands to a lambda that applies the syntax-table text properties to the buffer. In fact, your function doesn't even have to use it, it can apply the text property manually, if that would make sense. Commented Nov 18, 2016 at 16:18
  • so you are suggesting I define an advice that surrounds the original function so that I can make a call to syntax-propertize-rules, add my rules, then call the original function? Commented Nov 18, 2016 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.