;; (define-key global-map [M-S-down-mouse-3] 'imenu)
-;;;; Font lock bugs as of v4.32:
-
-;; The following kinds of Perl code erroneously start strings:
-;; \$` \$' \$"
-;; $opt::s $opt_s $opt{s} (s => ...) /\s+.../
-;; likewise with m, tr, y, q, qX instead of s
-
;;; Code:
\f
;;; Compatibility with older versions (for publishing on ELPA)
--- /dev/null
+# The following Perl punctiation variables contain characters which
+# are classified as string delimiters in the syntax table. The mode
+# should not be confused by these.
+# The corresponding tests check that two consecutive '#' characters
+# are seen as comments, not as strings.
+my $pre = $`; ## $PREMATCH, use another ` # to balance out
+my $pos = $'; ## $POSTMATCH, use another ' # to balance out
+my $lsp = $"; ## $LIST_SEPARATOR use another " # to balance out
+
+# In the second level, we use the reference constructor \ on these
+# variables. The backslash is an escape character *only* in strings.
+my $ref = \$`; ## \$PREMATCH, use another ` # to balance out
+my $rif = \$'; ## \$POSTMATCH, use another ' # to balance out
+my $raf = \$"; ## \$LIST_SEPARATOR use another " # to balance out
+
+my $opt::s = 0; ## s is no substitution here
+my $opt_s = 0; ## s is no substitution here
+my %opt = (s => 0); ## s is no substitution here
+$opt{s} = 0; ## s is no substitution here
+$opt_s =~ /\s+.../ ## s is no substitution here
(should (equal got expected)))))
(cperl-set-style "CPerl"))))
+(ert-deftest cperl-mode-fontify-punct-vars ()
+ "Test fontification of Perl's punctiation variables.
+Perl has variable names containing unbalanced quotes for the list
+separator $\" and pre- and postmatch $` and $'. A reference to
+these variables, for example \\$\", should not cause the dollar
+to be escaped, which would then start a string beginning with the
+quote character. This used to be broken in cperl-mode at some
+point in the distant past, and is still broken in perl-mode. "
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (let ((file (ert-resource-file "fontify-punctuation-vars.pl")))
+ (with-temp-buffer
+ (insert-file-contents file)
+ (goto-char (point-min))
+ (funcall cperl-test-mode)
+ (while (search-forward "##" nil t)
+ ;; The third element of syntax-ppss is true if in a string,
+ ;; which would indicate bad interpretation of the quote. The
+ ;; fourth element is true if in a comment, which should be the
+ ;; case.
+ (should (equal (nth 3 (syntax-ppss)) nil))
+ (should (equal (nth 4 (syntax-ppss)) t))))))
+
;;; cperl-mode-tests.el ends here