]> git.eshelyaron.com Git - emacs.git/commitdiff
cperl-mode.el: Update for the current Perl version 5.040
authorHarald Jörg <haj@posteo.de>
Mon, 10 Jun 2024 10:19:04 +0000 (12:19 +0200)
committerEshel Yaron <me@eshelyaron.com>
Wed, 12 Jun 2024 09:23:30 +0000 (11:23 +0200)
* etc/NEWS: Announce new features of cperl-mode.

* lisp/progmodes/cperl-mode.el (cperl-menu): Add toggle for extra
paired delimiters.
(defconst): new rx expressions `cperl--sub-name-generated-rx' and
`cperl--field-declaration-rx'
(cperl--imenu-entries-rx): Use the new expressions
(cperl--extra-paired-delimiters): New variable holding the paired
delimiters for Perl 5.36 and newer
(cperl-imenu-sub-keywords): Add autogenerated methods to imenu
(cperl-init-faces): Add the __CLASS__ token, builtin constants,
and attributes for field declarations.
(cperl-short-docs): Add __CLASS__ to one-line docs.
(cperl-extra-paired-delimiters-mode): new minor mode to handle
non-ASCII paired delimiters.

* test/lisp/progmodes/cperl-mode-tests.el
(cperl-test-fontify-builtin-constants): new test.
(cperl-test-fontify-class): New test clauses for attributes.
(cperl-test-field-declaration-rx): new test.
(cperl-test-autogenerated-reader-rx): new unit test for the rx
expression.
(cperl-test-extra-delimiters): new test.
(cperl-test-imenu-index): new clauses for imenu capture of
autogenerated methods.

* test/lisp/progmodes/cperl-mode-resources/grammar.pl: Add
examples for Perl 5.40 syntax.

* test/lisp/progmodes/cperl-mode-resources/extra-delimiters.pl:
New resource for non-ASCII paired delimiters.

(cherry picked from commit 060c48435f49eb03019cc9eb7f1657f756f56ceb)

etc/NEWS
lisp/progmodes/cperl-mode.el
test/lisp/progmodes/cperl-mode-resources/extra-delimiters.pl [new file with mode: 0644]
test/lisp/progmodes/cperl-mode-resources/grammar.pl
test/lisp/progmodes/cperl-mode-resources/perl-class.pl
test/lisp/progmodes/cperl-mode-tests.el

index 98d39f6153e209b3a60a735130f68e42b854783f..b02d2d2bc6de34270f91f25d5cea4d62b3513659 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1744,9 +1744,9 @@ fit on fewer lines without negatively impacting readability.
 CPerl mode fontifies subroutine signatures like variable declarations
 which makes them visually distinct from subroutine prototypes.
 
-*** Syntax of Perl up to version 5.38 is supported.
+*** Syntax of Perl up to version 5.40 is supported.
 CPerl mode supports the new keywords for exception handling and the
-object oriented syntax which were added in Perl 5.36 and 5.38.
+object oriented syntax which were added in Perl 5.36, 5.38 and 5.40.
 
 *** New user option 'cperl-fontify-trailer'.
 This user option takes the values 'perl-code' or 'comment' and treats
@@ -1760,6 +1760,11 @@ This command sets the indentation style for the current buffer.  To
 change the default style, either use the user option with the same name
 or use the command 'cperl-set-style'.
 
+*** New minor mode cperl-extra-paired-delimiters-mode
+Perl 5.36 and newer allows using more than 200 non-ASCII paired
+delimiters for quote-like constructs, eg. "q«text»".  Use this minor
+mode in buffers where this feature is activated.
+
 *** Commands using the Perl info page are obsolete.
 The Perl documentation in info format is no longer distributed with
 Perl or on CPAN since more than 10 years.  Perl documentation can be
index cbc23507fca84fab1ed6f498b601a9af2f08261f..5dba24ae76aeba32a4acb14ec1f3cd8ba84a8a26 100644 (file)
@@ -1130,6 +1130,7 @@ Unless KEEP, removes the old indentation."
      ["Auto newline" cperl-toggle-auto-newline t]
      ["Electric parens" cperl-toggle-electric t]
      ["Electric keywords" cperl-toggle-abbrev t]
+     ["Extra paired delimiters" cperl-extra-paired-delimiters-mode t]
      ["Fix whitespace on indent" cperl-toggle-construct-fix t]
      ["Auto-help on Perl constructs" cperl-toggle-autohelp t]
      ["Auto fill" auto-fill-mode t])
@@ -1436,6 +1437,33 @@ Contains three groups: One to distinguish lexical from \"normal\"
 subroutines, for the keyword \"sub\" or \"method\", and one for
 the subroutine name.")
 
