Function list for Caml
-
Hi guys !
I recently (yesterday) discovered function list in Notepad++.
So, I’m trying to do a parser for the Caml and OCaml languages.Here is my code :
<parser displayName="Caml" id ="caml_function" commentExpr="(\(\*+(^\*\))*\*\)))|(\x22.*\x22" > <function mainExpr="let(\s+|\s+rec\s+)[a-z_][a-zA-Z0-9_]*(\s*|\s*\(\s*([a-z_][a-zA-Z0-9_]*|)(\s*,\s*[a-z_][a-zA-Z0-9_]*)*\s*\)\s*=.+\s+in\s+" > <functionName> <nameExpr expr="[a-z_][a-zA-Z0-9_]*" /> </functionName> </function> </parser>
I don’t understand why it doesn’t work, if someone could light it up to my mind, it’d be really nice.
Thanks
-
You may want to have a look at https://github.com/notepad-plus-plus/notepad-plus-plus/pull/3393 to check against further parser definitions.
-
@MAPJe71 Is there any progress to be expected with the function lists?
-
Thanks replying !
I don’t see anything that could help me with your link.
Do you agree that to modify the function parser of a language or just implement it, you only have to change the functionList.xml file, save changes and refresh NPP, don’t you ?
If yes, then it means that my code may contain some errors 'cause it doesn’t work at all.
-
Ok, little update.
I don’t know why, but I’ve got two different files named functionList.xml, one in AppData\Roaming\Notepad++ and one in Program Files\Notepad++
So I modified both of them but still nothing appears in function list pannel when I open a OCaml source code.I’m loosing hope…
Here is a OCaml source code for anyone who wants to clearify it (tell me if there is a way to collapse it) :let read_int () = Scanf.scanf " %d" (fun x -> x) in let n = read_int() and m = read_int() in let amis = Array.init n (fun x -> pred (read_int())) and guir = Array.init n (fun x -> read_int()) in let nCadeau = ref 0 and positions = ref [] and nb = ref 0 in try while nb < do incr nb; let cadeau = ref true in try for i=pred n downto 1 do if (guir.(amis.(pred i)) > guir.(amis.(i))) then begin cadeau := false; (* Printf.printf "guir.(%d) > guir.(%d)\n" (amis.(pred i) + pos) (amis.(i) + pos); *) raise Exit; end; (* Printf.printf "guir.(%d) < guir.(%d)\n" (amis.(pred i) + pos) (amis.(i) + pos) *) (*DEBUG*) done; if (!cadeau) then begin incr nCadeau; positions := !positions @ [n]; end; with | Exit -> begin () end; for i=0 to n-2 do guir.(i) <- guir.(succ i); done; guir.(pred n) <- read_int(); done; with | Invalid_argument "end of file" -> (); Printf.printf "%d\n" (!nCadeau); List.iter (fun x -> Printf.printf "%d " x;) (!positions);
-
@Tom-Saury
and what should the function list look like? -
I suppose something like that :
- read_int
- n
- amis
- nCadeau
- cadeau
It’s what it should look like with my actual RE, it detects one function/variable per ‘let’ key word.
It’s not the ideal thing but it’s just a start. I would like it can detect ‘and’ key word which allows to define several variables with 1 ‘let’.
But first, I just want the base works to improve the code. And it doesn’t with no reason to me… -
@Tom-Saury try this parser (function definition only):
<association id= "caml_syntax" langID="41" /> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Based on: | https://notepad-plus-plus.org/community/topic/16501/function-list-for-caml \--> <parser displayName="[#5 TODO] CAML - Categorical Abstract Machine Language" id ="caml_syntax" commentExpr="(?x) # free-spacing (see `RegEx - Pattern Modifiers`) (?: # Multi Line Comment \(\*+ (?:[^*]|\*(?!\)))* \*\) ) " > <function mainExpr="(?x) # free-spacing (see `RegEx - Pattern Modifiers`) let # start-of-function indicator... \s+ # ...should be followed by at least one white-space \K # discard text matched so far [a-z_]\w* # valid character combination for identifiers \s*\( # start-of-parameters indicator (?: \s*[a-z_]\w* (?: \s*, # parameter separator \s*[a-z_]\w* )* # more parameters are optional )? # parameters are optional \s*\) # end-of-parameters indicator \s*= # function-header-body separator .+ # whatever, until... \s+in\b # ...end-of-function indicator " > <functionName> <nameExpr expr="[a-z_]\w*" /> </functionName> </function> </parser>
-
Thanks you !
Unfortunately, I replaced my parser with yours and it still not work. So now I’m sure the problem does not come from the parser but somewhere else. Any idea ? -
Hi, @tom-saury and @mapje71,
I thougt the
main rexpression
regex of Tom, terribly complicated !! I’m probably missing some particularities but my solution works nice with the sample file , provided by Tom. Of course, it needs some testing on trueCAML
files !Here is my first ( simple ) attempt :
<association id= "caml_syntax" langID="41" /> </associationMap> <parsers> <parser displayName="Caml" id ="caml_syntax" commentExpr="\(\*((?!\(\*|\*\)).)+?\*)$" > <function mainExpr="let\s+(rec \s+)?[\l_]\w*\s*?=.+?in$" > <functionName> <nameExpr expr="let\s+(rec \s+)?\K[\l_]\w*" /> </functionName> </function> </parser>
Note that I included the line
<association id= "caml_syntax" langID="41"
in theassociationMap
nodeCheers,
guy038
-
I agree, it might have been too complicated but I wanted to treat every case.
As I say, my problem is not with the regex but how do you change the functionList.xml in order to implement a new language parser. As you said, I already included the assiociation map. That’s why I don’t know where the problem could be 'cause there is a problem : it doesn’t work at all with a .ml file. Nothing is displayed as if it doesn’t know there is a new parser.
Do you think I did not install NPP well ? Is it normal to have two functionList.xml files which are not related or linked ? One is in AppData\Roaming\Notepad++ and the other one is in Program files\Notepad++Thanks you 2 for helping me
(Tu peux parler en français, je le suis ^^). -
Only ONE functionList.xml file will matter for you.
Do this: Select ? (menu) -> Debug Info… and read the result.
If Local Conf mode is ON, then the active functionList.xml (and other configuration files) will be in the same folder as notepad++.exe
If Local Conf mode is OFF, then the active functionList.xml (and other configuration files) will be in %APPDATA%\Notepad++
-
Salut, @tom-saury,
La fois dernière, j’avais simplement ouvert un nouvel onglet copié ton exemple
CAML
et choisi the langageCaml
pour tester ma solution.Cette fois, j’ai copié ton code
Caml
dans un fichier, nommétest.ml
, et, une fois encore, les résultats étaient corects. Dans la fenêtre de Function List, les4
fonctions n, amis, ncadeau et cadeau étaient bien présentes !Personnellement, j’utilise N++
v7.5.8
, en configuration locale, placé dans le répertoireD:\@@\758
=> Tous les fichiers de configuration se trouvent dans ce dossier ou les ses sous-dossiers :-))Si j’étais toi, je testerai la méthode de Scott mais si tu as un peu peur de faire des bêtises, tu peux simplement renommer un des deux fichiers
functionList.xml
, disons :functionList.tom
et de faire le test ( A propos, c’est chouette, d’avoir un prénom de trois lettres comme toi et moi, pour changer l’extension d’un fichier ! )Je pense que tu as installé N++ de manière traditionnelle, avec l’“Installer”. Dans ce cas, le fichier, du répertoire
C:\Program files\Notepad++
, n’est sûrement pas utilisé !Maintenant, je te conseille, également, de renommer le répertoire
AppData\Roaming\Notepad++
enAppData\Roaming\Old_N++
( bien sûr, après avoir fermé toutes les instances de N++ ouvertes ! )A la prochaine ouverture de N++, une nouvelle arborescence de travail
AppData\Roaming\Notepad++
devrait être créée, avec les sous-répertoires adéquats. Tu verras bien si FunctionList fonctionne, cette fois !Si ce n’est pas mieux ( ou même pire !), tu pourras toujours renommer
AppData\Roaming\Old_N++
enAppData\Roaming\Notepad++
. Rien ne sera perdu ;-))A+ ( For non-French speakers, it’s a very-common shortcut of the French expression “À plus tard”, which could be translated as “See you later” ! )
guy038
-
Thanks all of you !
Problem solved with @guy038’s method making a backup of the Notepad++ folder in AppData and delenting this one. Maybe you have you have to restart NPP to refresh the functionList rules. I don’t know why, but it was as if it kept the old functionList.xml even if I had modified it. Weird… Now, I will improve the regex selector, I will share here the code for those who are interested.
Merci à toi @guy038, j’ai fait exactement ce que tu m’as dit et ça a marché. J’avoue que je réchignais un peu à faire ça car j’avais pas mal customisé NPP mais j’ai juste à copier-coller le contenu donc aucun problème. ^^
-
@Tom-Saury said:
Maybe you have you have to restart NPP to refresh the functionList rules
Yes! If you manually-edit any of Notepad++'s configuration files (and for functionList.xml that is the only way), changes aren’t going to be picked up until you restart Notepad++. I really think this is obvious, even if you aren’t all that familiar with Notepad++.
And FYI, be careful when manually editing other config files, because upon shutdown Notepad++ may need to overwrite them with its own changes, blowing away any manual edits you may have done.
-
Wasn’t obvious to me, my bad. This post wouldn’t be there if I knew this. :
It’s written no where, how can you know that the refresh button doesn’t refresh the rules ? -
Wasn’t obvious to me
That’s fine, we all have different levels of experience with computers in general. I hope you didn’t spend a lot of time thinking your expressions must be wrong if the right stuff didn’t happen right when you saved the xml file!
Later thought: Actually, I don’t know what the refresh button in the Function List window does. For all I know it may do what you originally thought and something else was wrong?
-
The refresh-button refreshes the function list i.e. re-parses the active buffer/source file which isn’t saved yet. When saving a file the refresh is automatically triggered.
To refresh the parser itself after changing functionList.xml you have to restart Notepad++. -
Hey everyone !
Could someone tell me why does “for” match here ?
Here is my function parser :mainExpr="(?x) # free-spacing (see `RegEx - Pattern Modifiers`) let # start-of-function indicator... \s+ # ...should be followed by at least one white-space (rec\s+)? \K # discard text matched so far [a-z_]\w* # valid character combination for identifiers \s+ # start-of-parameters indicator ([a-z_]\w*(\s+[a-z_]\w*)*\s+ # several parameters are optional )|(\(\s*\)\s+) # parameters are optional = # function-header-body separator .+ # whatever, until... \s+in\s # ...end-of-function indicator "
and here is my source code :
let boatGenO () = for boat=0 to 4 do let length = boatLength.(boat) in let isPlaced = ref false in while not !isPlaced do if (Random.bool()) then begin let x = Random.int (10-length) and y = Random.int 10 in let canBePlaced = ref true in for i=0 to pred length do if plateauO.(x+i).(y)<>" " then canBePlaced := false; done; if !canBePlaced then begin for d=0 to pred length do plateauO.(x+d).(y) <- (boatSymbol.(boat)); done; tabBateauO := Array.concat [!tabBateauO; [|(x, y, (boat, false), 1)|]]; isPlaced := true; end; end else begin let y = Random.int (10-length) and x = Random.int 10 in let canBePlaced = ref true in for i=0 to pred length do if plateauO.(x).(y+i)<>" " then canBePlaced := false; done; if !canBePlaced then begin for d=0 to pred length do plateauO.(x).(y+d) <- (boatSymbol.(boat)); done; tabBateauO := Array.concat [!tabBateauO; [|(x, y, (boat, false), 0)|]]; isPlaced := true; end; end; done; done; Array.iter (fun ligne -> begin print_string "|"; Array.iter (fun symb -> print_string (symb^"|");) ligne; print_string "\n"; end;) plateauO; in
I expected that only boatGenO matchs but it’s not the case and I can’t figure out why.
Cheers
-
Make sure you have whitespace at the end of your source file e.g. newline.