FunctionList Confused
-
@lycan-thrope said in FunctionList Confused:
This lack of class showing without functions, however, kind of hurts the purpose of my goal which was to use the FunctionList panel as a navigational tool,
If a class will always have at least one of “with” and “function”, then change the
function
inside theclassRange
to:<function mainExpr="(?x-s) \h* (?: function \h+ \w+ | with \h+ \(.*?\) ) \h* " > <functionName> <funcNameExpr expr="(?x-s) # multiline/comments \h* # allow leading spaces (?: function # must have word 'function' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'function' in the name of the function in the panel \w+ # the name of the function is the first whole word after 'function' | with # must have word 'with' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'with' in the name of the function in the panel \( # start paren .*? # 'this' or equivalent \) # end paren ) " /> </functionName> </function>
It will then give the “argument” to
with
as a function name as well…
It might not be exactly what you want, but it comes close. -
@peterjones
You’re a genius. :-)Every class does indeed, as far as I know, have to have a
this
andwith endwith
construct that sets the properties of the object it will create, unless it is only copying and giving a different name to a default superclass.I was going to ask and point out that I thought the C++ mixed parser that MAPJe71 shows in the FAQ, would work because it shows a function being declared inside the class construct, but actually being defined outside.
dBASE has a similar thing where it is assigned as a property
onOpen = class::objectsname_onOpen
and then is later either actually defined in the class definition, or externally defined (if that’s possible). I know we define helper functions outside of the class constructor that are either defined in the same file, or an external file that will be named as needed or prior to the start of the form or function it’s being called in. Like I said, it’s kind of loosely typed and ambiguous, but it works :)I tried my earlier suggestion of putting a null function in each class and took a screenshot of it.
Simple search and replace on endclass and adding the fake function made it work, but I kind of like yours better, maybe using the
this
orwith
words will work better. Thanks for this.Lee
-
@peterjones
Incidentally, Peter.While trying to copy this over, I hadn’t read that I should put this in the classrange/function body, and had put it in the funtion body outside. No biggie right. I took the copy from the upper post, took this and copied it into the right section, then set about to remove my fake function from the .cc file using the search terms and switching them between search and replace boxes. After going through the list, which I thought for sure, I had bypassed the only class with a real function I saved and ran the program, only to find that I had replaced the real function.
Argh…panic set in. Oh wait…I have a .bak file of the original saved one. I recopied it and then tested the functionlist again and viola. See how disparate threads lead to one point? :-) Saved from myself, again. :-)
Anyway, thanks for this. I think you have made it very possible for this package to be a nice Christmas present for the dBASEPlus community that has been longing for an external editor with the basic features of the IDE editor with some of the more advanced tools available in Notepad++ of which many were users, but didn’t have highlighting which NPP now makes it possible for use to combine the use. Now our folks, as one user put it, be able to edit the file externally, and run it right away without having to close the editor just to compile the program. Of course, thanks to the default .bak choice, it will not function like our environment to save us from it and ourselves. :-)
Lee
-
Hi, @lycan-thrope, @peterjones and All,
As you can see, there are different ways to get an element, whatever it is, listed, in the
Function List
panel !!I’ll explain what my process was, for writing my previous post and how I tested my regex solution !
First, from the initial list of the
9
class syntaxes, provided by @lycan-thrope, below :class TruckNotebookForm of TBASE from :Truck:Truckbase.cfm class PlainObjectListForm of FORM class FrameCtrl(frameObj) of dBCWndCtrl custom class dBCWndCtrl class FrameAppCtrl of FrameCtrl custom class ToolButtonFx(oParent) of Toolbutton(oParent) custom class MenuFx(oParent,cName) class dContainersForm of DFORM from "dForm.cfm" class LGCENTRYFIELD(parentObj, name) of ENTRYFIELD(parentObj, name) custom
I decided to search, first, for a regex solution, only, without any reference to the
Function List
mechanism ! In addition, I considered only the line of theclass
definition ! After modifications, I ended up with the followingMainExpr
regex :(?x-i) # Free-spacing mode and inline comments + search ensitive to case ^\h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \w+ # Class name ( # Beginning of the optional parameter(s) part \h? \( # Opening parenthesis \w+ # First and required parameter ( , \h? \w+)* # Following optional/additional parameters \) # Closing parenthesis )? # End of the optional parameter(s) part (?: # Beginning of the main optional part \h of \h # Optional 'of' keyword, surrounded by 1 horizontal whitespace char \w+ # Superclass name (?1)? # Optional parameter(s) part ( \h custom )? # Optional 'custom' keyword (?: # Beginning of the optional part \h from \h # Optional 'from' keyword, surrounded by 1 horizontal whitespace char ( : \w+ : \w+ \. \w+ # First pointing file case | # OR \x22 \w+ \. \w+ \x22 # Second pointing file case ) )? # End of the optional part )? # End of the main optional part and end of the class declaration
If you select all the text between
(?x-i)
and the last comment..... and end of the class declaration
( so a selection of1,607
chars, which is under the maximum of2,046
chars ) and open the Find dialog (Ctrl + F
), you’ll verify that it correctly matches the9
syntaxes, provided by @lycan-thrope !Of course I, tested my regex solution and was upset to notice that it would also match wrong pieces of code :-((
For instance, after taking the last syntax and adding a
#
char in some places, it would wrongly match some part of the two lines, below :class LGCENTRYFIELD(parentObj, name) of ENTRYFIELD(parentObj, #name) custom class LGCENTRYFIELD(parentObj#, name) of ENTRYFIELD(parentObj, name) custom
As you can see, as soon as a part contains a non-allowed char (
#
), my regex skips it and just matches the minimum valid form :-( I finally solved this problem by adding, at the end of my regex, the$
symbol which forces the regex engine to get valid syntaxes on a complete line !So, the right multi-lines regex, for the
mainExpr
attribute, is rather :(?x-i) # Free-spacing mode and inline comments + search ensitive to case ^\h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \w+ # Class name ( # Beginning of the optional parameter(s) part \h? \( # Opening parenthesis \w+ # First and required parameter ( , \h? \w+)* # Following optional/additional parameters \) # Closing parenthesis )? # End of the optional parameter(s) part (?: # Beginning of the main optional part \h of \h # Optional 'of' keyword, surrounded by 1 horizontal whitespace char \w+ # Superclass name (?1)? # Optional parameter(s) part ( \h custom )? # Optional 'custom' keyword (?: # Beginning of the optional part \h from \h # Optional 'from' keyword, surrounded by 1 horizontal whitespace char ( : \w+ : \w+ \. \w+ # First pointing file case | # OR \x22 \w+ \. \w+ \x22 # Second pointing file case ) )? # End of the optional part )? # End of the main optional part $ # End of current line and end of the class declaration
And you’ll notice, this time, that the last
2
syntaxes, below, are not matched, as expected :class TruckNotebookForm of TBASE from :Truck:Truckbase.cfm class PlainObjectListForm of FORM class FrameCtrl(frameObj) of dBCWndCtrl custom class dBCWndCtrl class FrameAppCtrl of FrameCtrl custom class ToolButtonFx(oParent) of Toolbutton(oParent) custom class MenuFx(oParent,cName) class dContainersForm of DFORM from "dForm.cfm" class LGCENTRYFIELD(parentObj, name) of ENTRYFIELD(parentObj, name) custom class LGCENTRYFIELD(parentObj, name) of ENTRYFIELD(parentObj, #name) custom class LGCENTRYFIELD(parentObj#, name) of ENTRYFIELD(parentObj, name) custom
However, this second version still considers the current
class
definition line as the only domain to study, without any further stuff and/or anyendclass
statement !
In a second time, I tried to test this final regex version with the
Function List
feature. So, in theoverrideMap.xml
file, I added the line :<association id= "dBasePlus.xml" langID= "0"/> <!-- Normal Text ID -->
Then, I used the general template, provided by @lycan-thrope, to build a correct
dBasePlus.xml
file. But, NO chance, I was unable to get the list of classes, in theFunction List
panel :-(( I suppose that relation between classes and functions, in amix
orclass parser
, must be of importance ! But after numerous tries, I gave up, as I’m rather not acquainted with modern structured languages :-(But, as I’m rather stubborn, I decided to simplify the problem by using a simple
function parser
. Of course, in this case, the “elements”, detected by theFile List
mechanism, are seen as functions but, actually, may represent any element that we need to be listed. For instance, presently, thedBasePlus
classes !From this old page, caught by the
wayBack Machine
site :https://web.archive.org/web/20190826024431/https://notepad-plus-plus.org/features/function-list.html
I used this minimal form of a
function parser
( Can’t do more simple ! ) :<NotepadPlus> <functionList> <parser id ="xxxxx" commentExpr="yyyyy" > <function mainExpr="zzzzz" <functionName> <nameExpr expr="wwwww" /> </functionName> </function> </parser> </functionList> </NotepadPlus>
Giving the functional
dBasePlus.xml
file, below :<?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> <!-- ========================================================= [ dBASEPlus ] --> <parser id ="dBasePlus" commentExpr="(/\*.*?\*/)|(?-s://.*)" > <function mainExpr="(?x-i) # Free-spacing mode and inline comments + search ensitive to case ^\h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \w+ # Class name # Following the class name there is the option of parameters, and if so the first entry inside the parens is required, whether there is other # parameters or not, once the parens go up, the first is required. ie: class FrameCtrl(frameObj) ( # Beginning of the optional parameter(s) part \h? \( # Opening parenthesis \w+ # First and required parameter ( , \h? \w+)* # Following optional/additional parameters \) # Closing parenthesis )? # End of the optional parameter(s) part # For the rest of the class declaration, after the class name, all other options are part of one big optional set, that follows 'of' # and can be populated by one of several options. (?: # Beginning of the main optional part # The first and most prevalent is the Superclass name that the class is being subclassed from, and it's options of parameters and again, # if it has parameters, at least the first one is required ie.: class class ToolButtonFx(oParent) of Toolbutton(oParent) \h of \h # Optional 'of' keyword, surrounded by 1 horizontal whitespace char \w+ # Superclass name (?1)? # Optional parameter(s) part # The next possible option is that it is a custom object and needs to be in this line so if the object or form is opened up in the dBASE IDE, # the designers in it won't mess up the object by streaming out missing parts or overriding properties or objects and functions. ( \h custom )? # Optional 'custom' keyword # The next possible option is that the class is being subclassed from another object that is contained elsewhere and the compiler needs to know # this reference. There are two options for pointing to the file. The first is an Alias path in the IDE that can be accessed by the compiler # in the environment, or second, it is in the current directory and only the name is needed...or it has a path that can be listed here, # but this is bad practice, and an Alias is recommended if the file is in a place other than the current directory. If it is, the name can be # used in quotes as a string that gets passed to the compiler. Both follow the word 'From'. The Alias directory is a name that is enclosed # in two colons, one immediately before the Alias name and one immediately after, no spaces. (?: # Beginning of the optional part \h from \h # Optional 'from' keyword, surrounded by 1 horizontal whitespace char ( : \w+ : \w+ \. \w+ # First pointing file case | # OR \x22 \w+ \. \w+ \x22 # Second pointing file case ) )? # End of the optional part )? # End of the main optional part $ # End of current line and end of the class declaration " > <functionName> <nameExpr expr="(?x) # Free-spacing mode and inline comments \h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \K\w+ # Class name " /> </functionName> </function> </parser> </functionList> </NotepadPlus>
You may test it, by pasting, in a new tab, the text, below, with the
normal text
language :class TruckNotebookForm of TBASE from :Truck:Truckbase.cfm class PlainObjectListForm of FORM class FrameCtrl(frameObj) of dBCWndCtrl custom class dBCWndCtrl class FrameAppCtrl of FrameCtrl custom class ToolButtonFx(oParent) of Toolbutton(oParent) custom class MenuFx(oParent,cName) class dContainersForm of DFORM from "dForm.cfm" class LGCENTRYFIELD(parentObj, name) of ENTRYFIELD(parentObj, name) custom
Best Regards
guy038
-
@guy038 , your efforts are appreciated, like I said, if only to show I could have been less verbose.
Originally, I was trying to decipher the C++ FunctionList structure, but was getting dizzy trying to figure it out since it’s not my native language, so regex aside, some of the structures it was trying to capture was dizzying. Hence I tried shifting to the Java FunctionList to study, and it helped show I didn’t need the organized chaos that C++ was. :-)
It still, however, seemed to me to be trying to parse a single line to of possible options for the lines, so I began my journey trying to just regex the options of that one line. My hope was to be able to just get that recognized and just show the class name. I still don’t completely understand the workings of FunctionList, but even though Peter and you both seemed to help solve the problem, I’m happy, but still playing just to advance my knowledge of this and see if I can’t enhance or improve things.
If nothing else, this little experiment has kind of turned me on to regex, which I’ve never needed or used until now to make this. I’ve done my own little parsers, but in C or dBASE, simple little things, but dealing with the regex that had to be put inside the xml and figure everything out was …let’s just say kind of overwhelming, but educational. So thanks for that.
I find trying to regex new lines and such in the Find search of NPP doen’t work for me trying to get down to the “endclass” part and was frustrating as hell trying to make it work, using what seemed like the proper way, using the ‘class’ and ‘endclass’ keywords in the open and close symbole seemed like a simple answer…but it wasn’t…so, here we are :-) I’ve shown screenshots to the community and they’re salivating for it. Anyway, this is a work of love so thanks again. I do understand the stubborn part. I’ve been banging the head and neglecting my house chores trying to crack this, which is why I finally relented and reached out…and grateful that I did.
Happy Holidays while I try and tie this package up for delivery. :-)
Lee
-
Hello @lycan-thrope, @peterjones and All,
Well, today is an other day ! So, let’s go on studying some more structures !
Let’s suppose, as previously mentioned, that you need the general
class
syntax, below, that you’ll paste in a new tab :class Test_1 bla blah with (this) bla bla blah endwith blah bla bla endclass classTest_2 bla blah with (this) bla bla blah endwith blah bla bla endclass
So, after a simple
class
definition line, you would need :-
Further on, a line with the
with
keyword and its parameter(xxxxx)
, after possiblewhitespace
chars -
Further on, a line with the
endwith
keyword, after possiblewhitespace
chars -
At last, a line with the
endclass
keyword, after possiblewhitespace
chars
Then, each entire
class •••••••••• endclass
section, which meets all the rules, could be matched with the multi-lines regex, below :(?sx-i) # We MUUST add the '(?s)' in-line modifier as we search for a MULTI-LINE range of chars ^ \h* # Optional leading whitespace chars, beginning a line class # Mandatory 'class' keyword \h? # Optional whitepace char \w+ # Class name $ # End of current line ((?!endclass).)*? # The SMALLEST range of characters, even NULL, NOT CONTAINING the 'endclass' keyword, till ... ^ \h* # Optional leading whitespace chars, beginning a line with # Mandatory 'with' keyword \h # Mandatory whitepace char \( \w+ \) # Mandatory parameter name, between parentheses $ # End of current line ((?!endclass).)*? # The SMALLEST range of characters, even NULL, NOT CONTAINING the 'endclass' keyword, till ... ^ \h* # Optional leading whitespace chars, beginning a line endwith # Mandatory 'endwith' keyword $ # End of current line ((?!endclass).)*? # The SMALLEST range of characters, even NULL, NOT CONTAINING the 'endclass' keyword, till ... ^ \h* # Optional leading whitespace chars, beginning a line endclass # Mandatory 'endclass' keyword $ # End of current line
Note that, in order to get the smallest range of chars between two lines of importance, as
with
,endwith
orendclass
, we have to use the regex syntax((?!endclass).)*?
and not the simple regex.*?
. Why ? Just because it must not match a greater rangeclass ••••• endclass ••••••••••••••• class ••••• endclass
, in the case where an innerclass
section does not satisfy the regex rules ! Thus, the keywordendclass
must not be present at any position of the range !Now,
-
Select from
(?xs-i)
to the last# End of current line
-
Open the Find dialog (
Ctrl + F
) -
Test it, against the above text : it should select any block of lines, between the
class
andendclass
lines !
Finally, if we insert this additional regex part, in the
dBasePlus.xml
file, we obtain :<?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> <!-- ========================================================= [ dBASEPlus ] --> <parser id ="dBasePlus" commentExpr="(/\*.*?\*/)|(?-s://.*)" > <function mainExpr="(?x-i) # Free-spacing mode and inline comments + search ensitive to case ^\h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \w+ # Class name # Following the class name there is the option of parameters, and if so the first entry inside the parens is required, whether there is other # parameters or not, once the parens go up, the first is required. ie: class FrameCtrl(frameObj) ( # Beginning of the optional parameter(s) part \h? \( # Opening parenthesis \w+ # First and required parameter ( , \h? \w+)* # Following optional/additional parameters \) # Closing parenthesis )? # End of the optional parameter(s) part # For the rest of the class declaration, after the class name, all other options are part of one big optional set, that follows 'of' # and can be populated by one of several options. (?: # Beginning of the main optional part # The first and most prevalent is the Superclass name that the class is being subclassed from, and it's options of parameters and again, # if it has parameters, at least the first one is required ie.: class class ToolButtonFx(oParent) of Toolbutton(oParent) \h of \h # Optional 'of' keyword, surrounded by 1 horizontal whitespace char \w+ # Superclass name (?1)? # Optional parameter(s) part # The next possible option is that it is a custom object and needs to be in this line so if the object or form is opened up in the dBASE IDE, # the designers in it won't mess up the object by streaming out missing parts or overriding properties or objects and functions. ( \h custom )? # Optional 'custom' keyword # The next possible option is that the class is being subclassed from another object that is contained elsewhere and the compiler needs to know # this reference. There are two options for pointing to the file. The first is an Alias path in the IDE that can be accessed by the compiler # in the environment, or second, it is in the current directory and only the name is needed...or it has a path that can be listed here, # but this is bad practice, and an Alias is recommended if the file is in a place other than the current directory. If it is, the name can be # used in quotes as a string that gets passed to the compiler. Both follow the word 'From'. The Alias directory is a name that is enclosed # in two colons, one immediately before the Alias name and one immediately after, no spaces. (?: # Beginning of the optional part \h from \h # Optional 'from' keyword, surrounded by 1 horizontal whitespace char ( : \w+ : \w+ \. \w+ # First pointing file case | # OR \x22 \w+ \. \w+ \x22 # Second pointing file case ) )? # End of the optional part )? # End of the main optional part $ # End of current line and end of the class declaration ((?!endclass).)*? # The SMALLEST range of characters, even NULL, NOT CONTAINING the 'endclass' keyword, till ... ^ \h* # Optional leading whitespace chars, beginning a line with # Mandatory 'with' keyword \h # Mandatory whitepace char \( \w+ \) # Mandatory parameter name, between parentheses $ # End of current line ((?!endclass).)*? # The SMALLEST range of characters, even NULL, NOT CONTAINING the 'endclass' keyword, till ... ^ \h* # Optional leading whitespace chars, beginning a line endwith # Mandatory 'endwith' keyword $ # End of current line ((?!endclass).)*? # The SMALLEST range of characters, even NULL, NOT CONTAINING the 'endclass' keyword, till ... ^ \h* # Optional leading whitespace chars, beginning a line endclass # Mandatory 'endclass' keyword $ # End of current line " > <functionName> <nameExpr expr="(?x) # Free-spacing mode and inline comments \h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \K\w+ # Class name " /> </functionName> </function> </parser> </functionList> </NotepadPlus>
Note that, in the
Function List
parser, we do not have to add the(?s)
modifier. This is enabled by default, meaning that the dot regex symbol.
matches absolutely any character of theBMP
Unicode plane !Best Regards,
guy038
-
-
@guy038 ,
That made sense, and I can use that to play with, because it did what I was trying to, although, so far, Peter’s and your contribution to it works great.
I was curious, however if I play with it further, and maybe Peter can also verify or deny, if I can get NPP to make it’s display look more like the dBASEPlus editor’s if I work more at the regex in the parser. Not so much the graphics, as just the way it breaks down the class, objects and functions etc. If not, believe me, what you guys did is fine…I’m just curious if it’s possible or not. Screenshots of both on Identical file.
dBASEPlus:
Notepad++:
Yeah or nay? :-)
Lee
-
@lycan-thrope
Maybe with the regex I can change the names to drop the ‘this.’ and burrow down to the name of the object itself I guess is what I would mean. I’m going to play with it anyway, I just don’t want to break it. :-)Lee
-
@lycan-thrope
As a note, Peter, thanks for that code. I had forgotten an older but not obsolete alternative tofunction
in the dBASE language, namelyprocedure
that is essentially the same as a function’s syntax. It used to be used pre OOP days, and dBASE used to differentiate them, but that disappeared when it went OOP, but it was never removed and maintained to be compatible because the OOP version is still able to run older procedural code and it’s still recognized.I was able to figure out how to add that in the OR that you had setup, and the first time I ran it, it showed that it was highlighting a different aspect of dBASE, where you can
set procedure to
a file that has external code and it highlighted the wordto
and included it in the FunctionList panel, so I was able after learning from guy038 the different way to write regex to (!to) and successfully run it without error. Learning a lot from you guys. :-)Just feeling good about that…not as good as you guys yet ;), but working on it.
Lee
-
-
@lycan-thrope
Hey Folks,I found a bit of a problem. I searched the forums to see if there was a previous issue with FunctionList words being found inside comments, and I think even Peter made a comment in it that it still had a bug that required to spaces or some such to keep it from listing in the FunctionList.
So, I double checked and the following screenshots show my problem with apparently any time a keyword (function, procedure, with/endwith) shows up in any comment. I know I didn’t regex the (&& comment characters) but it doesn’t seem to make any difference as it shows in this screenshot:
I also checked to make sure the comments were being considered by rechecking the FunctionList regex for the comments symbols (// and /* */) and they were as the screenshot shows, these are standard comment symbols that are supposed to be ignored:
I also tried to change the regex in the search to not include comment symbols from the start of the line search, by using a similar regex like I used to exclude “to”.
(! // | && | *)
All this did was stop even the legitimate finding of functions from working altogether.
So I guess the question is, has this bug been fixed, or is there some way I can exclude these Functions from being found inside comments and listed?
Thanks in advance for any help and wishing all a Happy New Year during these holidays,
Lee
-
@lycan-thrope
OOps forgot the second screenshot showing the regex for the standard comments here:
Thanks , again,
Lee
-
Hi, @lycan-thrope,
Be patient
4/6
hours. I’ll have a look into your problem. I think I’ve got a work-aroud to solve the detection of the wordFunction
in comments !Best Regards,
guy038
-
@guy038 ,
Thanks. Patience, fortunately or unfortunately, is one of my virtues. :-)
I have to get back to work documenting our common methods for the hints as well as our ADO components.
Thanks,
Lee
-
My first, with no proper comment defined, shows functions found in both comments and non-c omments:
My second attempt, just adding in the
//
comment expression does not show the functions from the comments:Now add in the
/*...*/
-style comments to the UDL, but not to the functionList (though I did update to put the//
inside the modified group), and restart:
As expected, it shows
/* function othercomment */
asfunction othercomment
in the functionList. Now edit the comment regex to include an alternate comment definition and restartIt works exactly as I would expect. FunctionList shows
real
,second
,real
,nextwillbecommentedtoo
, andlast
, without showing any ofin comment
,hidden
,commented
,othercomment
, ordontlistme
.As I have done in all the times I have given suggestions in your various forays into UDL, FunctionList, and AutoComplete – though I may not have said it explicitly enough – I always work incrementally in these: start with something that is working, then modify it to try one small thing new, and then either debug until it works or move forward to the next step if it does work. For you to make progress, you are going to have to do the same thing.
<?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> <parser displayName="LycanThropeWFM" id ="lycanthropewfm_function" commentExpr="(?s:/\*.*?\*/)|(?xm-s://.*$)" > <function mainExpr="(?x) # Utilize inline comments (see `RegEx - Pattern Modifiers`) (function|procedure) # works with functions or procedures \s+ [A-Za-z_]\w* " > <functionName> <nameExpr expr=".*" /> </functionName> </function> </parser> </functionList> </NotepadPlus>
Oh, sorry, I just saw that you have added
&&
as a new comment. I will assume those are single-line comments as well, like//
. So i used(?s:/\*.*?\*/)|(?xm-s:(//|\&\&).*$)
in Notepad++ search first, and verified it also found&& procedure ampersand
in addition to the other comment lines. So then I change the commentExpr and save and restart Notepad++:Once again, it works exactly as I would expect. I also removed the
\
before the&
, because that’s only special in the subsitution/replacement, not in the search, and it still works.Oh, you also don’t have the x in the modifier list. But when I remove it, it still works right:
<?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> <parser displayName="LycanThropeWFM" id ="lycanthropewfm_function" commentExpr="(?s:/\*.*?\*/)|(?m-s:(//|&&).*$)" > <function mainExpr="(?x) # Utilize inline comments (see `RegEx - Pattern Modifiers`) (function|procedure) # works with functions or procedures \s+ [A-Za-z_]\w* " > <functionName> <nameExpr expr=".*" /> </functionName> </function> </parser> </functionList> </NotepadPlus>
So, I cannot replicate your problem. If I am inside the parser’s
commentExpr
region, the parser will not identify the function/prcedure for me. -
Hello, @lycan-thrope,
Finally, as we all tried numerous ways to to get a functional parser, the best would be to send me, first, the last version of your
dBAsePlus.xml
file, as text, of course !If you mind a possible lack of confidentiality, here is my temporary e-mail address :
Sorry for this delay !
BR
guy038
-
I don’t know how to explain it, Peter. I pretty much left the file alone after we did our thing and then I made that one change to keep the to out that I posted above to stop
procedure to
from printing theto
. I actually need to stop anyset procedure to
from being recognized, but for the time, that was enough as long as the other stuff worked. I sent it out to some users to test for me and they reported the problems, and then I duplicated it…in that screenshot above.Prior, none of my code has those keywords in my comments, that’s why I didn’t notice it…but that’s the way it was, so I’m at a loss to explain it, but I am back to checking the regex and such.
Here’s my code:
<?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> <!-- ========================================================= [ dBASEPlus ] --> <parser displayName="dBASEPlus" id ="dbaseplus" commentExpr="(?s:/\*.*?\*/)|(?m-s://.*?$)|(?m-s:\&\&.*?$)" > <classRange mainExpr="(?x-i) # Free-spacing mode and inline comments + search sensitive to case ^\h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \w+ # Class name # Following the class name there is the option of parameters, and if so the first entry inside the parens is required, whether there is other # parameters or not, once the parens go up, the first is required. ie: class FrameCtrl(frameObj) ( # Beginning of the optional parameter(s) part ( Group 1 ) \h? \( # Opening parenthesis \w+ # First and required parameter ( , \h? \w+)* # Following optional/additional parameters \) # Closing parenthesis )? # End of the optional parameter(s) part # For the rest of the class declaration, after the class name, all other options are part of one big optional set, that follows 'of' # and can be populated by one of several options. (?: # Beginning of the main optional part, in a non-capturing group # The first and most prevalent is the Superclass name that the class is being subclassed from, and it's options of parameters and again, # if it has parameters, at least the first one is required ie.: class ToolButtonFx(oParent) of Toolbutton(oParent). \h of \h # Optional 'of' keyword, surrounded by 1 horizontal whitespace char \w+ # Superclass name (?1)? # Optional parameter(s) part ( Subroutine call to Group 1 ) # The next possible option is that it is a custom object and needs to be in this line so if the object or form is opened up in the dBASE IDE, # the designers in it won't mess up the object by streaming out missing parts or overriding properties or objects and functions. ( \h custom )? # Optional 'custom' keyword # The next possible option is that the class is being subclassed from another object that is contained elsewhere and the compiler needs to know # this reference. There are two options for pointing to the file. The first is an Alias path in the IDE that can be accessed by the compiler # in the environment, or second, it is in the current directory and only the name is needed...or it has a path that can be listed here, # but this is bad practice, and an Alias is recommended if the file is in a place other than the current directory. If it is, the name can be # used in quotes as a string that gets passed to the compiler. Both follow the word 'From'. The Alias directory is a name that is enclosed # in two colons, one immediately before the Alias name and one immediately after, no spaces. (?: # Beginning of the optional part, in a non-capturing group \h from \h # Optional 'from' keyword, surrounded by 1 horizontal whitespace char (?: # Beginning of a non-capturing group : \w+ : \w+ \. \w+ # First pointing file case | # OR \x22 \w+ \. \w+ \x22 # Second pointing file case ) # End of a non-capturing group )? # End of the optional part )? # End of the main optional part $ # End of current line and end of the class declaration (?s:.*?^\h*endclass) # must match all the way to 'endclass' " closeSymbole="endclass" > <className> <nameExpr expr="(?x-i) # Free-spacing mode and inline comments and search sensible to case \h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \K\w+ # Pure class name " /> </className> <function mainExpr="(?x-s) \h* (?: function \h+ \w+ | procedure \h+ \w+ | with \h+ \(.*?\) ) \h* " > <functionName> <funcNameExpr expr="(?x-s) # multiline/comments # (! // | && | * ) trying to keep following keywords from being included in comments \h* # allow leading spaces (?: function # must have word 'function' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'function' in the name of the function in the panel \w+ # the name of the function is the first whole word after 'function' | procedure # must have word 'procedure' as first word \h+ # must have at least one horizontal space after procedure \K # don't keep 'procedure' in the name of the function in the panel (!to)\w+ # the name of the function is the first whole word after 'procedure' - 'to' # so as to exclude any 'set procedure to' statements, needs work though. | with # must have word 'with' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'with' in the name of the function in the panel \( # start paren .*? # 'this' or equivalent \) # end paren ) " /> </functionName> </function> </classRange> <function mainExpr="(?x-s) \h* (?: function \h+ \w+ | procedure \h+ \w+ | with \h+ \(.*?\) ) \h* " > <functionName> <funcNameExpr expr="(?x-s) # multiline/comments \h* # allow leading spaces (?: function # must have word 'function' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'function' in the name of the function in the panel \w+ # the name of the function is the first whole word after 'function' | procedure \h+ \K (!to)\w+ | with # must have word 'with' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'with' in the name of the function in the panel \( # start paren .*? # 'this' or equivalent \) # end paren ) " /> </functionName> </function> </parser> </functionList> </NotepadPlus>
-
@guy038 ,
I sent the FunctionList file and an example program that I’ve been using, it’s small but if you throw comments in you may see it. I was just using a blank document to put those comments in with a .wfm extension to trigger the FunctionList.
Lee -
@lycan-thrope
Awww crap, I think I just saw the problem in this color-coded viewer on the forums. Need to check it out. :(Lee
-
@lycan-thrope
Not sure if I made it worse or not. ::sigh::
The one change I did do, which was changed thefuncNameExpr
that’s supposed to find just the functions, tonameExpr
seem to change my test set, to lose the Function/Procedure lead names, but they still show, but on the positive side, theset procedure to
in my testing program was removed and from being shown, which is a desired result. So, I may be on to something, but those words in the commentsFunction <name>
the<name>
part is still showing up, so, I guess I’ll have to play.In the code above, I noticed that my pasted code had different highlighing than it does in NPP, which triggered my finding that I had misnamed the nameExpr. Strange that it didn’t show up on the editor like it does here.
Lee
-
@lycan-thrope
Testing to see if my change fixed the highlight difference in here:<?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> <!-- ========================================================= [ dBASEPlus ] --> <parser displayName="dBASEPlus" id ="dbaseplus" commentExpr="(?s:/\*.*?\*/)|(?m-s://.*?$)|(?m-s:\&\&.*?$)" > <classRange mainExpr="(?x-i) # Free-spacing mode and inline comments + search sensitive to case ^\h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \w+ # Class name # Following the class name there is the option of parameters, and if so the first entry inside the parens is required, whether there is other # parameters or not, once the parens go up, the first is required. ie: class FrameCtrl(frameObj) ( # Beginning of the optional parameter(s) part ( Group 1 ) \h? \( # Opening parenthesis \w+ # First and required parameter ( , \h? \w+)* # Following optional/additional parameters \) # Closing parenthesis )? # End of the optional parameter(s) part # For the rest of the class declaration, after the class name, all other options are part of one big optional set, that follows 'of' # and can be populated by one of several options. (?: # Beginning of the main optional part, in a non-capturing group # The first and most prevalent is the Superclass name that the class is being subclassed from, and it's options of parameters and again, # if it has parameters, at least the first one is required ie.: class ToolButtonFx(oParent) of Toolbutton(oParent). \h of \h # Optional 'of' keyword, surrounded by 1 horizontal whitespace char \w+ # Superclass name (?1)? # Optional parameter(s) part ( Subroutine call to Group 1 ) # The next possible option is that it is a custom object and needs to be in this line so if the object or form is opened up in the dBASE IDE, # the designers in it won't mess up the object by streaming out missing parts or overriding properties or objects and functions. ( \h custom )? # Optional 'custom' keyword # The next possible option is that the class is being subclassed from another object that is contained elsewhere and the compiler needs to know # this reference. There are two options for pointing to the file. The first is an Alias path in the IDE that can be accessed by the compiler # in the environment, or second, it is in the current directory and only the name is needed...or it has a path that can be listed here, # but this is bad practice, and an Alias is recommended if the file is in a place other than the current directory. If it is, the name can be # used in quotes as a string that gets passed to the compiler. Both follow the word 'From'. The Alias directory is a name that is enclosed # in two colons, one immediately before the Alias name and one immediately after, no spaces. (?: # Beginning of the optional part, in a non-capturing group \h from \h # Optional 'from' keyword, surrounded by 1 horizontal whitespace char (?: # Beginning of a non-capturing group : \w+ : \w+ \. \w+ # First pointing file case | # OR \x22 \w+ \. \w+ \x22 # Second pointing file case ) # End of a non-capturing group )? # End of the optional part )? # End of the main optional part $ # End of current line and end of the class declaration (?s:.*?^\h*endclass) # must match all the way to 'endclass' " closeSymbole="endclass" > <className> <nameExpr expr="(?x-i) # Free-spacing mode and inline comments and search sensible to case \h* # Optional leading whitespace chars class # 'class' keyword \h? # Optional whitepace char \K\w+ # Pure class name " /> </className> <function mainExpr="(?x-s) \h* (?: function \h+ \w+ | procedure \h+ \w+ | with \h+ \(.*?\) ) \h* " > <functionName> <funcNameExpr expr="(?x-s) # multiline/comments # (! // | && | * ) trying to keep following keywords from being included in comments \h* # allow leading spaces (?: function # must have word 'function' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'function' in the name of the function in the panel \w+ # the name of the function is the first whole word after 'function' | procedure # must have word 'procedure' as first word \h+ # must have at least one horizontal space after procedure \K # don't keep 'procedure' in the name of the function in the panel (!to)\w+ # the name of the function is the first whole word after 'procedure' - 'to' # so as to exclude any 'set procedure to' statements, needs work though. | with # must have word 'with' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'with' in the name of the function in the panel \( # start paren .*? # 'this' or equivalent \) # end paren ) " /> </functionName> </function> </classRange> <function mainExpr="(?x-s) \h* (?: function \h+ \w+ | procedure \h+ \w+ | with \h+ \(.*?\) ) \h* " > <functionName> <nameExpr expr="(?x-s) # multiline/comments \h* # allow leading spaces (?: function # must have word 'function' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'function' in the name of the function in the panel \w+ # the name of the function is the first whole word after 'function' | procedure \h+ \K (!to)\w+ | with # must have word 'with' as first word \h+ # must have at least one horizontal space after function \K # don't keep 'with' in the name of the function in the panel \( # start paren .*? # 'this' or equivalent \) # end paren ) " /> </functionName> </function> </parser> </functionList> </NotepadPlus>