+  (defconst cperl--sub-name-generated-rx
+    `(sequence symbol-start
+               (optional (group-n 3 unmatchable))
+               ;; autogenerated methods are not lexicals, so enforce the
+               ;; first capture group to be nil
+               "field"
+               ,cperl--ws+-rx
+               (or
+                (sequence (in "$%@")
+                          (group-n 2 ,cperl--basic-identifier-rx)
+                          (1+ (not (in ";={")))
+                          ":"
+                          (group-n 1 "reader")
+                          (not "("))
+                (sequence ,cperl--basic-variable-rx
+                          (1+ (not (in ";={")))
+                          ":"
+                          (group-n 1 "reader")
+                          "("
+                          (group-n 2 ,cperl--basic-identifier-rx)
+                          ")")))
+    "A regular expression to capture autogenerated reader methods.
+The name of the method is either the field name without its sigil, or
+given in parentheses after the \":reader\" keyword.")
+  ;; I don't dare to think about :writer where the generated name does
+  ;; not even occur in the text.
+
 (defconst cperl--block-declaration-rx
   `(sequence
     (or "class" "method" "package" "sub")
@@ -1445,16 +1473,16 @@ the subroutine name.")
 Used for indentation.  These declarations introduce a block which
 does not need a semicolon to terminate the statement.")
 
-;;; Initializer blocks are not (yet) part of the Perl core.
-;; (defconst cperl--field-declaration-rx
-;;   `(sequence
-;;     "field"
-;;     (1+ ,cperl--ws-or-comment-rx)
-;;     ,cperl--basic-variable-rx)
-;;   "A regular expression to find a declaration for a field.
-;; Used for indentation.  These declarations allow an initializer
-;; block which does not need a semicolon to terminate the
-;; statement.")
+(defconst cperl--field-declaration-rx
+  `(sequence
+    "field"
+    (1+ ,cperl--ws-or-comment-rx)
+    ,cperl--basic-variable-rx
+    (optional (sequence ,cperl--ws+-rx ,cperl--attribute-list-rx))
+    )
+  "A regular expression to find a declaration for a field.
+Fields can have attributes for fontification, and even for imenu because
+for example \":reader\" implicitly declares a method.")
 
 (defconst cperl--pod-heading-rx
   `(sequence line-start
@@ -1470,6 +1498,7 @@ heading text.")
   `(or ,cperl--package-for-imenu-rx
        ,cperl--class-for-imenu-rx
        ,cperl--sub-name-for-imenu-rx
+       ,cperl--sub-name-generated-rx
        ,cperl--pod-heading-rx)
   "A regular expression to collect stuff that goes into the `imenu' index.
 Covers packages and classes, subroutines and methods, and POD headings.")
@@ -3351,10 +3380,333 @@ fontified.  Do nothing if BEGIN and END are equal.  If
       (put-text-property begin end 'face (if string 'font-lock-string-face
                                           'font-lock-comment-face)))))
 
-(defvar cperl-starters '(( ?\( . ?\) )
-                        ( ?\[ . ?\] )
-                        ( ?\{ . ?\} )
-                        ( ?\< . ?\> )))
+(defvar cperl--basic-paired-delimiters '(( ?\( . ?\) )
+                                        ( ?\[ . ?\] )
+                                        ( ?\{ . ?\} )
+                                        ( ?\< . ?\> )))
+;; -------- The following definition is generated code from  "perlop"
+;; https://metacpan.org/release/HAARG/perl-5.40.0/view/pod/perlop.pod
+(defvar cperl--extra-paired-delimiters '(( ?\N{U+0028} . ?\N{U+0029} )
+                                         ( ?\N{U+003C} . ?\N{U+003E} )
+                                         ( ?\N{U+005B} . ?\N{U+005D} )
+                                         ( ?\N{U+007B} . ?\N{U+007D} )
+                                         ( ?\N{U+00AB} . ?\N{U+00BB} )
+                                         ( ?\N{U+00BB} . ?\N{U+00AB} )
+                                         ( ?\N{U+0F3A} . ?\N{U+0F3B} )
+                                         ( ?\N{U+0F3C} . ?\N{U+0F3D} )
+                                         ( ?\N{U+169B} . ?\N{U+169C} )
+                                         ( ?\N{U+2018} . ?\N{U+2019} )
+                                         ( ?\N{U+2019} . ?\N{U+2018} )
+                                         ( ?\N{U+201C} . ?\N{U+201D} )
+                                         ( ?\N{U+201D} . ?\N{U+201C} )
+                                         ( ?\N{U+2035} . ?\N{U+2032} )
+                                         ( ?\N{U+2036} . ?\N{U+2033} )
+                                         ( ?\N{U+2037} . ?\N{U+2034} )
+                                         ( ?\N{U+2039} . ?\N{U+203A} )
+                                         ( ?\N{U+203A} . ?\N{U+2039} )
+                                         ( ?\N{U+2045} . ?\N{U+2046} )
+                                         ( ?\N{U+204D} . ?\N{U+204C} )
+                                         ( ?\N{U+207D} . ?\N{U+207E} )
+                                         ( ?\N{U+208D} . ?\N{U+208E} )
+                                         ( ?\N{U+2192} . ?\N{U+2190} )
+                                         ( ?\N{U+219B} . ?\N{U+219A} )
+                                         ( ?\N{U+219D} . ?\N{U+219C} )
+                                         ( ?\N{U+21A0} . ?\N{U+219E} )
+                                         ( ?\N{U+21A3} . ?\N{U+21A2} )
+                                         ( ?\N{U+21A6} . ?\N{U+21A4} )
+                                         ( ?\N{U+21AA} . ?\N{U+21A9} )
+                                         ( ?\N{U+21AC} . ?\N{U+21AB} )
+                                         ( ?\N{U+21B1} . ?\N{U+21B0} )
+                                         ( ?\N{U+21B3} . ?\N{U+21B2} )
+                                         ( ?\N{U+21C0} . ?\N{U+21BC} )
+                                         ( ?\N{U+21C1} . ?\N{U+21BD} )
+                                         ( ?\N{U+21C9} . ?\N{U+21C7} )
+                                         ( ?\N{U+21CF} . ?\N{U+21CD} )
+                                         ( ?\N{U+21D2} . ?\N{U+21D0} )
+                                         ( ?\N{U+21DB} . ?\N{U+21DA} )
+                                         ( ?\N{U+21DD} . ?\N{U+21DC} )
+                                         ( ?\N{U+21E2} . ?\N{U+21E0} )
+                                         ( ?\N{U+21E5} . ?\N{U+21E4} )
+                                         ( ?\N{U+21E8} . ?\N{U+21E6} )
+                                         ( ?\N{U+21F4} . ?\N{U+2B30} )
+                                         ( ?\N{U+21F6} . ?\N{U+2B31} )
+                                         ( ?\N{U+21F8} . ?\N{U+21F7} )
+                                         ( ?\N{U+21FB} . ?\N{U+21FA} )
+                                         ( ?\N{U+21FE} . ?\N{U+21FD} )
+                                         ( ?\N{U+2208} . ?\N{U+220B} )
+                                         ( ?\N{U+2209} . ?\N{U+220C} )
+                                         ( ?\N{U+220A} . ?\N{U+220D} )
+                                         ( ?\N{U+2264} . ?\N{U+2265} )
+                                         ( ?\N{U+2266} . ?\N{U+2267} )
+                                         ( ?\N{U+2268} . ?\N{U+2269} )
+                                         ( ?\N{U+226A} . ?\N{U+226B} )
+                                         ( ?\N{U+226E} . ?\N{U+226F} )
+                                         ( ?\N{U+2270} . ?\N{U+2271} )
+                                         ( ?\N{U+2272} . ?\N{U+2273} )
+                                         ( ?\N{U+2274} . ?\N{U+2275} )
+                                         ( ?\N{U+227A} . ?\N{U+227B} )
+                                         ( ?\N{U+227C} . ?\N{U+227D} )
+                                         ( ?\N{U+227E} . ?\N{U+227F} )
+                                         ( ?\N{U+2280} . ?\N{U+2281} )
+                                         ( ?\N{U+2282} . ?\N{U+2283} )
+                                         ( ?\N{U+2284} . ?\N{U+2285} )
+                                         ( ?\N{U+2286} . ?\N{U+2287} )
+                                         ( ?\N{U+2288} . ?\N{U+2289} )
+                                         ( ?\N{U+228A} . ?\N{U+228B} )
+                                         ( ?\N{U+22A3} . ?\N{U+22A2} )
+                                         ( ?\N{U+22A6} . ?\N{U+2ADE} )
+                                         ( ?\N{U+22A8} . ?\N{U+2AE4} )
+                                         ( ?\N{U+22A9} . ?\N{U+2AE3} )
+                                         ( ?\N{U+22B0} . ?\N{U+22B1} )
+                                         ( ?\N{U+22D0} . ?\N{U+22D1} )
+                                         ( ?\N{U+22D6} . ?\N{U+22D7} )
+                                         ( ?\N{U+22D8} . ?\N{U+22D9} )
+                                         ( ?\N{U+22DC} . ?\N{U+22DD} )
+                                         ( ?\N{U+22DE} . ?\N{U+22DF} )
+                                         ( ?\N{U+22E0} . ?\N{U+22E1} )
+                                         ( ?\N{U+22E6} . ?\N{U+22E7} )
+                                         ( ?\N{U+22E8} . ?\N{U+22E9} )
+                                         ( ?\N{U+22F2} . ?\N{U+22FA} )
+                                         ( ?\N{U+22F3} . ?\N{U+22FB} )
+                                         ( ?\N{U+22F4} . ?\N{U+22FC} )
+                                         ( ?\N{U+22F6} . ?\N{U+22FD} )
+                                         ( ?\N{U+22F7} . ?\N{U+22FE} )
+                                         ( ?\N{U+2308} . ?\N{U+2309} )
+                                         ( ?\N{U+230A} . ?\N{U+230B} )
+                                         ( ?\N{U+2326} . ?\N{U+232B} )
+                                         ( ?\N{U+2348} . ?\N{U+2347} )
+                                         ( ?\N{U+23ED} . ?\N{U+23EE} )
+                                         ( ?\N{U+261B} . ?\N{U+261A} )
+                                         ( ?\N{U+261E} . ?\N{U+261C} )
+                                         ( ?\N{U+269E} . ?\N{U+269F} )
+                                         ( ?\N{U+2768} . ?\N{U+2769} )
+                                         ( ?\N{U+276A} . ?\N{U+276B} )
+                                         ( ?\N{U+276C} . ?\N{U+276D} )
+                                         ( ?\N{U+276E} . ?\N{U+276F} )
+                                         ( ?\N{U+2770} . ?\N{U+2771} )
+                                         ( ?\N{U+2772} . ?\N{U+2773} )
+                                         ( ?\N{U+2774} . ?\N{U+2775} )
+                                         ( ?\N{U+27C3} . ?\N{U+27C4} )
+                                         ( ?\N{U+27C5} . ?\N{U+27C6} )
+                                         ( ?\N{U+27C8} . ?\N{U+27C9} )
+                                         ( ?\N{U+27DE} . ?\N{U+27DD} )
+                                         ( ?\N{U+27E6} . ?\N{U+27E7} )
+                                         ( ?\N{U+27E8} . ?\N{U+27E9} )
+                                         ( ?\N{U+27EA} . ?\N{U+27EB} )
+                                         ( ?\N{U+27EC} . ?\N{U+27ED} )
+                                         ( ?\N{U+27EE} . ?\N{U+27EF} )
+                                         ( ?\N{U+27F4} . ?\N{U+2B32} )
+                                         ( ?\N{U+27F6} . ?\N{U+27F5} )
+                                         ( ?\N{U+27F9} . ?\N{U+27F8} )
+                                         ( ?\N{U+27FC} . ?\N{U+27FB} )
+                                         ( ?\N{U+27FE} . ?\N{U+27FD} )
+                                         ( ?\N{U+27FF} . ?\N{U+2B33} )
+                                         ( ?\N{U+2900} . ?\N{U+2B34} )
+                                         ( ?\N{U+2901} . ?\N{U+2B35} )
+                                         ( ?\N{U+2903} . ?\N{U+2902} )
+                                         ( ?\N{U+2905} . ?\N{U+2B36} )
+                                         ( ?\N{U+2907} . ?\N{U+2906} )
+                                         ( ?\N{U+290D} . ?\N{U+290C} )
+                                         ( ?\N{U+290F} . ?\N{U+290E} )
+                                         ( ?\N{U+2910} . ?\N{U+2B37} )
+                                         ( ?\N{U+2911} . ?\N{U+2B38} )
+                                         ( ?\N{U+2914} . ?\N{U+2B39} )
+                                         ( ?\N{U+2915} . ?\N{U+2B3A} )
+                                         ( ?\N{U+2916} . ?\N{U+2B3B} )
+                                         ( ?\N{U+2917} . ?\N{U+2B3C} )
+                                         ( ?\N{U+2918} . ?\N{U+2B3D} )
+                                         ( ?\N{U+291A} . ?\N{U+2919} )
+                                         ( ?\N{U+291C} . ?\N{U+291B} )
+                                         ( ?\N{U+291E} . ?\N{U+291D} )
+                                         ( ?\N{U+2920} . ?\N{U+291F} )
+                                         ( ?\N{U+2933} . ?\N{U+2B3F} )
+                                         ( ?\N{U+2937} . ?\N{U+2936} )
+                                         ( ?\N{U+2945} . ?\N{U+2946} )
+                                         ( ?\N{U+2947} . ?\N{U+2B3E} )
+                                         ( ?\N{U+2953} . ?\N{U+2952} )
+                                         ( ?\N{U+2957} . ?\N{U+2956} )
+                                         ( ?\N{U+295B} . ?\N{U+295A} )
+                                         ( ?\N{U+295F} . ?\N{U+295E} )
+                                         ( ?\N{U+2964} . ?\N{U+2962} )
+                                         ( ?\N{U+296C} . ?\N{U+296A} )
+                                         ( ?\N{U+296D} . ?\N{U+296B} )
+                                         ( ?\N{U+2971} . ?\N{U+2B40} )
+                                         ( ?\N{U+2972} . ?\N{U+2B41} )
+                                         ( ?\N{U+2974} . ?\N{U+2B4B} )
+                                         ( ?\N{U+2975} . ?\N{U+2B42} )
+                                         ( ?\N{U+2979} . ?\N{U+297B} )
+                                         ( ?\N{U+2983} . ?\N{U+2984} )
+                                         ( ?\N{U+2985} . ?\N{U+2986} )
+                                         ( ?\N{U+2987} . ?\N{U+2988} )
+                                         ( ?\N{U+2989} . ?\N{U+298A} )
+                                         ( ?\N{U+298B} . ?\N{U+298C} )
+                                         ( ?\N{U+298D} . ?\N{U+2990} )
+                                         ( ?\N{U+298F} . ?\N{U+298E} )
+                                         ( ?\N{U+2991} . ?\N{U+2992} )
+                                         ( ?\N{U+2993} . ?\N{U+2994} )
+                                         ( ?\N{U+2995} . ?\N{U+2996} )
+                                         ( ?\N{U+2997} . ?\N{U+2998} )
+                                         ( ?\N{U+29A8} . ?\N{U+29A9} )
+                                         ( ?\N{U+29AA} . ?\N{U+29AB} )
+                                         ( ?\N{U+29B3} . ?\N{U+29B4} )
+                                         ( ?\N{U+29C0} . ?\N{U+29C1} )
+                                         ( ?\N{U+29D8} . ?\N{U+29D9} )
+                                         ( ?\N{U+29DA} . ?\N{U+29DB} )
+                                         ( ?\N{U+29FC} . ?\N{U+29FD} )
+                                         ( ?\N{U+2A79} . ?\N{U+2A7A} )
+                                         ( ?\N{U+2A7B} . ?\N{U+2A7C} )
+                                         ( ?\N{U+2A7D} . ?\N{U+2A7E} )
+                                         ( ?\N{U+2A7F} . ?\N{U+2A80} )
+                                         ( ?\N{U+2A81} . ?\N{U+2A82} )
+                                         ( ?\N{U+2A83} . ?\N{U+2A84} )
+                                         ( ?\N{U+2A85} . ?\N{U+2A86} )
+                                         ( ?\N{U+2A87} . ?\N{U+2A88} )
+                                         ( ?\N{U+2A89} . ?\N{U+2A8A} )
+                                         ( ?\N{U+2A8D} . ?\N{U+2A8E} )
+                                         ( ?\N{U+2A95} . ?\N{U+2A96} )
+                                         ( ?\N{U+2A97} . ?\N{U+2A98} )
+                                         ( ?\N{U+2A99} . ?\N{U+2A9A} )
+                                         ( ?\N{U+2A9B} . ?\N{U+2A9C} )
+                                         ( ?\N{U+2A9D} . ?\N{U+2A9E} )
+                                         ( ?\N{U+2A9F} . ?\N{U+2AA0} )
+                                         ( ?\N{U+2AA1} . ?\N{U+2AA2} )
+                                         ( ?\N{U+2AA6} . ?\N{U+2AA7} )
+                                         ( ?\N{U+2AA8} . ?\N{U+2AA9} )
+                                         ( ?\N{U+2AAA} . ?\N{U+2AAB} )
+                                         ( ?\N{U+2AAC} . ?\N{U+2AAD} )
+                                         ( ?\N{U+2AAF} . ?\N{U+2AB0} )
+                                         ( ?\N{U+2AB1} . ?\N{U+2AB2} )
+                                         ( ?\N{U+2AB3} . ?\N{U+2AB4} )
+                                         ( ?\N{U+2AB5} . ?\N{U+2AB6} )
+                                         ( ?\N{U+2AB7} . ?\N{U+2AB8} )
+                                         ( ?\N{U+2AB9} . ?\N{U+2ABA} )
+                                         ( ?\N{U+2ABB} . ?\N{U+2ABC} )
+                                         ( ?\N{U+2ABD} . ?\N{U+2ABE} )
+                                         ( ?\N{U+2ABF} . ?\N{U+2AC0} )
+                                         ( ?\N{U+2AC1} . ?\N{U+2AC2} )
+                                         ( ?\N{U+2AC3} . ?\N{U+2AC4} )
+                                         ( ?\N{U+2AC5} . ?\N{U+2AC6} )
+                                         ( ?\N{U+2AC7} . ?\N{U+2AC8} )
+                                         ( ?\N{U+2AC9} . ?\N{U+2ACA} )
+                                         ( ?\N{U+2ACB} . ?\N{U+2ACC} )
+                                         ( ?\N{U+2ACF} . ?\N{U+2AD0} )
+                                         ( ?\N{U+2AD1} . ?\N{U+2AD2} )
+                                         ( ?\N{U+2AD5} . ?\N{U+2AD6} )
+                                         ( ?\N{U+2AE5} . ?\N{U+22AB} )
+                                         ( ?\N{U+2AF7} . ?\N{U+2AF8} )
+                                         ( ?\N{U+2AF9} . ?\N{U+2AFA} )
+                                         ( ?\N{U+2B46} . ?\N{U+2B45} )
+                                         ( ?\N{U+2B47} . ?\N{U+2B49} )
+                                         ( ?\N{U+2B48} . ?\N{U+2B4A} )
+                                         ( ?\N{U+2B4C} . ?\N{U+2973} )
+                                         ( ?\N{U+2B62} . ?\N{U+2B60} )
+                                         ( ?\N{U+2B6C} . ?\N{U+2B6A} )
+                                         ( ?\N{U+2B72} . ?\N{U+2B70} )
+                                         ( ?\N{U+2B7C} . ?\N{U+2B7A} )
+                                         ( ?\N{U+2B86} . ?\N{U+2B84} )
+                                         ( ?\N{U+2B8A} . ?\N{U+2B88} )
+                                         ( ?\N{U+2B95} . ?\N{U+2B05} )
+                                         ( ?\N{U+2B9A} . ?\N{U+2B98} )
+                                         ( ?\N{U+2B9E} . ?\N{U+2B9C} )
+                                         ( ?\N{U+2BA1} . ?\N{U+2BA0} )
+                                         ( ?\N{U+2BA3} . ?\N{U+2BA2} )
+                                         ( ?\N{U+2BA9} . ?\N{U+2BA8} )
+                                         ( ?\N{U+2BAB} . ?\N{U+2BAA} )
+                                         ( ?\N{U+2BB1} . ?\N{U+2BB0} )
+                                         ( ?\N{U+2BB3} . ?\N{U+2BB2} )
+                                         ( ?\N{U+2BEE} . ?\N{U+2BEC} )
+                                         ( ?\N{U+2E02} . ?\N{U+2E03} )
+                                         ( ?\N{U+2E03} . ?\N{U+2E02} )
+                                         ( ?\N{U+2E04} . ?\N{U+2E05} )
+                                         ( ?\N{U+2E05} . ?\N{U+2E04} )
+                                         ( ?\N{U+2E09} . ?\N{U+2E0A} )
+                                         ( ?\N{U+2E0A} . ?\N{U+2E09} )
+                                         ( ?\N{U+2E0C} . ?\N{U+2E0D} )
+                                         ( ?\N{U+2E0D} . ?\N{U+2E0C} )
+                                         ( ?\N{U+2E11} . ?\N{U+2E10} )
+                                         ( ?\N{U+2E1C} . ?\N{U+2E1D} )
+                                         ( ?\N{U+2E1D} . ?\N{U+2E1C} )
+                                         ( ?\N{U+2E20} . ?\N{U+2E21} )
+                                         ( ?\N{U+2E21} . ?\N{U+2E20} )
+                                         ( ?\N{U+2E22} . ?\N{U+2E23} )
+                                         ( ?\N{U+2E24} . ?\N{U+2E25} )
+                                         ( ?\N{U+2E26} . ?\N{U+2E27} )
+                                         ( ?\N{U+2E28} . ?\N{U+2E29} )
+                                         ( ?\N{U+2E36} . ?\N{U+2E37} )
+                                         ( ?\N{U+2E42} . ?\N{U+201E} )
+                                         ( ?\N{U+2E55} . ?\N{U+2E56} )
+                                         ( ?\N{U+2E57} . ?\N{U+2E58} )
+                                         ( ?\N{U+2E59} . ?\N{U+2E5A} )
+                                         ( ?\N{U+2E5B} . ?\N{U+2E5C} )
+                                         ( ?\N{U+A9C1} . ?\N{U+A9C2} )
+                                         ( ?\N{U+FD3E} . ?\N{U+FD3F} )
+                                         ( ?\N{U+FF62} . ?\N{U+FF63} )
+                                         ( ?\N{U+FFEB} . ?\N{U+FFE9} )
+                                         ( ?\N{U+1D103} . ?\N{U+1D102} )
+                                         ( ?\N{U+1D106} . ?\N{U+1D107} )
+                                         ( ?\N{U+1F57B} . ?\N{U+1F57D} )
+                                         ( ?\N{U+1F599} . ?\N{U+1F598} )
+                                         ( ?\N{U+1F59B} . ?\N{U+1F59A} )
+                                         ( ?\N{U+1F59D} . ?\N{U+1F59C} )
+                                         ( ?\N{U+1F5E6} . ?\N{U+1F5E7} )
+                                         ( ?\N{U+1F802} . ?\N{U+1F800} )
+                                         ( ?\N{U+1F806} . ?\N{U+1F804} )
+                                         ( ?\N{U+1F80A} . ?\N{U+1F808} )
+                                         ( ?\N{U+1F812} . ?\N{U+1F810} )
+                                         ( ?\N{U+1F816} . ?\N{U+1F814} )
+                                         ( ?\N{U+1F81A} . ?\N{U+1F818} )
+                                         ( ?\N{U+1F81E} . ?\N{U+1F81C} )
+                                         ( ?\N{U+1F822} . ?\N{U+1F820} )
+                                         ( ?\N{U+1F826} . ?\N{U+1F824} )
+                                         ( ?\N{U+1F82A} . ?\N{U+1F828} )
+                                         ( ?\N{U+1F82E} . ?\N{U+1F82C} )
+                                         ( ?\N{U+1F832} . ?\N{U+1F830} )
+                                         ( ?\N{U+1F836} . ?\N{U+1F834} )
+                                         ( ?\N{U+1F83A} . ?\N{U+1F838} )
+                                         ( ?\N{U+1F83E} . ?\N{U+1F83C} )
+                                         ( ?\N{U+1F842} . ?\N{U+1F840} )
+                                         ( ?\N{U+1F846} . ?\N{U+1F844} )
+                                         ( ?\N{U+1F852} . ?\N{U+1F850} )
+                                         ( ?\N{U+1F862} . ?\N{U+1F860} )
+                                         ( ?\N{U+1F86A} . ?\N{U+1F868} )
+                                         ( ?\N{U+1F872} . ?\N{U+1F870} )
+                                         ( ?\N{U+1F87A} . ?\N{U+1F878} )
+                                         ( ?\N{U+1F882} . ?\N{U+1F880} )
+                                         ( ?\N{U+1F892} . ?\N{U+1F890} )
+                                         ( ?\N{U+1F896} . ?\N{U+1F894} )
+                                         ( ?\N{U+1F89A} . ?\N{U+1F898} )
+                                         ( ?\N{U+1F8A1} . ?\N{U+1F8A0} )
+                                         ( ?\N{U+1F8A3} . ?\N{U+1F8A2} )
+                                         ( ?\N{U+1F8A5} . ?\N{U+1F8A6} )
+                                         ( ?\N{U+1F8A7} . ?\N{U+1F8A4} )
+                                         ( ?\N{U+1F8A9} . ?\N{U+1F8A8} )
+                                         ( ?\N{U+1F8AB} . ?\N{U+1F8AA} ))
+  "Full list of paired delimiters for quote-like constructs.
+As an experimental feature, Perl uses these under \"feature
+\='extra_paired_delimiters\='\" or in feature bundles of Perl 5.40 or
+newer.  To activate the extra delimiters, switch on the minor mode
+`cperl-extra-paired-delimiters-mode'.  This is also available from the
+\"Perl\" menu in section \"Toggle...\".
+The character pairs available are:
+(), <>, [], {}, «», »«, ༺༻, ༼༽, ᚛᚜, ‘’, ’‘, “”, ”“, ‵′, ‶″, ‷‴, ‹›, ›‹, ⁅⁆,
+⁍⁌, ⁽⁾, ₍₎, →←, ↛↚, ↝↜, ↠↞, ↣↢, ↦↤, ↪↩, ↬↫, ↱↰, ↳↲, ⇀↼, ⇁↽, ⇉⇇, ⇏⇍, ⇒⇐, ⇛⇚,
+⇝⇜, ⇢⇠, ⇥⇤, ⇨⇦, ⇴⬰, ⇶⬱, ⇸⇷, ⇻⇺, ⇾⇽, ∈∋, ∉∌, ∊∍, ≤≥, ≦≧, ≨≩, ≪≫, ≮≯, ≰≱, ≲≳,
+≴≵, ≺≻, ≼≽, ≾≿, ⊀⊁, ⊂⊃, ⊄⊅, ⊆⊇, ⊈⊉, ⊊⊋, ⊣⊢, ⊦⫞, ⊨⫤, ⊩⫣, ⊰⊱, ⋐⋑, ⋖⋗, ⋘⋙, ⋜⋝,
+⋞⋟, ⋠⋡, ⋦⋧, ⋨⋩, ⋲⋺, ⋳⋻, ⋴⋼, ⋶⋽, ⋷⋾, ⌈⌉, ⌊⌋, ⌦⌫, ⍈⍇, ⏭⏮, ☛☚, ☞☜, ⚞⚟, ❨❩, ❪❫,
+❬❭, ❮❯, ❰❱, ❲❳, ❴❵, ⟃⟄, ⟅⟆, ⟈⟉, ⟞⟝, ⟦⟧, ⟨⟩, ⟪⟫, ⟬⟭, ⟮⟯, ⟴⬲, ⟶⟵, ⟹⟸, ⟼⟻, ⟾⟽,
+⟿⬳, ⤀⬴, ⤁⬵, ⤃⤂, ⤅⬶, ⤇⤆, ⤍⤌, ⤏⤎, ⤐⬷, ⤑⬸, ⤔⬹, ⤕⬺, ⤖⬻, ⤗⬼, ⤘⬽, ⤚⤙, ⤜⤛, ⤞⤝, ⤠⤟,
+⤳⬿, ⤷⤶, ⥅⥆, ⥇⬾, ⥓⥒, ⥗⥖, ⥛⥚, ⥟⥞, ⥤⥢, ⥬⥪, ⥭⥫, ⥱⭀, ⥲⭁, ⥴⭋, ⥵⭂, ⥹⥻, ⦃⦄, ⦅⦆, ⦇⦈,
+⦉⦊, ⦋⦌, ⦍⦐, ⦏⦎, ⦑⦒, ⦓⦔, ⦕⦖, ⦗⦘, ⦨⦩, ⦪⦫, ⦳⦴, ⧀⧁, ⧘⧙, ⧚⧛, ⧼⧽, ⩹⩺, ⩻⩼, ⩽⩾, ⩿⪀,
+⪁⪂, ⪃⪄, ⪅⪆, ⪇⪈, ⪉⪊, ⪍⪎, ⪕⪖, ⪗⪘, ⪙⪚, ⪛⪜, ⪝⪞, ⪟⪠, ⪡⪢, ⪦⪧, ⪨⪩, ⪪⪫, ⪬⪭, ⪯⪰, ⪱⪲,
+⪳⪴, ⪵⪶, ⪷⪸, ⪹⪺, ⪻⪼, ⪽⪾, ⪿⫀, ⫁⫂, ⫃⫄, ⫅⫆, ⫇⫈, ⫉⫊, ⫋⫌, ⫏⫐, ⫑⫒, ⫕⫖, ⫥⊫, ⫷⫸, ⫹⫺,
+⭆⭅, ⭇⭉, ⭈⭊, ⭌⥳, ⭢⭠, ⭬⭪, ⭲⭰, ⭼⭺, ⮆⮄, ⮊⮈, ⮕⬅, ⮚⮘, ⮞⮜, ⮡⮠, ⮣⮢, ⮩⮨, ⮫⮪, ⮱⮰, ⮳⮲,
+⯮⯬, ⸂⸃, ⸃⸂, ⸄⸅, ⸅⸄, ⸉⸊, ⸊⸉, ⸌⸍, ⸍⸌, ⸑⸐, ⸜⸝, ⸝⸜, ⸠⸡, ⸡⸠, ⸢⸣, ⸤⸥, ⸦⸧, ⸨⸩, ⸶⸷,
+⹂„, ⹕⹖, ⹗⹘, ⹙⹚, ⹛⹜, ꧁꧂, ﴾﴿, 「」, →←, 𝄃𝄂, 𝄆𝄇, 🕻🕽, 🖙🖘, 🖛🖚, 🖝🖜, 🗦🗧, 🠂🠀, 🠆🠄, 🠊🠈,
+🠒🠐, 🠖🠔, 🠚🠘, 🠞🠜, 🠢🠠, 🠦🠤, 🠪🠨, 🠮🠬, 🠲🠰, 🠶🠴, 🠺🠸, 🠾🠼, 🡂🡀, 🡆🡄, 🡒🡐, 🡢🡠, 🡪🡨, 🡲🡰, 🡺🡸,
+🢂🢀, 🢒🢐, 🢖🢔, 🢚🢘, 🢡🢠, 🢣🢢, 🢥🢦, 🢧🢤, 🢩🢨, 🢫🢪")
+
+;; --------End of generated code
+(defvar cperl-starters cperl--basic-paired-delimiters)
 
 (defun cperl-cached-syntax-table (st)
   "Get a syntax table cached in ST, or create and cache into ST a syntax table.
@@ -5672,7 +6024,8 @@ indentation and initial hashes.  Behaves usually outside of comment."
 ;; The following lists are used for categorizing the entries found by
 ;; `cperl-imenu--create-perl-index'.
 (defvar cperl-imenu-package-keywords '("package" "class" "role"))
-(defvar cperl-imenu-sub-keywords '("sub" "method" "function" "fun"))
+(defvar cperl-imenu-sub-keywords '("sub" "method" "function" "fun"
+                                   "reader")) ;; for autogenerated
 (defvar cperl-imenu-pod-keywords '("=head"))
 
 (defun cperl-imenu--create-perl-index ()
@@ -5973,7 +6326,7 @@ functions (which they are not).  Inherits from `default'.")
             (concat
              "\\(^\\|[^$@%&\\]\\)\\<\\("
               (regexp-opt
-               '("CORE" "__FILE__" "__LINE__" "__SUB__" "__PACKAGE__"
+               '("CORE" "__FILE__" "__LINE__" "__SUB__" "__PACKAGE__" "__CLASS__"
                  "abs" "accept" "alarm" "and" "atan2"
                  "bind" "binmode" "bless" "caller"
                  "chdir" "chmod" "chown" "chr" "chroot" "close"
@@ -6087,7 +6440,7 @@ functions (which they are not).  Inherits from `default'.")
            ;; 1=my_etc, 2=white? 3=(+white? 4=white? 5=var
             ;; -------- variable declarations
             ;; (matcher (subexp facespec) ...
-           `(,(rx (sequence (or "state" "my" "local" "our" "field"))
+           `(,(rx (sequence (or "state" "my" "local" "our"))
                    (eval cperl--ws*-rx)
                    (opt (group (sequence "(" (eval cperl--ws*-rx))))
                    (group
@@ -6137,6 +6490,44 @@ functions (which they are not).  Inherits from `default'.")
                  (forward-char -2)) ; disable continued expr
               nil
               (1 font-lock-variable-name-face)))
+            ;; -------- builtin constants with and without package prefix
+            ;; (matcher subexp facespec)
+            `(,(rx (or space (in "=<>-"))
+                   (group (optional "&")
+                          (optional "builtin::")
+                          (or "inf" "nan")
+                          symbol-end))
+              1 'font-lock-constant-face)
+            ;; -------- field declarations
+            `(,(rx "field"
+                   (eval cperl--ws+-rx)
+                   (group (eval cperl--basic-variable-rx))
+                   (optional (sequence
+                              (eval cperl--ws+-rx)
+                              (group (eval cperl--attribute-list-rx)))))
+              (1 font-lock-variable-name-face)
+              ;; -------- optional attributes
+              ;; (anchored-matcher pre-form post-form subex-highlighters)
+              (,(rx
+                 (group (optional ":" (eval cperl--ws*-rx))
+                        (eval cperl--basic-identifier-rx))
+                 (optional "("
+                           (group (eval cperl--basic-identifier-rx))
+                           ")"))
+               ;; pre-form: Define range for anchored matcher
+               (if (match-beginning 2)
+                   (progn
+                     (goto-char (match-beginning 2))
+                     (match-end 2))
+                 ;; If there's no attribute list in match 2, set a short
+                 ;; limit to the search for the anchored matcher,
+                 ;; otherwise it might interpret stuff from the
+                 ;; initializer expression as attribute.
+                 (1+ (point)))
+               nil
+               (1 font-lock-constant-face)
+               (2 font-lock-string-face nil t) ; lax match, value is optional
+              ))
             ;; ----- foreach my $foo (
             ;; (matcher subexp facespec)
             `(,(rx symbol-start "for" (opt "each")
@@ -7773,6 +8164,7 @@ x= ...    Repetition assignment.
 \\u    Upcase the next character.  See also \\U and \\l, ucfirst.
 \\x    Hex character, e.g. \\x1b.
 ... ^ ...      Bitwise exclusive or.
+__CLASS__      The class of an object in construction
 __DATA__       Ends program source.
 __END__        Ends program source.
 ADJUST {...}   Callback for object creation
@@ -8984,6 +9376,24 @@ do extra unwind via `cperl-unwind-to-safe'."
   "Text property which inhibits refontification.")
 (make-obsolete-variable 'cperl-do-not-fontify nil "28.1")
 
+;;; Minor mode for optional Perl features
+(define-minor-mode cperl-extra-paired-delimiters-mode
+  "Toggle treatment of extra paired delimiters in Perl.
+Many non-ASCII paired delimiters can be used for quote-like constructs
+by activating the feature \"extra_paired_delimiters\" either explicitly
+or as part of the Perl 5.40 feature bundle.  This command allows
+`cperl-mode' to recognize the same set of paired delimiters, see the
+variable `cperl--extra-paired-delimiters'."
+  :group 'cperl
+  :lighter "«»"
+  :interactive (cperl-mode)
+  (if cperl-extra-paired-delimiters-mode
+      (progn
+        (setq-local cperl-starters cperl--extra-paired-delimiters)
+        (cperl-find-pods-heres (point-min) (point-max)))
+    (setq-local cperl-starters cperl--basic-paired-delimiters)
+    (cperl-find-pods-heres (point-min) (point-max))))
+
 (provide 'cperl-mode)
 
 ;;; cperl-mode.el ends here
diff --git a/test/lisp/progmodes/cperl-mode-resources/extra-delimiters.pl b/test/lisp/progmodes/cperl-mode-resources/extra-delimiters.pl
new file mode 100644 (file)
index 0000000..8d2f639
--- /dev/null
@@ -0,0 +1,23 @@
+use utf8;
+
+my $string_with_strange_delimiters  = q«a»;
+my $printed = 0;
+
+label:
+print $string_with_strange_delimiters;
+$printed = 1;
+
+# With cperl-extra-delimiters-mode=on the previous lines are a label
+# and a a print statement.  This line here is a comment.  Without
+# cperl-extra-delimiters-mode, all this is part of the variable
+# declaration.
+
+# Perl will print hist an "a" if called like this:
+#   perl -M5.040 extra.pl
+# ...and, if called without that -M switch,
+#   perl extra.pl
+# will print everything until here: «;
+
+$printed  or print $string_with_strange_delimiters;
+
+my $sanity = "eventually recovered.";
index 9420c0d1fa8cbd179488c135c1f9906001bbe4d4..14da28b0fd8016be50ff547e33e89c4f4f3c955b 100644 (file)
@@ -194,4 +194,16 @@ class Class::Class 0.01 {
     }
 }
 
+=head1 Perl 5.40 brings new stuff
+
+The __CLASS__ token (only for fontification) and the :reader
+method-generator for classes are available with Perl 5.40.
+
+=cut
+
+class With::Readers {
+    field $simple;
+    field $auto_reader :reader;
+    field $named_reader :reader(named);
+}
 1;
index 032690d20a514694d596e3300d5b641b93a98d8b..ebcb52c8ffd000a8ac92c73e7129750c143d8c9a 100644 (file)
@@ -16,4 +16,8 @@ class C
   }
 }
 
+class D {
+  field $decorated :param :reader(get_decoration);
+  field $no_attributes = not_an(attribute)
+}
 say "done!";
index 9d9718f719cc637e3551914436cb00c249ce1051..7c8cc3931bcbcdb93ee8a0bb3d1b0c1754699b8f 100644 (file)
@@ -216,6 +216,39 @@ attributes, prototypes and signatures."
                            'font-lock-variable-name-face)))
           (goto-char end-of-sub))))))
 
+(ert-deftest cperl-test-fontify-builtin-constants ()
+  "Test fontificiation of the floating point constants \"nan\" and \"inf\"."
+  (skip-unless (eq cperl-test-mode #'cperl-mode))
+  (let ((constants '("my $min=-builtin::inf;"
+                     "my $unknown = builtin::nan;"
+                     "if ($big == inf) {"
+                     "my $with_ampersand = &inf")))
+    (dolist (code constants)
+      (with-temp-buffer
+        (insert code)
+        (goto-char (point-min))
+        (funcall cperl-test-mode)
+        (font-lock-ensure)
+        (search-forward-regexp "&?\\(builtin::\\)?\\(inf\\|nan\\)")
+        (should (equal (get-text-property (match-beginning 0) 'face)
+                       'font-lock-constant-face)))))
+  ;; Also, test some things that are not these constants
+  (let ((lookalikes '(("sub inf { ... }" . font-lock-function-name-face)
+                      ("my $inf = 1E6;"  . font-lock-variable-name-face)
+                      ("$object->inf;"   . cperl-method-call))))
+    (dolist (doppelganger lookalikes)
+      (let ((code (car doppelganger))
+            (face (cdr doppelganger)))
+        (with-temp-buffer
+          (insert code)
+          (goto-char (point-min))
+          (funcall cperl-test-mode)
+          (font-lock-ensure)
+          (search-forward-regexp "&?\\(builtin::\\)?\\(inf\\|nan\\)")
+          (should (equal (get-text-property (match-beginning 0) 'face)
+                         face)))))))
+
+
 (ert-deftest cperl-test-fontify-class ()
   "Test fontification of the various elements in a Perl class."
   (skip-unless (eq cperl-test-mode #'cperl-mode))
@@ -241,6 +274,24 @@ attributes, prototypes and signatures."
                      'font-lock-variable-name-face))
       (should (equal (get-text-property (match-beginning 1) 'face)
                      'font-lock-variable-name-face))
+      ;; Fields
+      (goto-char (point-min))
+      (search-forward-regexp "\\(field\\)")
+      (should (equal (get-text-property (match-beginning 1) 'face)
+                     'font-lock-keyword-face))
+      (search-forward-regexp "\\(decorated\\)")
+      (should (equal (get-text-property (match-beginning 1) 'face)
+                     'font-lock-variable-name-face))
+      (search-forward-regexp "\\(:param\\)")
+      (should (equal (get-text-property (match-beginning 1) 'face)
+                     'font-lock-constant-face))
+      (search-forward-regexp "\\(get_decoration\\)")
+      (should (equal (get-text-property (match-beginning 1) 'face)
+                     'font-lock-string-face))
+      ;; Initializers are no attributes
+      (search-forward-regexp "\\(not_an\\)")
+      (should-not (equal (get-text-property (match-beginning 1) 'face)
+                     'font-lock-constant-face))
 )))
 
 (ert-deftest cperl-test-fontify-special-variables ()
@@ -516,7 +567,7 @@ Also includes valid cases with whitespace in strange places."
                                  valid invalid)))
 
 (ert-deftest cperl-test-attribute-list-rx ()
-  "Test attributes and attribute lists"
+  "Test attributes and attribute lists."
   (skip-unless (eq cperl-test-mode #'cperl-mode))
   (let ((valid
          '(":" ":foo" ": bar()" ":baz(quux):"
@@ -533,7 +584,26 @@ Also includes valid cases with whitespace in strange places."
     (cperl-test--validate-regexp (rx (eval cperl--attribute-list-rx))
                                  valid invalid)))
 
-(ert-deftest cperl-test-prototype-rx ()
+(ert-deftest cperl-test-field-declaration-rx ()
+  "Test field declarations with and without attributes."
+  (skip-unless (eq cperl-test-mode #'cperl-mode))
+  (let ((valid
+         '("field $fold"
+           "field @many"
+           "field %ofStrawberries"
+           "field $required :param"
+           "field $renamed :param(alias)"
+           "field $readable : param reader(get_readable)"))
+        (invalid
+         '("field name"                 ; missing sigil
+           "field $else::where"         ; invalid qualification
+           "field &code")))             ; invalid sigil
+    (cperl-test--validate-regexp (rx (eval cperl--field-declaration-rx))
+                                 valid invalid)))
+
+
+
+         (ert-deftest cperl-test-prototype-rx ()
   "Test subroutine prototypes"
   (skip-unless (eq cperl-test-mode #'cperl-mode))
   (let ((valid
@@ -562,6 +632,21 @@ Also includes valid cases with whitespace in strange places."
     (cperl-test--validate-regexp (rx (eval cperl--signature-rx))
                                  valid invalid)))
 
+(ert-deftest cperl-test-autogenerated-reader-rx ()
+  (let ((code-examples '("field $name :reader;"
+                         "field $field :reader(name);"
+                         "field $name :param :reader;"
+                         "field $field :param :reader(name);"
+                         "field $field :reader(name) :param;"
+                         "field $field :reader(name) = 'value';")))
+    (dolist (code code-examples)
+      (with-temp-buffer
+        (insert code)
+        (goto-char (point-min))
+        (search-forward-regexp (rx (eval cperl--sub-name-generated-rx)))
+        (should (string= (match-string 1) "reader"))
+        (should (string= (match-string 2) "name"))))))
+
 ;;; Test unicode identifier in various places
 
 (defun cperl--test-unicode-setup (code string)
@@ -604,7 +689,7 @@ point after the first occurrence of STRING (no regexp!)."
       (goto-char (point-min))
       (search-forward "-34")
       (beginning-of-defun)
-     (should (looking-at "sub")))))
+      (should (looking-at "sub")))))
 
 (ert-deftest cperl-test-unicode-varname ()
   (with-temp-buffer
@@ -827,6 +912,41 @@ perl-mode generally does not stringify bareword hash keys."
         (insert word)
         (should (string= word (cperl-word-at-point-hard)))))))
 
+(ert-deftest cperl-test-extra-delimiters ()
+  "Test whether cperl-mode can process unicode delimiters.
+The minor mode `cperl-extra-paired-delimiters-mode' controls whether we
+have extra paired delimiters."
+  (skip-unless (eq cperl-test-mode #'cperl-mode))
+  (with-temp-buffer
+    (insert-file-contents (ert-resource-file "extra-delimiters.pl"))
+    (funcall cperl-test-mode)
+    (cperl-extra-paired-delimiters-mode t)
+    (font-lock-ensure)
+    (goto-char (point-min))
+    (search-forward-regexp "\\(label:\\)")
+    (should (equal (get-text-property (match-beginning 1) 'face)
+                   font-lock-constant-face))
+    (search-forward-regexp "\\(comment\\)")
+    (should (equal (get-text-property (match-beginning 1) 'face)
+                   font-lock-comment-face))
+    (search-forward-regexp "\\(sanity\\)")
+    (should (equal (get-text-property (match-beginning 1) 'face)
+                   font-lock-variable-name-face))
+    ;; Now switch off the minor mode and redo
+    (cperl-extra-paired-delimiters-mode -1)
+    (font-lock-ensure)
+    (goto-char (point-min))
+    (search-forward-regexp "\\(label:\\)")
+    (should (equal (get-text-property (match-beginning 1) 'face)
+                   font-lock-string-face))
+    (search-forward-regexp "\\(comment\\)")
+    (should (equal (get-text-property (match-beginning 1) 'face)
+                   font-lock-string-face))
+    (search-forward-regexp "\\(sanity\\)")
+    (should (equal (get-text-property (match-beginning 1) 'face)
+                   font-lock-variable-name-face))))
+
+
 ;;; Function test: Building an index for imenu
 
 (ert-deftest cperl-test-imenu-index ()
@@ -853,7 +973,9 @@ created by CPerl mode, so skip it for Perl mode."
                         "Package::in_package_again"
                         "Erdős::Number::erdős_number"
                         "Class::Class::init"
-                        "Class::Inner::init_again")))
+                        "Class::Inner::init_again"
+                        "With::Readers::auto_reader"
+                        "With::Readers::named")))
         (dolist (sub expected)
           (should (assoc-string sub index)))))))