Simple code sharing on macOS

For anyone not using version control perhaps the easiest way to share code between various projects is to use external items. However, not everything cam be made external. Modules that contain classes & other modules cant be shared via external items.

So how can you share these ?

On macOS the answer is … ALIASES !!!!!

The trick is how you set things up when you want to share such a thing between various projects. But this only works for TEXT projects because text projects save everything in separate files. For binary & XML projects you really dont have much in the way of choices when it comes to sharing Modules with other classes & modules in them.

And, if you ARE using TEXT projects then its also very likely you ARE using version control. So this tip is really for a very narrow set of use cases.

Basically what we need to do is set up an aliases that refers to the code we want to share instead of the code in our project.

Lets walk through a really simple example.

First create a new folder on your desktop – I called mine Code Sharing Example.

Now lets create a new project and add a module that we’re going to share between this new project and others.

And we’ll save this in a new folder we create inside the new folder we created earlier. I named the folder this is saved in Originator since we’re going to have the original source in this project and others will use it.Make sure you save the project as a TEXT, or Xojo Project. I also named the project Originator.xojo_project

This forms the basis of what we want to share.

Start a new desktop project. In this example I happen to use a desktop project but it could be a web or console app. iOS is harder to do this with because it uses the new, now deprecated Xojo framework so data type compatibility may be an issue. However, if you are using the new framework in desktop or other apps then you can use the same technique.

In this new app we are going to add a PROXY module that we will fix up manually later. Its just a placeholder. But it does make life simpler if you name this the same as the one we wanted to bring in from the other project. So we’ll name it ToBeShared like in the Originator project.

Now save this project in a new folder inside the Code Sharing Folder. I named mine Second Project and the project also named Second Project.

And now the manual work to make it so we can share the module.

A module, when saved as a text project, is a file. If you look in the folder that holds the Originator Project you will see a file named ToBeShared.xojo_code as well as a directory named ToBeShared.

In order to get Second Project to read the Originator Projects module and contained classes we need to replace the Second Projects file on disk with an alias named exactly the same – extension and everything. And we also need to make sure we have an alias to the directory with the ToBeShared name so the IDE realizes that this is a module with contents.

Since we added the proxy in the Second Project with the exact name we do not need to do anything to the project manifest.

First navigate to Second Project and remove ToBeShared.xojo_code

Then navigate to Originator Project and select ToBeShared.xojo_code and the ToBeShared directory. And press Cmd + Ctrl + A (or right click and select make alias)

Move these two aliases to the Second Project directory.

We’re almost done.

Navigate to Second Project.

Change ToBeShared alias so its names is only ToBeShared without the alias as part of the name. And ToBeShared.xojo_code alias to ToBeShared.xojo_code again with the alias part removed.

Open the Originator project & add a method to the Shareable class and the ToBeShared module. Save.

Now open the Second Project and you should see those just added items.

And here is where norm realizes he missed a step 😛

Thats ok though.

I’ll show you how I fixed it and what I messed up earlier.

To explain the problem. We should have added not just a proxy that we’d fix for the module but the Shareable class inside it as well. This would have made it so we did not need to manually fix the manifest and creating the aliases would have been sufficient. If you were to go back to that step & add the class then everything would just work now.

But since I missed that step I’ll manually fix the manifest. If you opened the Second project what was missing is the class that we added inside the ToBeSharedModule. The reason is that the manifest does not know there is such a class.

In the Originator project you would see something like

Module=ToBeShared;ToBeShared.xojo_code;&h000000000F00AFFF;&h0000000000000000;false
Class=ShareableClass;ToBeShared/ShareableClass.xojo_code;&h00000000580AC7FF;&h000000000F00AFFF;false

But when you open the Second Project manifest, because we did not add the class to the module, you only see something like

Module=ToBeShared;ToBeShared.xojo_code;&h0000000042EA77FF;&h0000000000000000;false

and no entry for the class. And thats the problem. The manifest lists everything a project is composed of and since there is no entry for the class the class contained by the module doesnt show. And the fix is simply to copy the lines for the module & class in the manifest from the Originator project and replace the one line for the module in the Second Project.*

And once you copy that across & save the manifest and reopen the project there’s the code from the Originator project. And if you make chnages to this code in the second project and reopen the originator project the changes will exist there as well.

One thing to take care with – do NOT open both projects at the same time and edit in both. You are sure to cause yourself problems.

If you add new classes to either Originator or Second Project you will have to do many of the same manifest file changes over again so each project knows about the added items.

*When manually editing a manifest there are some things to be careful about. One is the two hexadecimal entries on the line. The first is the items id and the second the id of the item that contains this one. These items need to be unique within a project. Take care to make sure this is true otherwise you run the very real risk of messing your project manifest up to the point your project won’t load.

Stupid IDE tricks

A question was asked the other day about “how can I list just all the Windows in my application” And that reminded me of something I added to the IDE some time back.

Advanced filters in the find field above the navigator. It has only a very short mention in the IDE user guide.

So if you want to find all the Windows in your application you can type something like this into the filter field

% type:Window

and press enter and you will see all windows and container controls listed (containers are window like objects hence why they are listed). You can use the type filter with just about any type you can imagine in your project; property, constant, enumeration, delegate, method and so on.

You can also put things in the type field that include wild cards. So if you want to see all properties, computed and regular, you can put

% type:%property

This will list any computedproperty or property, regardless of its name, in the navigator.

Combine this with a decent naming convention and you can make the filter work for you in a lot of ways I think a lot of people do not realize exists.