Enable Function List in Notepad++ for AHK Scripts (with classes now)

Scripting and setups with Notepad++ and AutoHotkey.
Noesis
Posts: 301
Joined: 26 Apr 2014, 07:57

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

13 Mar 2017, 03:01

Hi guys, great work on this.

NightWolf that latest code seems to do the trick for that case of a comment before the opening bracket, and for me I'm not seeing anything excluded previously like mapa seems to be.

One limitation that annoys me a little with this is the exclusion of functions beginning with if or while, so I thought I'd run this by you guys, as it seems to fix it for me without including legitimate if and while statements and doesn't seem to have other side effects (despite built in commands like ifequal or ifnotexist and others, probably because the rest of the regex excludes these for other reasons like they need a space or comma before any parenthesis ?).

Change the mainExpr line everywhere where it currently reads

Code: Select all

!(if|while|for)
to be

Code: Select all

!(if[ \(]|while[ \(]|for[ \(])
Anyway Just figure I'd share it should you guys want to test it out, and perhaps include it but there could be instances where it fails I'm not noticing (FYI I've only changed the function section not the class part for the time being).
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

13 Mar 2017, 11:05

mapa4, You're welcome.

I really thought that last version worked, it seems to work for me without skipping now. Maybe you checked before I made the edits?


Image


Noesis,
I think you are right it is annoying and I took your suggestion and used it in the parser, with a slight change (?!(if\(|while\(|for\()) will stop cases where the line starts with if while for, and is immediately followed by the open parenthesis from matching, while allowing if there is other text between to still match. Thank you very much.

Code: Select all

			<parser id="ahk_function" displayName="AHK" commentExpr="(\/\*[\s+\w+\n]{1,}\*\/)|(^;[\s+\w+]{1,})">
				<!-- AutoHotKey Function List -->
				<classRange
					mainExpr="^[\t ]*(class|struct)[\t ]+[\w]+([\t ]+|[\t ]+(extends)[\s]+(\,[\t ]*|(\\|[\w][\w]*))+[\s]*)?([\s\t]+;.*?[\r\n]+\{|[\s\t\r\n]*\{)"
					openSymbole = "\{"
					closeSymbole = "\}"
					displayMode="node">
					<className>
						<nameExpr expr="(class|struct)[\t ]+[\w]+"/>
						<nameExpr expr="[\t ]+[\w]+"/>
						<nameExpr expr="[\w]+"/>
					</className>
					<function
						mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.]*\)([\s\t]+;.*?[\r\n]+\{|[\s\t\r\n]*\{)|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?">
						<functionName>
							<funcNameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
						</functionName>
					</function>
				</classRange>
				<function
					mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.]*\)([\s\t]+;.*?[\r\n]+\{|[\s\t\r\n]*\{)|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?"
					displayMode="$className->$functionName">
					<functionName>
						<nameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
					</functionName>
				</function>
			</parser>
*EDIT*
Above parser code also applies the comment fix to class names, so cases where there is a comment after a class declaration but before the open bracket should be fixed as well.

*EDIT2*
A bug I just noticed when testing above class fixes, there needs to be a new line after the closing bracket ( } ) of a class. Not sure this is a problem I'll look into much, since it should be easy to just add a new line to the end of any file.
Last edited by Nightwolf85 on 13 Mar 2017, 13:10, edited 1 time in total.
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

13 Mar 2017, 12:57

I've found out that if I update the 'commentExpr' to match AHK comments more accurately the work it took to fix the comment issue was not completely needed ( it was needed for class still apparently ). I see no benefit to using one fix over the other though, so I've put both in at the same time.


The last case I've fixed is for:

Code: Select all

aa(
	  test = Value ; Comment
	, test2 = "Test") {
}
It will display kind of ugly and probably get cut off at some point, but works. I've seen quite a few complicated functions have this format so it may be helpful.

Code: Select all

			<parser id="ahk_function" displayName="AHK" commentExpr="((/\*.*?\*)/|((?<=[\s\t]);.*?$))">
				<!-- AutoHotKey Function List -->
				<classRange
					mainExpr="^[\t ]*(class|struct)[\t ]+[\w]+([\t ]+|[\t ]+(extends)[\s]+(\,[\t ]*|(\\|[\w][\w]*))+[\s]*)?([\s\t]+;.*?[\r\n]+\{|[\s\t\r\n]*\{)"
					openSymbole = "\{"
					closeSymbole = "\}"
					displayMode="node">
					<className>
						<nameExpr expr="(class|struct)[\t ]+[\w]+"/>
						<nameExpr expr="[\t ]+[\w]+"/>
						<nameExpr expr="[\w]+"/>
					</className>
					<function
						mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t]+;.*?[\r\n]+\{|[\s\t\r\n]*\{)|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?">
						<functionName>
							<funcNameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
						</functionName>
					</function>
				</classRange>
				<function
					mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t]+;.*?[\r\n]+\{|[\s\t\r\n]*\{)|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?"
					displayMode="$className->$functionName">
					<functionName>
						<nameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
					</functionName>
				</function>
			</parser>
User avatar
mapa4
Posts: 13
Joined: 14 Nov 2013, 02:55

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

13 Mar 2017, 13:28

Hi NightWolf85,

Based on your last example and also your last code above, here are 2 examples where the parser seems to be lost :
MWSnap028.png
MWSnap028.png (12.85 KiB) Viewed 15203 times
MWSnap029.png
MWSnap029.png (13.82 KiB) Viewed 15203 times
Mapa.
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

13 Mar 2017, 20:19

You are correct, my mistake. I didn't think of there being a space or tab after the comment and new line before the bracket, which was a stupid assumption.

Fixed:

Code: Select all

Removed, try version below
This still has the potential to eat up other functions in certain cases like below, granted it is a syntax error so it might not be a problem. I have a fix for that, which breaks extra comment lines like the second function below.

Code: Select all

;This currently breaks matches as it will consume other functions
aa() ;Test Comment {
 blah{
}

;Fix for above breaks this from matching
bb() ; Comment
; More Comments
{
}
Let me know what you guys think is the better of the two, as I can't decide.

*EDIT*
I think I've got a version that covers this problem, and the other, done working on it for tonight. The RegEx for functions is getting long, and complicated.

Code: Select all

			<parser id="ahk_function" displayName="AHK" commentExpr="((/\*.*?\*)/|((?<=[\s\t]);.*?$))">
				<!-- AutoHotKey Function List -->
				<classRange
					mainExpr="^[\t ]*(class|struct)[\t ]+[\w]+([\t ]+|[\t ]+(extends)[\s]+(\,[\t ]*|(\\|[\w][\w]*))+[\s]*)?([\s\t]+?;[^\r\n]*?([\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))+?[\s\t]*\{|([\s\t\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))+?[\s\t]*\{)"
					openSymbole = "\{"
					closeSymbole = "\}"
					displayMode="node">
					<className>
						<nameExpr expr="(class|struct)[\t ]+[\w]+"/>
						<nameExpr expr="[\t ]+[\w]+"/>
						<nameExpr expr="[\w]+"/>
					</className>
					<function
						mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t]+?;[^\r\n]*?([\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))+?[\s\t]*\{|([\s\t\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))+?[\s\t]*\{)|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?">
						<functionName>
							<funcNameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
						</functionName>
					</function>
				</classRange>
				<function
					mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t]+?;[^\r\n]*?([\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))+?[\s\t]*\{|([\s\t\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))+?[\s\t]*\{)|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?"
					displayMode="$className->$functionName">
					<functionName>
						<nameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
					</functionName>
				</function>
			</parser>
Noesis
Posts: 301
Joined: 26 Apr 2014, 07:57

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

14 Mar 2017, 06:21

Latest version seems pretty damn good to me (not sure what the other choice was but my guess is you decided against it so removed it). No need for errors to be included as functions IMO (ultimately they're not functions and aren't really anything unless fixed). I also tend to not do code comments like in the bb() function above, but works for them now anyway.
User avatar
mapa4
Posts: 13
Joined: 14 Nov 2013, 02:55

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

14 Mar 2017, 06:29

Hi NightWolf85,

Wow, I have to say that I have no more use cases to propose to your brain ;-)
For me it is perfect, well done and thanks a lot for the community !
TTYL.
Mapa.
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

15 Mar 2017, 13:48

Thank you, I'm pretty happy with the version we have now too.

I'm sure we'll eventually find something it does wrong though.

*EDIT*
I couldn't help myself, this isn't finding anything new, but I don't think it stops finding anything, and it is more efficient. I'm not sure it matters cause it always seems to load the list pretty fast, but hey it makes it much easier RegEx to read.

Code: Select all

			<parser id="ahk_function" displayName="AHK" commentExpr="((/\*.*?\*)/|((?<=[\s\t]);.*?$))">
				<!-- AutoHotKey Function List -->
				<classRange
					mainExpr="^[\t ]*(class|struct)[\t ]+[\w]+([\t ]+|[\t ]+(extends)[\s]+(\,[\t ]*|(\\|[\w][\w]*))+[\s]*)?([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{"
					openSymbole = "\{"
					closeSymbole = "\}"
					displayMode="node">
					<className>
						<nameExpr expr="(class|struct)[\t ]+[\w]+"/>
						<nameExpr expr="[\t ]+[\w]+"/>
						<nameExpr expr="[\w]+"/>
					</className>
					<function
						mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?">
						<functionName>
							<funcNameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
						</functionName>
					</function>
				</classRange>
				<function
					mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?"
					displayMode="$className->$functionName">
					<functionName>
						<nameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
					</functionName>
				</function>
			</parser>
Note I turned this:

Code: Select all

^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t]+?;[^\r\n]*?([\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))+?[\s\t]*\{|([\s\t\r\n]|((/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$)))*?[\s\t]*\{)
Into:

Code: Select all

^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{
My next thoughts on optimizing are figuring out what we should include as valid function names, right now #!^+&<>*~$ are also working in a function name, although they are valid in a HotKey they aren't really for functions or labels right? Anyway now I'm just nit picking, I will get to optimizing further.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

17 Mar 2017, 01:04

Superb work! :bravo:

What would very nice and useful to have:
Display class properties (see https://autohotkey.com/docs/Objects.htm - Section Classes) within function list
User avatar
mapa4
Posts: 13
Joined: 14 Nov 2013, 02:55

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

17 Mar 2017, 06:17

Hi Nightwolf85, I was not able to answer your last PM in this forum, my response still stays in the Outbox, I will retry later. Thanks.
Mapa.
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

17 Mar 2017, 21:04

For class properties, is the only real difference that they use a square bracket instead of regular parenthesis? If so then this should work, but please note I haven't extensively tested this to make sure it doesn't break any other matches ( But it really shouldn't )

Code: Select all

			<parser id="ahk_function" displayName="AHK" commentExpr="((/\*.*?\*)/|((?<=[\s\t]);.*?$))">
				<!-- AutoHotKey Function List -->
				<classRange
					mainExpr="^[\t ]*(class|struct)[\t ]+[\w]+([\t ]+|[\t ]+(extends)[\s]+(\,[\t ]*|(\\|[\w][\w]*))+[\s]*)?([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{"
					openSymbole = "\{"
					closeSymbole = "\}"
					displayMode="node">
					<className>
						<nameExpr expr="(class|struct)[\t ]+[\w]+"/>
						<nameExpr expr="[\t ]+[\w]+"/>
						<nameExpr expr="[\w]+"/>
					</className>
					<function
						mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*(\(|\[)[\w+:=\d\s,"#.;]*(\)|\])([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?">
						<functionName>
							<funcNameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*(\(|\[)[\w+:=\d\s,"#.;]*(\)|\])|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
						</functionName>
					</function>
				</classRange>
				<function
					mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?"
					displayMode="$className->$functionName">
					<functionName>
						<nameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
					</functionName>
				</function>
			</parser>
Note another thing I don't think I have a hope of getting to work right now is Nested classes, it just doesn't seem possible with the current functionality.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

17 Mar 2017, 21:17

I cant seem to get any of these to be recognized when placed into my functionlist.xml file in AppData :(
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

17 Mar 2017, 21:28

That is odd, did you make sure to follow the steps in the OP to enable the function list parser for AHK, I don't repost those steps, just my version of the parser itself.
2. In <associationMap> field add these lines:

Code: Select all

 <association ext=".ahk" id="ahk_function"/>
 <association userDefinedLangName="Name" id="ahk_function"/>
Where Name should be the exact name you have defined as the AHK Language in
Language menu. This is, in most cases, a user defined Language.
Make sure to change where it says "Name" as described.

If all of that is right, then make sure you paste the parser in completely, and don't have any strange typo errors, like an extra < or >

Here is my entire FunctionList.xml file contents if you'd like, just make sure that AHK language name is called "AutoHotkey" or change that line in Functionlist to be an Exact match to what you have it called.
http://pastebin.com/YvdH8n3R
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

18 Mar 2017, 08:46

I replaced my functionlist.xml file with yours from the pastebin, renamed the association as my language is called 'AHK', saved and restarted notepad++. Still doesn't work.

Here is a screenshot of my user defined language.

Image

EDIT:

Turns out that because I have it setup to store my settings in Dropbox, that it kept storing the functionList.xml from the installation directory and then reading that in at load time. So I manually put the updated file in my dropbox directory, restarted NP++, and it worked! Thanks :)
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

18 Mar 2017, 11:25

Ah, yeah that is a unique setup from mine, glad you got it sorted out.
ludamo
Posts: 44
Joined: 25 Mar 2015, 02:21

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

19 Mar 2017, 03:17

Many thanks to you guys for extending the usefulness of the Function List. I had given up on classes until I tried your code. I am posting my AHK code as I think it may take things a little bit further i.e. in-line comments in the RegEx which make it easier to debug and also a pseudo-class of the #If... block directives (each block encased in {}), which I use quite a bit of in my scripts.
Also because testing requires a restart of Notepad++ each edit, I went looking for an easier way to do this, and I have mimicked the restart that happens after [un]installing a plugin. Click on Notepad++ menu Run > Run... and enter the following:
"C:\Program Files (x86)\Notepad++\updater\gpup.exe" -w "Notepad++" -e "C:\Program Files (x86)\Notepad++\notepad++.exe"
Save it with a Hotkey e.g. F12 then each press of F12 should close and restart Notepad++. Maybe there are other ways?

Code: Select all

<!-- \x08 = backspace; \x09 = \t = tab; \x7B = \{ = left curly bracket; \x26 = ampersand; \x34=quote=" -->
<parser id="ahk_function" displayName="AHK source" 
commentExpr="(?x)										# RegEx inline comments (need to escape '\ ' and '\#' except in [ #])
			(?s:\x2F\x2A.*?\x2A\x2F)					# multi-line comment \x2F='/', \x2A='*', \x3B=';'
		|	(?:^;[\s\w]{1,})							# single line comment
			">
		<!-- AutoHotKey Function List -->
	<classRange
		mainExpr="(?x)
		^(class											# name of class or pseudoclass
	|	struct
	|	\#If.*?,?)										# {} In AHK seems to work with #IfWin block directives
		([^\x08]*?\{)									# rest of line(s) including in-line comment up to {. \x08 = backspace
		"
		openSymbole = "\{"
		closeSymbole = "(?x)							#
						\}								# in AHK code the final } in a file needs to be followed by a CR LF
						"
		displayMode="node">
		<className>
			<nameExpr expr="(class|struct|\#If)([^\x08\t;\n]*)"/>
		</className>
		<function
		mainExpr="(?x)
		^(\t?\w+\(.*?\)									# Functions - inside a class must be preceeded by 1 Tab to show
	|	\w+\ \x26\ \w+::								# Custom Combination Hotkeys - \x26 is ampersand
	|	[^;\t\s\n]+:[:\*]?)								# Labels, Hotkeys or Hotstrings
		([^\n]*)$										# rest of line including in-line comment	
	">
			<functionName>
				<funcNameExpr expr="[^\t;\{]{1,32}"/>
			</functionName>
		</function>
	</classRange>
	<function
		mainExpr="(?x)
		^([\w\d]+\(.*?\)								# Functions
	|	[^;\t\s\n]+:[:\*]?								# Labels, Hotkeys or Hotstrings
	|	\w+\ \x26\ \w+::)								# Custom Combination Hotkeys - \x26 is ampersand
		([^\n]*$)										# rest of line
	"
		displayMode="$className->$functionName">
		<functionName>
			<nameExpr expr="[^\t;\{]{1,32}"/>
		</functionName>
	</function>
</parser>			
To simplify things in my code I have most functions / hotkeys etc left justified. One thing I found was that a 'non-class' hotkey inside a multi-line comment still shows up in function list whereas if a function is in a multi-line comment is inside a class then it seems to work as expected. In this case I just add a space or single line comment to remove these from showing up in the Function List Panel.
User avatar
mapa4
Posts: 13
Joined: 14 Nov 2013, 02:55

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

19 Mar 2017, 04:28

Hi Ludamo,

Unfortunately, it does not cover the initial requirement.
Nightwolf85 spent a lot of time on this and resolved a lot of cases, this is not the same behavior, it really detects quite all syntax types used by any fellow.
Mapa.
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

19 Mar 2017, 06:24

ludamo,
My main goal was for my parser to pull out functions, hotkeys, and labels. However, I didn't want it to just work for code that I write, but for any code that I get from others online.

If your solution works for you that is great, but it places too many formatting restrictions on the code for it to be useful for me. As an example, I might have functions in a class that use 4 spaces instead of a tab, your version wouldn't find them. It also finds too many things that aren't functions, labels, or hotkeys as mapa4 mentioned.

I do like the idea of the Regex having comments so it is easier to read, and I may do that for my version of the parser if I get to it. And I can see a benefit to having directives show up as classes if brackets are used after them. Thank you for sharing.


EDIT**

While I'm here I might as well post the latest version I have, which includes a couple new fixes for parameter names to include param* and `n

Code: Select all

			<parser id="ahk_function" displayName="AHK" commentExpr="((/\*.*?\*)/|((?<=[\s\t]);.*?$))">
				<!-- AutoHotKey Function List -->
				<classRange
					mainExpr="^[\t ]*(class|struct)[\t ]+[\w]+([\t ]+|[\t ]+(extends)[\s]+(\,[\t ]*|(\\|[\w][\w]*))+[\s]*)?([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{"
					openSymbole = "\{"
					closeSymbole = "\}"
					displayMode="node">
					<className>
						<nameExpr expr="(class|struct)[\t ]+[\w]+"/>
						<nameExpr expr="[\t ]+[\w]+"/>
						<nameExpr expr="[\w]+"/>
					</className>
					<function
						mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*(\(|\[)[\w+:=\d\s,"#.;*`]*(\)|\])([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?">
						<functionName>
							<funcNameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*(\(|\[)[\w+:=\d\s,"#.;*`]*(\)|\])|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
						</functionName>
					</function>
				</classRange>
				<function
					mainExpr="^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;*`]*\)([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))|^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?"
					displayMode="$className->$functionName">
					<functionName>
						<nameExpr expr="([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;*`]*\)|([a-zA-Z0-9#!^+&<>*~$_: ])+\d*::?"/>
					</functionName>
				</function>
			</parser>
ludamo
Posts: 44
Joined: 25 Mar 2015, 02:21

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

19 Mar 2017, 18:27

Thanks mapa4 and Nightwolf85 for responding and interacting. I appreciate what you say. I guess posting my code may have been misleading, I think I was thinking of it more as just an example of what might be done to make it easier to modify the code for one's personal requirements. I had thought of trying to format your code with the in line comments to help me understand the RegEx better but I think is is beyond my capabilities with RegEx! My eyes / mind tend to get lost in the string of symbols! Your requirement for it to work for any code is obviously a better idea.
Nightwolf85
Posts: 302
Joined: 05 Feb 2017, 00:03

Re: Enable Function List in Notepad++ for AHK Scripts (with classes now)

19 Mar 2017, 20:07

That makes sense, and I appreciate the feedback and clarification.

I'll work on putting in the comments so it is easier for other people to understand, and modify. To start this isn't a complete parser, but this is the big RegEx string split into Function, Label, and Hotkey parts. It isn't everything broken down, but should help understand a little.

Code: Select all

^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*\([\w+:=\d\s,"#.;*`]*\)([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{    -- Function RegEx (Not in a class)
^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*(\(|\[)[\w+:=\d\s,"#.;*`]*(\)|\])([\s\t\r\n]|(/\*.*?\*)/|((?<=[\s\t]);[^\r\n]*?$))*?[\s\t]*\{    -- Function RegEx (In classes since it allows [] as well as () to allow parameters to match)
^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_])+\d*:(?=([\s\t]*[\r\n]|[\s\t]+;.*[\r\n]))    -- Label Regex
^[\t ]*(?!(if\(|while\(|for\())([a-zA-Z0-9#!^+&<>*~$_: ])+\d*(?<![ ])::(?=[^\r\n\t\s])?    -- Hotkey Regex
I then just put a | between each and use that in the parser.

To test it in Notepadd++ Search make sure to change the " to a " and the < to a <

and that is basically how I build and test each change.

Return to “Notepad++”

Who is online

Users browsing this forum: No registered users and 8 guests