2

I have an issue outlined here that I was able to find a partial solution for. The problem involved changing perl-modes syntax table. One of the commenters pointed me to the function syntax-propertize-function. Within it, there is macro called syntax-propertize-rules and I was able to add the following code snippet to it.

      ("\\('\\)[bh]" (1 "."))

this fixed the syntax problem I was having. However this is a change I made to the source perl-mode.el. What I need is some way to add this rule to syntax-propertize-rules from within my .emacs file. I have already tried

(defun my/perl-syntax-propertize-function ()
    ("\\('\\)[bh]" (1 ".")))

(add-hook 'perl-mode-hook
          (lambda () (add-function :after (symbol-function 'syntax-propertize-rules) #'my/perl-syntax-propertize-function)))

But this does not work. What is the correct way to make this change?

Prgrm.celeritas
  • 849
  • 6
  • 15
  • Why are you patching the macro code? Can't you just provide a list of rules as as argument to the macro? (Apologies if the question is silly; I haven't tried to understand the code.) – Drew Nov 17 '16 at 23:01
  • @Drew the macro is already defined in perl-mode.el. How can I provide arguments to it after the fact? I am very new to Emacs Lisp. – Prgrm.celeritas Nov 17 '16 at 23:05
  • I see. Hopefully someone else here will provide you with a helpful answer. – Drew Nov 17 '16 at 23:59

1 Answers1

4

The answer is that you can't do it "right". But you can do the following:

(defalias 'my/perl-syntax-propertize-function
  (syntax-propertize-rules ("\\('\\)[bh]" (1 "."))))

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

AFAIK the main problem with the above is that it will misfire when 'b is not the beginning of a binary constant but the end of a string followed by b. Fixing this would be a lot more ugly, because you'd then need to know if you're already within a string, and to know this, you'd need to apply your rule at the same time as perl-mode's normal rules rather :after or :before.

Stefan
  • 26,154
  • 3
  • 46
  • 84
  • I changed the regex to ("\\('\\)b[01]+[[:space:]]*\\([,;\\)\\}]\\|$\\)" (1 ".")) so hopefully it will be more robust. still not as robust as checking if you are in a string though. Thanks for your answer! – Prgrm.celeritas Nov 22 '16 at 18:55