Community
    • Login

    Need help to make Maxscript functions recognized by Function List

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    function listmaxscript
    8 Posts 2 Posters 4.3k 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.
    • WerwacKW
      WerwacK
      last edited by

      Hello,

      I am currently using a User Defined Language setup I found a long time ago for Maxscript, the internal scripting language for 3dsMax. Since the definition is old and the package not so easy to found I shared it on my website here: http://werwackfx.com/index.php/graphictools/maxscript-main/maxscript-articles/73-maxscriptinnotepadpp

      This language definition is nice and really helps to work with Notepad++ when developping with Maxscript. Unfortunately it is not complete and the functions are not recognized in the Function Lister.

      Can someone help me to write the appropriate regular expressions to make them visible?
      Beside it would be very nice if this language could be intergrated by default into NPP package.

      Here are how the functions look like in the code (I do appologize but I don’t see the balise “Code” to highlight it nor how to attach a file).

      Thank you very much for your help.

      /*
      Block comment
      */

      – Line comment

      – Files extension can be *.ms or *.mcr

      global myGlobalVariable

      macroScript MyMacroscript category:“MyMacroscript” internalCategory:“MyMacroscript” tooltip: “MyMacroscript” buttonText:“MyMacroscript” Icon:#(“MyMacroscript”,1)
      (
      – blabla
      local lScriptRootDir = getdir #userScripts + “\”

      local lLauncherFile = lScriptRootDir + "_ScriptLauncher.ms"
      if doesFileExist lLauncherFile then
      	filein lLauncherFile
      else if doesFileExist (lLauncherFile + "e") then
      	filein (lLauncherFile + "e")
      else messagebox ("File \"" + filenameFromPath lLauncherFile + "\" not found in script directory\n\nIf the script has been uninstalled, shortcuts must be removed manually") title:"Warning"
      

      )

      macroScript MyMacroscriptWithLessParameters buttonText:“MyMacroscriptWithLessParameters” Icon:#(“MyMacroscript”,1)
      (
      – blabla
      messagebox “toto”
      )

      – functions can be identified by the term “fn” or by “function”, this with the same behavior
      – return value is not mandatory
      – indentations are not madatory
      fn myFunction01 =
      (
      local lMyVar = “toto” – the use of “local” is not mandatory
      return lMyVar
      )

      function myFunction02 myParam =
      (
      messagebox ("myParam: " + myParam as string)
      )

      function myFunction03 myOptionalParam: myOptionalParam02:“my default value” = – optional parameters ends with : and may be followed by an initisalization value
      (
      messagebox ("myOptionalParam02: " + myOptionalParam02 as string)
      )

      struct tWkSubstanceObjectBoundaries
      (
      myVariable, – initialization of the variables is not mandatory
      myOtherVariable = undefined,

      mfDisplayInfos =
      (
      	format "\myVariable: %\n" (if undefined != myVariable then myVariable.name else "undefined")
      ),
      
      fn mfInit rScriptRootDir: =
      (
      	if unsupplied != rScriptRootDir do
      		mSCRIPTROOTDIR = rScriptRootDir
      )
      
      -- note that there is no coma at the end of the last variable or function of the structure
      

      )

      1 Reply Last reply Reply Quote 0
      • MAPJe71M
        MAPJe71
        last edited by

        @WerwacK I’ll will give it a try.

        1 Reply Last reply Reply Quote 0
        • WerwacKW
          WerwacK
          last edited by

          Hi MAPJe71,

          Thanks a lot, that’s very kind of you :)

          I think this would also be appreciated by Lukas, a user how also wanted to use NPP with Maxscript: https://notepad-plus-plus.org/community/topic/13259/user-defined-language-problem-with-code-folding

          By the way I noticed in the code I submitted above that the single-line comments have been converted to one single character. Line comments are really dash dash: - - (with no space inbetween).

          Werwack

          1 Reply Last reply Reply Quote 0
          • MAPJe71M
            MAPJe71
            last edited by

            @WerwacK could you try the following parser:

            			<parser
            				displayName="MAXScript - Scripting language for AutoDesk 3ds Max"
            				id         ="maxscript_syntax"
            				commentExpr="(?x)                                               # Utilize inline comments (see `RegEx - Pattern Modifiers`)
            								(?s:\x2F\x2A.*?\x2A\x2F)                        # Multi Line Comment
            							|	(?m-s:-{2}.*$)                                  # Single Line Comment
            							|	(?:                                             # String Literal - Double Quoted
            									@?\x22                                      # - start-of-double-quoted-(meta-)string indicator
            									(?:	[^\x22\x5C]                             # - any character except double-quote and backslash
            									|	\x5C                                    # - unless: backslash escape sequence for...
            										(?:	[\x22\x25\x2A\x3F\x5Cnrt]           #   ...a double-quote, %, *, ?, \, newline, carriage-return, tab...
            										|	x[A-Fa-f\d]+                        #   ...or character code sequence
            										)
            									)*                                          # - can be empty
            									\x22                                        # - end-of-double-quoted-(meta-)string indicator
            								)
            							"
            			>
            				<function
            					mainExpr="(?x)                                              # Utilize inline comments (see `RegEx - Pattern Modifiers`)
            							(?i:
            								(?:mapped\s+)?(?:fn|function)
            							|	macroScript
            							)\s+
            							\K
            							(?'VALID_ID'                                        # valid identifier, use as subroutine
            								\b(?!(?-i:                                      # keywords (case sensitive), not to be used as identifier
            									a(?:bout|n(?:d|imate)|[st])
            								|	by
            								|	c(?:a(?:se|tch)|o(?:llect|ntinue|ordsys))
            								|	do
            								|	e(?:lse|xit)
            								|	f(?:n|or|rom|unction)
            								|	global
            								|	i[fn]
            								|	local
            								|	ma(?:croscript|pped|x)
            								|	not
            								|	o(?:ff?|[nr])
            								|	p(?:arameters|ersistent|lugin)
            								|	r(?:cmenu|eturn|ollout)
            								|	s(?:et|truct)
            								|	t(?:hen|hrow|o(?:ol)?|ry)
            								|	u(?:ndo|tility)
            								|	w(?:h(?:e(?:n|re)|ile)|ith)
            								)\b)
            								[A-Za-z_]\w*                                    # valid character combination for identifiers
            							)
            						"
            				/>
            			</parser>
            

            with the following associations:

            			<association id=   "maxscript_syntax"        userDefinedLangName="MaxScript"      />
            			<association id=   "maxscript_syntax"        ext=".ms"                            />
            			<association id=   "maxscript_syntax"        ext=".mcr"                           />
            

            NOTE: make sure the userDefinedLangName value exactly equals (i.e. case sensitive) the name used in your User Defined Language setup.

            1 Reply Last reply Reply Quote 0
            • WerwacKW
              WerwacK
              last edited by

              Hi MAPJe71,

              Thanks a lot!! It works pretty well.

              There is maybe something that could be improved. I saw on the screenshot provided on the Function List page (https://notepad-plus-plus.org/features/function-list.html) that there is a folding level between the name of the file and the function list. I assume this is for classes.
              Would it be possible to make the macroscripts and structure appear as if they were classes? That would allow to distinguish functions that are part of a structure from those that are at the root level. Beside it would also separate functions from one structure from those of an other one.

              I put some code sample and a screenshot of the result here: https://we.tl/mrbLNJhywO

              Best regards,

              Werwack

              1 Reply Last reply Reply Quote 0
              • MAPJe71M
                MAPJe71
                last edited by

                Nice to hear it works and thanks for the samples!
                Looking at the grammar I was already thinking about visualizing the struct as a branch in the tree. I will let you know how it works out.

                1 Reply Last reply Reply Quote 0
                • MAPJe71M
                  MAPJe71
                  last edited by

                  @WerwacK

                  To have both macroscripts and structs appear as branches in the tree I could only think of implementing separate parsers for .ms and .mcr files.
                  This however requires to associate each parser with a different User Defined Language (UDL). You could define two UDL’s that only differ by name e.g. MaxScript and MaxScript Macro and associate them as follows:

                              <association id=   "maxscript_syntax"             userDefinedLangName="MaxScript"       />
                              <association id=   "maxscript_syntax"             ext=".ms"                             />
                              <association id=   "maxscript_macrosyntax"        userDefinedLangName="MaxScript Macro" />
                              <association id=   "maxscript_macrosyntax"        ext=".mcr"                            />
                  

                  The two parser would then look like this:

                  			<!-- =================================================== [ MAXScript ] -->
                  
                  			<parser
                  				displayName="MAXScript - Scripting language for AutoDesk 3ds Max"
                  				id         ="maxscript_syntax"
                  				commentExpr="(?x)                                               # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  								(?s:\x2F\x2A.*?\x2A\x2F)                        # Multi Line Comment
                  							|	(?m-s:-{2}.*$)                                  # Single Line Comment
                  							|	(?:                                             # String Literal - Double Quoted
                  									@?\x22                                      # - start-of-double-quoted-(meta-)string indicator
                  									(?:	[^\x22\x5C]                             # - any character except double-quote and backslash
                  									|	\x5C                                    # - unless: backslash escape sequence for...
                  										(?:	[\x22\x25\x2A\x3F\x5Cnrt]           #   ...a double-quote, %, *, ?, \, newline, carriage-return, tab...
                  										|	x[A-Fa-f\d]+                        #   ...or character code sequence
                  										)
                  									)*                                          # - can be empty
                  									\x22                                        # - end-of-double-quoted-(meta-)string indicator
                  								)
                  							"
                  			>
                  				<classRange
                  					mainExpr    ="(?x)                                          # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  							^\h*
                  							(?i:struct)\s+
                  							(?'VALID_ID'                                        # valid identifier, use as subroutine
                  								\b(?!(?-i:                                      # keywords (case sensitive), not to be used as identifier
                  									a(?:bout|n(?:d|imate)|[st])
                  								|	by
                  								|	c(?:a(?:se|tch)|o(?:llect|ntinue|ordsys))
                  								|	do
                  								|	e(?:lse|xit)
                  								|	f(?:n|or|rom|unction)
                  								|	global
                  								|	i[fn]
                  								|	local
                  								|	ma(?:croscript|pped|x)
                  								|	not
                  								|	o(?:ff?|[nr])
                  								|	p(?:arameters|ersistent|lugin)
                  								|	r(?:cmenu|eturn|ollout)
                  								|	s(?:et|truct)
                  								|	t(?:hen|hrow|o(?:ol)?|ry)
                  								|	u(?:ndo|tility)
                  								|	w(?:h(?:e(?:n|re)|ile)|ith)
                  								)\b)
                  								[A-Za-z_]\w*                                    # valid character combination for identifiers
                  							)
                  							\s*[^()]*
                  							\(                                                  # start-of-body indicator
                  							(?s:.*)                                             # body contents
                  							\)                                                  # end-of-body indicator
                  						"
                  					openSymbole ="\("
                  					closeSymbole="\)"
                  				>
                  					<className>
                  						<nameExpr expr="(?i:struct)\s+\K[A-Za-z_]\w*" />
                  					</className>
                  					<function
                  						mainExpr="(?x)                                          # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  								^\h*
                  								(?i:fn|function)\s+
                  								\K
                  								(?'VALID_ID'                                    # valid identifier, use as subroutine
                  									\b(?!(?-i:                                  # keywords (case sensitive), not to be used as identifier
                  										a(?:bout|n(?:d|imate)|[st])
                  									|	by
                  									|	c(?:a(?:se|tch)|o(?:llect|ntinue|ordsys))
                  									|	do
                  									|	e(?:lse|xit)
                  									|	f(?:n|or|rom|unction)
                  									|	global
                  									|	i[fn]
                  									|	local
                  									|	ma(?:croscript|pped|x)
                  									|	not
                  									|	o(?:ff?|[nr])
                  									|	p(?:arameters|ersistent|lugin)
                  									|	r(?:cmenu|eturn|ollout)
                  									|	s(?:et|truct)
                  									|	t(?:hen|hrow|o(?:ol)?|ry)
                  									|	u(?:ndo|tility)
                  									|	w(?:h(?:e(?:n|re)|ile)|ith)
                  									)\b)
                  									[A-Za-z_]\w*                                # valid character combination for identifiers
                  								)
                  							"
                  					>
                  						<functionName>
                  							<funcNameExpr expr="[A-Za-z_]\w*" />
                  						</functionName>
                  					</function>
                  				</classRange>
                  				<function
                  					mainExpr="(?x)                                              # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  							^\h*
                  							(?i:fn|function|macroscript)\s+
                  							\K
                  							(?'VALID_ID'                                        # valid identifier, use as subroutine
                  								\b(?!(?-i:                                      # keywords (case sensitive), not to be used as identifier
                  									a(?:bout|n(?:d|imate)|[st])
                  								|	by
                  								|	c(?:a(?:se|tch)|o(?:llect|ntinue|ordsys))
                  								|	do
                  								|	e(?:lse|xit)
                  								|	f(?:n|or|rom|unction)
                  								|	global
                  								|	i[fn]
                  								|	local
                  								|	ma(?:croscript|pped|x)
                  								|	not
                  								|	o(?:ff?|[nr])
                  								|	p(?:arameters|ersistent|lugin)
                  								|	r(?:cmenu|eturn|ollout)
                  								|	s(?:et|truct)
                  								|	t(?:hen|hrow|o(?:ol)?|ry)
                  								|	u(?:ndo|tility)
                  								|	w(?:h(?:e(?:n|re)|ile)|ith)
                  								)\b)
                  								[A-Za-z_]\w*                                    # valid character combination for identifiers
                  							)
                  						"
                  				/>
                  			</parser>
                  			<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
                  			<parser
                  				displayName="MAXScript Macro - Scripting language for AutoDesk 3ds Max"
                  				id         ="maxscript_macrosyntax"
                  				commentExpr="(?x)                                               # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  								(?s:\x2F\x2A.*?\x2A\x2F)                        # Multi Line Comment
                  							|	(?m-s:-{2}.*$)                                  # Single Line Comment
                  							|	(?:                                             # String Literal - Double Quoted
                  									@?\x22                                      # - start-of-double-quoted-(meta-)string indicator
                  									(?:	[^\x22\x5C]                             # - any character except double-quote and backslash
                  									|	\x5C                                    # - unless: backslash escape sequence for...
                  										(?:	[\x22\x25\x2A\x3F\x5Cnrt]           #   ...a double-quote, %, *, ?, \, newline, carriage-return, tab...
                  										|	x[A-Fa-f\d]+                        #   ...or character code sequence
                  										)
                  									)*                                          # - can be empty
                  									\x22                                        # - end-of-double-quoted-(meta-)string indicator
                  								)
                  							"
                  			>
                  				<classRange
                  					mainExpr    ="(?x)                                          # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  							^\h*
                  							(?i:macroscript)\s+
                  							(?'VALID_ID'                                        # valid identifier, use as subroutine
                  								\b(?!(?-i:                                      # keywords (case sensitive), not to be used as identifier
                  									a(?:bout|n(?:d|imate)|[st])
                  								|	by
                  								|	c(?:a(?:se|tch)|o(?:llect|ntinue|ordsys))
                  								|	do
                  								|	e(?:lse|xit)
                  								|	f(?:n|or|rom|unction)
                  								|	global
                  								|	i[fn]
                  								|	local
                  								|	ma(?:croscript|pped|x)
                  								|	not
                  								|	o(?:ff?|[nr])
                  								|	p(?:arameters|ersistent|lugin)
                  								|	r(?:cmenu|eturn|ollout)
                  								|	s(?:et|truct)
                  								|	t(?:hen|hrow|o(?:ol)?|ry)
                  								|	u(?:ndo|tility)
                  								|	w(?:h(?:e(?:n|re)|ile)|ith)
                  								)\b)
                  								[A-Za-z_]\w*                                    # valid character combination for identifiers
                  							)
                  							\s*[^()]*
                  							\(                                                  # start-of-body indicator
                  							(?s:.*)                                             # body contents
                  							\)                                                  # end-of-body indicator
                  						"
                  					openSymbole ="\("
                  					closeSymbole="\)"
                  				>
                  					<className>
                  						<nameExpr expr="(?i:macroscript)\s+\K[A-Za-z_]\w*" />
                  					</className>
                  					<function
                  						mainExpr="(?x)                                          # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  								^\h*
                  								(?i:fn|function)\s+
                  								\K
                  								(?'VALID_ID'                                    # valid identifier, use as subroutine
                  									\b(?!(?-i:                                  # keywords (case sensitive), not to be used as identifier
                  										a(?:bout|n(?:d|imate)|[st])
                  									|	by
                  									|	c(?:a(?:se|tch)|o(?:llect|ntinue|ordsys))
                  									|	do
                  									|	e(?:lse|xit)
                  									|	f(?:n|or|rom|unction)
                  									|	global
                  									|	i[fn]
                  									|	local
                  									|	ma(?:croscript|pped|x)
                  									|	not
                  									|	o(?:ff?|[nr])
                  									|	p(?:arameters|ersistent|lugin)
                  									|	r(?:cmenu|eturn|ollout)
                  									|	s(?:et|truct)
                  									|	t(?:hen|hrow|o(?:ol)?|ry)
                  									|	u(?:ndo|tility)
                  									|	w(?:h(?:e(?:n|re)|ile)|ith)
                  									)\b)
                  									[A-Za-z_]\w*                                # valid character combination for identifiers
                  								)
                  							"
                  					>
                  						<functionName>
                  							<funcNameExpr expr="[A-Za-z_]\w*" />
                  						</functionName>
                  					</function>
                  				</classRange>
                  				<function
                  					mainExpr="(?x)                                              # Utilize inline comments (see `RegEx - Pattern Modifiers`)
                  							^\h*
                  							(?i:macroscript)\s+
                  							\K
                  							(?'VALID_ID'                                        # valid identifier, use as subroutine
                  								\b(?!(?-i:                                      # keywords (case sensitive), not to be used as identifier
                  									a(?:bout|n(?:d|imate)|[st])
                  								|	by
                  								|	c(?:a(?:se|tch)|o(?:llect|ntinue|ordsys))
                  								|	do
                  								|	e(?:lse|xit)
                  								|	f(?:n|or|rom|unction)
                  								|	global
                  								|	i[fn]
                  								|	local
                  								|	ma(?:croscript|pped|x)
                  								|	not
                  								|	o(?:ff?|[nr])
                  								|	p(?:arameters|ersistent|lugin)
                  								|	r(?:cmenu|eturn|ollout)
                  								|	s(?:et|truct)
                  								|	t(?:hen|hrow|o(?:ol)?|ry)
                  								|	u(?:ndo|tility)
                  								|	w(?:h(?:e(?:n|re)|ile)|ith)
                  								)\b)
                  								[A-Za-z_]\w*                                    # valid character combination for identifiers
                  							)
                  						"
                  				/>
                  			</parser>
                  
                  1 Reply Last reply Reply Quote 0
                  • WerwacKW
                    WerwacK
                    last edited by

                    Hi MAPJe71,

                    Thank you for this new code.
                    I think having 2 separated parser definitions, one for the scripts (.ms) and one for the macros (.mcr), is fine in most of the cases, and your suggestion is nice :)

                    I tested the code above and I have the following issues:

                    • for .ms files, the structure is correctly identified with the “class” icon and as a new folder level. If there are 2 or more structures in the file though other structures are not recognized at all.

                    • for .mcr files the new folder level for macros is not recognized. It would be nice if it could also support several macros in the .mcr file.

                    I updated the sample files to introduce several structures and macros to test this, you can find them in this package: https://we.tl/kSLs8d5zhg

                    Thanks a lot for your help,

                    Werwack

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