From 2cc9d3c8c5ba49e7a3a84c60619bbe2100f9e008 Mon Sep 17 00:00:00 2001 From: Mauro Aranda Date: Tue, 20 Sep 2022 11:18:45 -0300 Subject: [PATCH] Recognize the backslash operator in perl-mode * lisp/progmodes/perl-mode.el (perl-syntax-propertize-function): Add new rule to detect a backslash operator. (Bug#11996) * test/lisp/progmodes/cperl-mode-tests.el (cperl-test-bug-11996): New test. * test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl: New file. --- lisp/progmodes/perl-mode.el | 6 ++++ .../cperl-mode-resources/cperl-bug-11996.pl | 8 +++++ test/lisp/progmodes/cperl-mode-tests.el | 30 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index bd8f4ecd1c..7b7a2cdf01 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -242,6 +242,12 @@ perl-syntax-propertize-function (not (nth 3 (syntax-ppss (match-beginning 0)))))) (string-to-syntax ". p")))) + ;; If "\" is acting as a backslash operator, it shouldn't start an + ;; escape sequence, so change its syntax. This allows us to handle + ;; correctly the \() construct (Bug#11996) as well as references + ;; to string values. + ("\\(\\\\\\)['`\"($]" (1 (unless (nth 3 (syntax-ppss)) + (string-to-syntax ".")))) ;; Handle funny names like $DB'stop. ("\\$ ?{?\\^?[_[:alpha:]][_[:alnum:]]*\\('\\)[_[:alpha:]]" (1 "_")) ;; format statements diff --git a/test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl b/test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl new file mode 100644 index 0000000000..566b7e7550 --- /dev/null +++ b/test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl @@ -0,0 +1,8 @@ +{ + my @zzzz=(\%seen_couchrequsts, \%seen_people ); + my @zzzz=\(%seen_couchrequsts, %seen_people ); + my @zzzz=(\%seen_couchrequsts, \%seen_people ); +} + +print "\"Watch out\""; +$ref = \"howdy"; diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el index 66039d6fc7..1bb206e704 100644 --- a/test/lisp/progmodes/cperl-mode-tests.el +++ b/test/lisp/progmodes/cperl-mode-tests.el @@ -788,6 +788,36 @@ cperl-test-bug-10483 (should (string-match "poop ('foo', \n 'bar')" (buffer-string)))))) +(ert-deftest cperl-test-bug-11996 () + "Verify that we give the right syntax property to a backslash operator." + (with-temp-buffer + (insert-file-contents (ert-resource-file "cperl-bug-11996.pl")) + (funcall cperl-test-mode) + (font-lock-ensure) + (goto-char (point-min)) + (re-search-forward "\\(\\\\(\\)") + (save-excursion + (goto-char (match-beginning 1)) + (should (equal (syntax-after (point)) (string-to-syntax "."))) + ;; `forward-sexp' shouldn't complain. + (forward-sexp) + (should (char-equal (char-after) ?\;))) + (re-search-forward "\\(\\\\\"\\)") + (save-excursion + (goto-char (match-beginning 1)) + (should (equal (syntax-after (point)) (string-to-syntax "\\"))) + (should (equal (get-text-property (point) 'face) 'font-lock-string-face))) + (re-search-forward "\\(\\\\\"\\)") + (save-excursion + (goto-char (match-beginning 1)) + (should (equal (syntax-after (point)) (string-to-syntax "\\")))) + (re-search-forward "\\(\\\\\"\\)") + (save-excursion + (goto-char (match-beginning 1)) + (should (equal (syntax-after (point)) (string-to-syntax "."))) + (should (equal (get-text-property (1+ (point)) 'face) + 'font-lock-string-face))))) + (ert-deftest cperl-test-bug-14343 () "Verify that inserting text into a HERE-doc string with Elisp does not break fontification." -- 2.34.1