Registering custom function in .InitializeFunctions procedure in Custom Statements database

“A good place to define a custom function is in the .InitializeFunctions procedure inside a custom statement library (inside the ~/Application Support/PanoramaX/Libraries folder). If you put your custom function definition code in that procedure, it will run automatically when Panorama starts up, and will also run automatically when you use the Libraries>Register Functions and Statements command in the View Organizer.”

Can I enter more than one custom function in this procedure. Does it need any separator besides white space, eg:

registercustomfunction “superdatefilename(thedate)(”,1,{batchreplace(superdatestrsec(•1),"/=_;:=-",";","=")}

registercustomfunction “startword(thetext)(”,1,{arraytrim(thetext,1," ")}

Jeff, your registercustomfunction statements are missing the foldername parameter. And my recollection is that, at the moment, you can put any value you like as the parametercount parameter - it seems to be ignored. But don’t do that or it won’t work when that bug is fixed (maybe it’s fixed already).

Here’s an example of one of my .InitializeFunctions procedures:

… and these are the statements and functions:

Thanks Michael. So you can register multi functions there. I can’t open Pan X at the moment because it crashed hard, but I thought in the description in the help file it said you didn’t need the folder name parameter.

You’re correct - my bad.

Jeff, you are correct, it does say that and it should be ok if you leave that parameter out.

Jeff, I think the problem with your code is that you have included the parameter name as part of the function name. So you have:

registercustomfunction "startword(thetext)(",1,{arraytrim(thetext,1," ")}

but it should be:

registercustomfunction "startword(",1,{arraytrim(thetext,1," ")}

That value is not ignored and never has been. It won’t give you an error when the registercustomfunction statement is run, but your custom function won’t run correctly if that number is wrong. So definitely do not put any value you like there – be careful to put in the correct value.

Using this parameter, you can define more than one version of a function, with different numbers of parameters. For example, you could define versions of a function named biggest(, with 2 parameters, 3 parameters, 4, 5, 6, etc. This is how you can create a function with optional parameters. (This was not possible in Panorama 6, this is a new feature in Panorama X.)

Actually, I believe that should be

registercustomfunction "startword(",1,{arraytrim(•1,1," ")}

Parameters should be •1, •2, etc.

Oh yes, he had that right in his first example, but I copied the second one because it was shorter and didn’t notice that problem.

Thanks guys. As a side note, when Pan X tried to load the Custom Statements database, it threw an error about illegal characters in the function name, then told me I had no time left on my site license and logged me out.

Are you following all of these instructions:

“The name of the custom function must be all uppercase letters (no numbers or punctuation). Earlier versions of Panorama required that the function name end with (, but this is now optional. When choosing a custom function name, make sure you don’t use a name that Panorama is already using – doing so could cause Panorama to break. A good practice is to always prefix your custom function names with a special prefix, perhaps your initials or company name.”

Yep. I have them all registered now.


Custom function names do not need to be upper case. I think it may be required of custom statements.

This is true. If you look at my list of registercustomfunction statements in my first post above, you will see that the last one (which was just a test) is called stringcount.45, so all of lower-case, punctuation and numbers can be used. What we don’t know is whether Jim is likely to enforce the published rules at some later stage so it might be wise to stick with them.

This is what Help says on my computer:

name – This is the name of the custom function. The name must start with a letter, and then may contain letters, numbers, period, underscore, and the omega symbol (Ω). Upper and lower case are the same (function names are case insensitive). Earlier versions of Panorama required that the function name end with (, but this is now optional. (Of course the ( is required when using the function.) When choosing a custom function name, make sure you don’t use a name that Panorama is already using – doing so could cause Panorama to break. A good practice is to always prefix your custom function names with a special prefix, perhaps your initials or company name.

If an error happens while Panorama X is initializing, the initialization won’t complete. Since checking your login status is one of the last things it does, it won’t log in. It didn’t really log you out, it just didn’t correctly log in. If you quit Panorama, and then relaunch w/o the initialization error (see below), Panorama will again show that you are logged in.

There may be other problems from an incomplete initialization. Normally there is no way you can cause an error during the Panorama X initialization process. But if you set up one or more Custom Statements databases, you can cause an error. If this happens I would recommend quitting Panorama, removing the Custom Statements database with the error, and relaunching Panorama. Don’t put the database back into action until you have fixed the error.

Actually, Panorama X should really trap any errors in your code, report them, and continue to finish the initialization. I’ve submitted a bug report and that will make that change. But for now, be careful.


I checked the source code, and Panorama is already performing error trapping when it calls the .InitializeFunctions procedure. That is where you should put your registercustomfunction statements – not in .InitializeLibrary. When you use .InitializeFunctions, you can change your definitions while Panorama is running, then use the Libraries>Register Functions & Libraries command in the View Organizer to update the definitions immediately, without having to quit and relaunch Panorama. I see that Michael got the memo, because his code above is in .InitializeFunctions. But Jeff, you should change your code and put these statements into .InitializeFunctions instead of .InitializeLibrary (this is a difference from Panorama 6 to X – Panorama 6 would not let you change a custom function except by quit and relaunch). You can still use .InitializeLibrary but then you won’t be able to change on the fly, and if there is an error, Panorama initialization will fail (at least for now).

Yep - I’m not sure where I got my quote from - maybe the rules for custom statements?

I had reported the problem with .InitializeFunctions recently, and you said you fixed it, but I do not think the fix has appeared in a new version yet for us peons.

I searched Bitbucket and this forum, but I cannot find “the Problem” you say you reported and I claim I fixed, unless you were talking about "no error appearing when closing the .InitializeFunctions procedure? Is that it? My reply was that that was expected behavior, runtime errors are only reported at runtime.

Perhaps there is something else you are referring to. There are no unpublished fixes in this area of the code, except that in my unpublished version RegisterFunction now works in addition to RegisterCustomFunction.

I think it was this:

Ok, you’re correct. I saw that in the commit list last night but misread the date and thought it was already in the 0.9.007 version.

Here’s the scary part – I did that on October 7th – only 4 days ago. Then yesterday I looked at that code and had no recollection of making that change, I thought I had done it months ago!! If it was Objective-C code, Xcode can show me the exact date when every single line of code was changed. Unfortunately, Panorama X can’t do that :frowning:

Bottom line, the 0.9.008 version will be much more resistant to possible user created problems during the initialization process. In the meantime, be careful out there!