Community
    • Login

    Perl keywords "class" and "method" not recognised by Function List

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    6 Posts 3 Posters 238 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      JohnL22
      last edited by

      The language highlight for perl recognises new keywords - class, field, ADJUST, method - BUT the Function List does not recognise class or method entries

      PeterJonesP 1 Reply Last reply Reply Quote 0
      • PeterJonesP
        PeterJones @JohnL22
        last edited by PeterJones

        @JohnL22 said in Perl keywords "class" and "method" not recognised by Function List:

        The language highlight for perl recognises new keywords - class, field, ADJUST, method - BUT the Function List does not recognise class or method entries

        The syntax highlight keyword lists are separate from the FunctionList parser, so having added one doesn’t guarantee having added the other.

        And during the last update of the FunctionList parser, the test file that was being used didn’t already include that syntax, so I forgot to add in the class to match package and method to match sub. (I haven’t started using the new perl class/method syntax yet)

        Does this screenshot do what you want? (I added the class NewClassSyntax section to the Perl FunctionList test file for this screenshot)
        a9f4c6e2-3794-4270-b123-91db838f04ba-image.png

        using a file ending with…

        ################ From here on was added by pryrt/PeterJones to test Notepad++'s FunctionList, and is not part of pltags source code
        sub MyClass::new        { return bless {}, 'MyClass' }
        sub MyClass::do_thing   { return 42 }
        sub MyClass::debug      { print "ok\n" }
        
        sub Other::run          { return 'running' }
        sub Other::stop         { return 'stopped' }
        
        package NameSpace::Block {
            sub inBlock { return 1 }
            sub inBlockProto($) { return $_[0] }
            sub inBlockAttrib :prototype($) { return $_[0] }
        }
        
        package NameSpace::Semicolon;
        sub afterSemi { return 0 }
        
        class NewClassSyntax {
            method inBlock { return 1 }
            method inBlockProto($) { return $_[0] }
            method inBlockAttrib :prototype($) { return $_[0] }
        }
        

        If so, then you can replace c:\program files\Notepad++\functionList\perl.xml with

        <?xml version="1.0" encoding="UTF-8" ?>
        <!-- ==========================================================================\
        |
        |   To learn how to make your own language parser, please check the following
        |   link:
        |       https://npp-user-manual.org/docs/function-list/
        |
        \=========================================================================== -->
        <NotepadPlus>
        	<functionList>
        		<!-- ======================================================== [ PERL ] -->
        		<!-- Perl - functions and packages, including fully-qualtified subroutine names -->
        
        			<!--
        			... replacement perl parser ...: https://community.notepad-plus-plus.org/topic/19842
        			... make sure to rename the id\s*=\s*"perl_function" near the beginning with "perl_syntax" to match
        			...
        			... 2025-11-26: Improve the regex to not include as much pointless backtracking
        			-->
        
        			<parser
        				displayName="Perl"
        				id="perl_syntax"
        				commentExpr="(?x)                                               # free-spacing (see `RegEx - Pattern Modifiers`)
        							(?m-s:\x23.*$)                                      # Single Line Comment
        						|	(?s:__(?:END|DATA)__.*\Z)                           # Discard up till end-of-text
        					"
        			>
        				<classRange
        					mainExpr    ="(?x)                                          # free-spacing (see `RegEx - Pattern Modifiers`)
        							(?m)                                                # ^ and $ match at line-breaks
        							(?'PACKAGE_HEADER'
        								^                                               # NO leading white-space at start-of-line
        								(?-i:(?:package|class)\b)
        							)
        							(?s:.*?)                                            # whatever,
        							(?=                                                 # ...up till
        								\s*                                             # ...optional leading white-space of
        								(?:
        									(?&amp;PACKAGE_HEADER)                      # ...next header
        								|	\Z                                          # ...or end-of-text
        								)
        							)
        						"
        				>
        					<className>
        						<nameExpr expr="(?x)                                    # free-spacing (see `RegEx - Pattern Modifiers`)
        								\s
        								\K                                              # discard text matched so far
        								[^;{]+
        							"
        						/>
        					</className>
        					<function
        						mainExpr="(?x)                                          # free-spacing (see `RegEx - Pattern Modifiers`)
        								(?m)
        								^\h*
        								(?:sub|method)
        								\s+
        								(?:\w++\:\:)*                                   # optional prefix::package::names::
        								\w+
        								\s*+(?:\([^()]*+\)\s*+)?+                       # prototype or signature
        								(?:\:[^{]+)?+                                   # attributes
        								\{                                              # start of function body
        							"
        					>
        						<functionName>
        							<funcNameExpr expr="(?x)                            # free-spacing (see `RegEx - Pattern Modifiers`)
        									((?:sub|method)\s+)?
        									\K                                          # discard text matched so far
        									(?:\w++\:\:)*                               # optional prefix::package::names::
        									\w+                                         # move the \K to just before this line if you don't want prefix::package shown in the functionList Panel
        								"
        							/>
        						</functionName>
        					</function>
        				</classRange>
        				<function
        					mainExpr="(?x)                                              # free-spacing (see `RegEx - Pattern Modifiers`)
        							(?m)
        							^\h*
        							(?:sub|method)
        							\s+
        							(?:\w++\:\:)*                                       # optional prefix::package::names::
        							\w+                                                 # add \K before the \w+ if you don't want prefix::package:: shown in the functionList Panel
        							\s*+(?:\([^()]*+\)\s*+)?+                           # prototype or signature
        							(?:\:[^{]+)?+                                       # attributes
        							\{                                                  # start of function body
        						"
        				>
        					<functionName>
        						<nameExpr expr="(?x)                                    # free-spacing (see `RegEx - Pattern Modifiers`)
        								(?:(?:sub|method)\s+)?
        								\K                                              # discard text matched so far
        								(?:\w++\:\:)*                                   # optional prefix::package::names::
        								\w+
        							"
        						/>
        					</functionName>
        					<className>
        						<nameExpr expr="(?:sub|method)\s+\K\w+(::\w+)*(?=::\w)"/>
        					</className>
        				</function>
        			</parser>
        	</functionList>
        </NotepadPlus>
        

        and try it out for a while. If it does what you expect, let me know, and I can create an official Issue and submit the updated FunctionList definition with class and method added.

        And if you have examples of class or method definitions that include syntax that this updated functionList parser doesn’t handle right, give me a brief snippet of code which shows the ones that aren’t done right…

        update: for example, do you think ADJUST blocks should show up in as functions/methods in the FunctionList panel or not? Since it’s just code that’s run during object construction, so it’s more like a BEGIN/END block, which don’t show up as functions in the FunctionList, so I would lean toward not including them, but I could be persuaded otherwise.

        PeterJonesP 1 Reply Last reply Reply Quote 3
        • guy038G
          guy038
          last edited by guy038

          Hello @peterjones, @johnL22 and All,

          Peter, adding the part :

          
          class NewClassSyntax {
              method inBlock { return 1 }
              method inBlockProto($) { return $_[0] }
              method inBlockAttrib :prototype($) { return $_[0] }
          }
          

          At the end of the uniTest.txt file

          And updating the perl.xml file, within the Function List folder, does display the same function list view than your screenshot !


          Sorry, I’ve just forgot to test your new perl.xml file, so far, in order to simplify some regexes, if possible. I’ll have to find some time to get started on it !!

          Best Regards,

          guy038

          1 Reply Last reply Reply Quote 0
          • J
            JohnL22
            last edited by

            PeterJones et al
            Thank you,
            That looks to be what I would expect the Function List to contain.
            I only use the most simple syntax of “class” and “method” currently.
            I agree ADJUST is very like BEGIN & END (which I have NOT yet used), so I am undecided about including them in the Function List.
            I will use your updated code, test it out, and confirm it does what I need soon.
            Regards

            1 Reply Last reply Reply Quote 1
            • PeterJonesP
              PeterJones @PeterJones
              last edited by

              @PeterJones said in Perl keywords "class" and "method" not recognised by Function List:

              Please note: the bad highlighting on the $) on lines 325 and 326 compared to 316-317 is caused by the underlying lexer from the Lexilla library project. I have already created an issue there to get that resolved; it cannot be fixed in Notepad++ until it’s fixed in Lexilla.

              (This is separate from the Function List behavior, but since I thought you might notice something like that if you used prototypes, I decided to point it out.)

              1 Reply Last reply Reply Quote 2
              • guy038G
                guy038
                last edited by guy038

                Hello, @peterjones and All,

                I finally succeeded to get a new perl.xml file parser !


                In short :

                • I do NOT use any atomic construction !

                • In mainExpr of the class range, I do NOT use a named group but, simply, use the part ^ (?: package | class ) \b, twice !

                • I changed your prototype / signature syntax (?:\([^()]*+\)\s*+)?+ to (?: \( [\x20-\x27\x2A-\x7E]* \) \s* )?

                • I changed your attributes syntax (?:\:[^{]+)?+ to (?: : [\x20-\x7A\x7C-\x7E]+ \s* )?

                So, for these two syntaxes, I just supposed that standard ASCII characters are used, from \x20 to \x7E, except for \x28 and \x29 in one part and \x7B in second part ! May be, the \t should be part of each class character, either !

                • I changed the regex class name (?x)\s\K[^;{]+ to (?x)\s+\K.+?(?=[;{])

                BTW, my parser presently contains 13 strings \s. May be, the \h or even [\t\x20] should be more appropriate, in some parts ?

                Also, how many optional parts (?: \w+ :: )* may exist, before the mandatory \w+ of the function name ?

                Anyway, this is a first draft. As I’m definitively not a Perl Expert, I probably missed a lot !


                So, here is the first version of my Perl.xml parser :

                <?xml version="1.0" encoding="UTF-8" ?>
                <!-- ==========================================================================\
                |
                |   To learn how to make your own language parser, please check the following
                |   link:
                |       https://npp-user-manual.org/docs/function-list/
                |
                \=========================================================================== -->
                <NotepadPlus>
                	<functionList>
                		<!-- ======================================================== [ PERL ] -->
                		<!-- Perl - functions and packages, including fully-qualtified subroutine names -->
                
                			<parser
                				displayName="Perl"  id="perl_syntax"
                
                				commentExpr="(?x)                                               # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                							(?m-s:                                              # 'Multi-lines' mode ( ^ and $ match at line-breaks ) / 'Dot' char does NOT match line-breaks
                								\x23 .*                                         #   Single Line Comment ( #................ )
                							)                                                   #
                							|                                                   # OR
                							(?s:                                                # 'Single line' mode (letter s optional as mode set by DEFAULT)
                								__ (?: END | DATA ) __                          #   String '__END__' or '__DATA__' 
                								.*                                              #   ANY character(s), including line-breaks, till...
                								\Z                                              #   Last line-break, included
                							)
                						"
                			>
                				<classRange
                					mainExpr="(?x)                                              # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                							(?m-i)                                              # 'Multi-lines' mode (^ and $ match at line-breaks) / 'Sensitive case' mode
                							^                                                   # NO leading white-space at start of line
                							(?: package | class ) \b                            # Header : word 'package' or 'clas', in LOWER case
                							(?s:                                                # 'Single line' mode (letter s optional as mode set by DEFAULT)
                								.+?                                             #   ANY character(s), including line-breaks, till...
                                            )                                                   # Section below, excluded
                							(?=                                                 # Start of look-ahead
                								\s*                                             #   Optional leading white-space of
                								^                                               #   NO leading white-space at start of line 
                								(?: package | class ) \b                        #   Next header : word 'package' or 'clas', in LOWER case
                							|                                                   # OR
                								\Z                                              #   last line-break
                							)                                                   # End of look-ahead
                						"
                				>
                					<className>
                						<nameExpr expr="(?x)                                    # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                										\s+                                     # Leading white-space(s)
                										\K                                      # Discard text matched so far
                										.+?                                     # ANY character(s) till...
                										(?= [;{] )                              # First semi-colon or left brace, excluded
                									"
                						/>
                					</className>
                					<function
                						mainExpr="(?x)                                          # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                								(?m-i)                                          # 'Mutli-lines' mode (^ and $ match at line-breaks) / 'Sensitive case' mode
                								^ \h*                                           # Optional leading spaces or tabulations
                								(?: sub | method ) \b                           # Word 'sub' or 'method', in LOWER case 
                								\s+                                             # White-space character(s)
                								(?: \w+ :: )*                                   # Optional list of words EACH followed with ::
                								\w+                                             # Word character(s)
                								\s*                                             # Optional white-space character(s)
                								(?: \( [\x20-\x27\x2A-\x7E]* \) \s* )?          # Optional Prototype or Signature section
                								(?: : [\x20-\x7A\x7C-\x7E]+ \s* )?              # Optional Attributes section
                								\{                                              # Start of function body
                							"
                					>
                						<functionName>
                							<funcNameExpr expr="(?x)                            # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                												(?: sub | method )              # Word 'sub' or 'method', in LOWER case
                												\s+                             # White-space character(s)
                												\K                              # Discard text matched, so far (move this line right before \w+ if 'prefix::' part NOT desired)
                												(?: \w+ :: )*                   # Optional prefix:: part ( package:: / names:: )
                												\w+                             # Word character(s)
                											"
                							/>
                						</functionName>
                					</function>
                				</classRange>
                				<function
                					mainExpr="(?x)                                              # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                							(?m-i)                                              # 'Mutli-lines' mode (^ and $ match at line-breaks) / 'Sensitive case' mode
                							^ \h*                                               # Optional leading spaces or tabulations
                							(?: sub | method )                                  # Word 'sub' or 'method', in LOWER case 
                							\s+                                                 # White-space character(s)
                							(?: \w+:: )*                                        # Optional list of words, EACH followed with ::
                							\w+                                                 # Word character(s)
                							\s*                                                 # Optional white-space character(s)
                							(?: \( [\x20-\x27\x2A-\x7E]* \) \s* )?              # Optional Prototype or Signature section
                							(?: : [\x20-\x7A\x7C-\x7E]+ \s* )?                  # Optional Attributes section
                							\{                                                  # Start of function body
                						"
                				>
                					<functionName>
                						<nameExpr expr="(?x)                                    # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                										(?: sub | method )                      # Word 'sub' or 'method', in LOWER case
                										\s+                                     # White-space character(s)
                										\K                                      # Discard text matched, so far ( move this line right before \w+ if part 'prefix::' NOT desired
                										(?: \w+ :: )*                           # Optional prefix:: part ( package:: / names:: )
                										\w+                                     # Word character(s)
                									"
                						/>
                					</functionName>
                					<className>
                						<nameExpr expr="(?x)                                    # 'Free-spacing' mode (see `RegEx - Pattern Modifiers`)
                										(?: sub | method )                      # Word 'sub' or 'method', in LOWER case
                										\s+                                     # White-space character(s)
                										\K                                      # Discard text matched, so far
                										\w+                                     # Word character(s)
                										( :: \w+ )*                             # Optional list of words, EACH preceded with ::
                										(?= :: \w )                             # Till a last string ':: + word char' excluded
                									"
                						/>
                					</className>
                				</function>
                			</parser>
                	</functionList>
                </NotepadPlus>
                

                May be, it would be interesting to compare my version to yours, in terms of speed. To my mind, it’s seems similar !?

                Best Regards,

                guy038

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post
                The Community of users of the Notepad++ text editor.
                Powered by NodeBB | Contributors