["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])
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")
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
`(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.")
(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.
;; 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 ()
(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"
;; 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
(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")
\\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
"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
'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))
'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 ()
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):"
(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
(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)
(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
(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 ()
"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)))))))