Show Xojo: A command line tool for getting information about a Xojo project

I’ve been working on a little command line tool that takes a Xojo project manifest (either Project or XML format) and is capable of listing properties of that project. It’s called xojotool and the repo is on GitHub.

It works with both Xojo Project and Xojo XML manifests. It even handles external modules and classes.


  1. Get help on the tool:
xojotool --help
  1. Get the number of lines of code:
xojotool --project [YOUR_XOJO_PROJECT] --sloc
  1. Output a little summary of the project:
xojotool --project [YOUR_XOJO_PROJECT] --summary

  1. Get more details on the parts of a project:
xojotool --project [YOUR_XOJO_PROJECT] --detail


Download the prebuilt binaries from the GitHub releases page.

State of the repo

The project currently externally references another project of mine (XojoKit) which handles parsing the Xojo project. I will be open sourcing this too soon but it just needs a bit of a tidy up. For the time being, you won’t be able to build the project, only use the precompiled binaries.


Very nice, thank you… Though I did think my project was much bigger than that… lol :slight_smile:

One to keep…


Breakdown of Assembly Language Studio:

2845 single lines of code.
731 comment lines.

Item           Type        Members   SLOC   
App            class       9         5      
WinMain        window      133       1050   
assemblyCore   module      108       1723   
asmLabel       class       3         2      
asmVariable    class       6         5      
libraries      module      7         0      
tabCode        class       5         4      
externCmd      class       8         7      
xmlTools       module      6         23     
asmThread      class       2         23     
asmCode        class       4         3
1 Like

The parsing library isn’t perfect (I had to reverse engineer both of Xojo’s project file types). Currently it essentially ignores code in Workers, Toolbars and Menubars. Apart from that the code counts should be correct.

You must write efficient code :slight_smile:

Yes I come from a time where you had to profile and optimise your code, it’s a hard habit to break. I regularly go back and review code to find performance tweaks.

I also like a lot of comments to explain everything…



One thing I don’t see mentioned in the thread or summary but may be useful to those of us who still run multiple releases of Xojo (for whatever reason) is the project’s Xojo release info.

1 Like

A great suggestion.

I’ve just pushed version 1.0.1 which outputs the version of the Xojo IDE that the project was saved in when using the --summary or --detail option.

I’ve also internalised the XojoKit module so it should now be possible to build the repository.

You will need to create a module called RegisterPlugins and add a method titled MBS that is responsible for registering your MonkeyBread plugins. This is only required for built apps (not apps running in the debugger). For obvious reasons, I can’t share my serial!

If you don’t have the MonkeyBread plugins don’t fret - just use a precompiled binary.


Precompiled binary just tried and the following messages were displayed:

Error: Expected a scope / attributes line after the Class tag.
Error: An unexpected internal error occured ().

Which platform?

Can you run the project in the debugger and see where it breaks? It’ll be an edge case in the parser.

You’re welcome to privately send me the project if you feel comfortable and I’ll take a look.

Monterey 12.5. Xojo 2022r3 build 57747.

Same issue if I load and save as with 2022r2.

You either need to run it in the debugger (to see where the crash is) or share the offending project with me privately so I can see the issue. It looks like an unexpected absence of a prefix before a member declaration.

Ah the joys of reverse engineering.

This is a scan of the files for " Class ":

ActionDialogs/ActionDialog.xojo_code:Protected Class ActionDialog
App.xojo_code:Protected Class App
CSW Classes/FrequencySettings.xojo_code:Protected Class FrequencySettings
CSW Classes/FontFamily.xojo_code:Protected Class FontFamily
CSW Classes/TwoByTwoData.xojo_code:Protected Class TwoByTwoData
CSW Classes/ClipboardBuffer.xojo_code:Protected Class ClipboardBuffer
CSW Classes/FindReplaceClass.xojo_code:Protected Class FindReplaceClass
CSW Classes/CurrentDocumentsClass.xojo_code:Protected Class CurrentDocumentsClass
CSW Classes/CStatLoader.xojo_code:Protected Class CStatLoader
CSW Classes/ColumnDefinition.xojo_code:Protected Class ColumnDefinition
CSW Classes/GridPrintThreadClass.xojo_code:Protected Class GridPrintThreadClass
CSW Classes/LoadFileThreadClass.xojo_code:Protected Class LoadFileThreadClass
CSW Classes/SGParams.xojo_code:Protected Class SGParams
CSW Classes/StatsGraphsThreadClass.xojo_code:Protected Class StatsGraphsThreadClass
CSW Classes/OpenWindowsClass.xojo_code:Protected Class OpenWindowsClass
CSW Classes/WindowMenuItem.xojo_code:Protected Class WindowMenuItem
CSW Classes/Graphing/FontClass.xojo_code:Protected Class FontClass
CSW Classes/Graphing/GraphingSVG.xojo_code:Protected Class GraphingSVG
CSW Classes/Graphing/Legend.xojo_code:Protected Class Legend
CSW Classes/Graphing/AxisClass.xojo_code:Protected Class AxisClass
CSW Classes/RecentMenuItem.xojo_code:Protected Class RecentMenuItem
CSW Classes/CSWMini.xojo_code:Protected Class CSWMini
CSW Classes/VirtualRowsThreadClass.xojo_code:Protected Class VirtualRowsThreadClass
CSW Classes/AUCSettings.xojo_code:Protected Class AUCSettings
CSW Classes/CStatException.xojo_code:Protected Class CStatException
CSW Classes/XLLoader/XLWorksheetLoader.xojo_code:Protected Class XLWorksheetLoader
CSW Classes/XLLoader/XLWorkbookLoader.xojo_code:Protected Class XLWorkbookLoader
CSW Classes/RecentsClass.xojo_code:Protected Class RecentsClass
CSW Classes/LoadFontsClass.xojo_code:Protected Class LoadFontsClass
CSW Classes/FilterClass.xojo_code:Protected Class FilterClass
CSW Classes/ProgressTimerClass.xojo_code:Protected Class ProgressTimerClass
General Dialogs/CloseCancelDialog.xojo_code:Protected Class CloseCancelDialog
Modules/UndoEngine/UndoUnit.xojo_code:Protected Class UndoUnit
Modules/UndoEngine/UndoStack.xojo_code:Protected Class UndoStack
Modules/FormulaEngine/ValueClass.xojo_code:Protected Class ValueClass
Modules/FormulaEngine/OperationClass.xojo_code:Protected Class OperationClass
Modules/FormulaEngine/FormulaClass.xojo_code:Protected Class FormulaClass
Modules/XLSWriter/XLSXBorders.xojo_code:Protected Class XLSXBorders
Modules/XLSWriter/XLSXDrawing.xojo_code:Protected Class XLSXDrawing
Modules/XLSWriter/XLSXDrawingItem.xojo_code:Protected Class XLSXDrawingItem
Modules/XLSWriter/XLSXChartsheet.xojo_code:Protected Class XLSXChartsheet
Modules/XLSWriter/XLSXStyle.xojo_code:Protected Class XLSXStyle
Modules/XLSWriter/XLSXStylesheet.xojo_code:Protected Class XLSXStylesheet
Modules/Help/HelpRunnerMenuItem.xojo_code:Protected Class HelpRunnerMenuItem
Modules/macoslib/MacTCPSocket.xojo_code:Protected Class MacTCPSocket
Modules/macoslib/Misc/NativeSubclass/DateExtended.xojo_code:Protected Class DateExtended
Modules/macoslib/Misc/NativeSubclass/DictionaryCaseSensitive.xojo_code:Protected Class DictionaryCaseSensitive
Modules/macoslib/BSD/Error.xojo_code:Protected Class Error
Modules/macoslib/FourCharCode.xojo_code:Protected Class FourCharCode
Modules/macoslib/Cocoa/AutoreleaseTimer.xojo_code:Protected Class AutoreleaseTimer
Modules/macoslib/Cocoa/NSBezierPath.xojo_code:		  //Holding the constructor private so one can only create a Bezier with the appropriate Class methods
Modules/macoslib/Cocoa/CocoaDelegate.xojo_code:		    mClassName = raiseEvent DelegateClassName // get the Class name and store it
Modules/macoslib/Cocoa/NSGradient.xojo_code:		    // In order to make this work, the Constructor of MacOSLib‘s NSColorSpace Class has to be made public.
Modules/macoslib/Cocoa/NSGradient.xojo_code:		This is the Cocoa.NSGradient Class for easy color gradients.
Modules/macoslib/Cocoa/NSGradient.xojo_code:		To use it, create an instance of this Class first by passing the appropriate values to the Constructor method 
Modules/macoslib/Cocoa/NSBundle.xojo_code:		  //# Returns the Class object for the specified name.
Modules/macoslib/Exception Classes/macoslibException.xojo_code:Protected Class macoslibException
Modules/macoslib/Exception Classes/BadSystemException.xojo_code:Protected Class BadSystemException
Modules/macoslib/Exception Classes/MacOSError.xojo_code:Protected Class MacOSError
Modules/macoslib/Exception Classes/Win32Error.xojo_code:Protected Class Win32Error
Modules/macoslib/Exception Classes/OSError.xojo_code:Protected Class OSError
Modules/macoslib/Exception Classes/libcError.xojo_code:Protected Class libcError
Modules/macoslib/Tuple.xojo_code:Protected Class Tuple
Modules/macoslib/UTI.xojo_code:Protected Class UTI
Result Classes/Anova1.xojo_code:Protected Class Anova1
Result Classes/TwoByTwo.xojo_code:Protected Class TwoByTwo
Result Classes/PairedT.xojo_code:Protected Class PairedT
Result Classes/ChiSquared.xojo_code:Protected Class ChiSquared
Result Classes/Frequency.xojo_code:Protected Class Frequency
Result Classes/BiPaPaired.xojo_code:Protected Class BiPaPaired
Result Classes/StaticResultClass.xojo_code:Protected Class StaticResultClass
Result Classes/StaticResultClass.xojo_code:	#tag Note, Name = Class Use
Result Classes/StaticResultClass.xojo_code:		This Class should hold anything that is common to every run of Stats for a given window. 
Result Classes/KruskalWallis.xojo_code:Protected Class KruskalWallis
Result Classes/Correlation.xojo_code:Protected Class Correlation
Result Classes/Descriptive.xojo_code:Protected Class Descriptive
Result Classes/ResultsClass.xojo_code:Protected Class ResultsClass
Result Classes/ResultsClass.xojo_code:	#tag Note, Name = Class Use
Result Classes/MLinReg.xojo_code:Protected Class MLinReg
Result Classes/AUC.xojo_code:Protected Class AUC
Result Classes/MannWhitneyU.xojo_code:Protected Class MannWhitneyU
Result Classes/Anova2.xojo_code:Protected Class Anova2
Result Classes/Spearman.xojo_code:Protected Class Spearman
Result Classes/Wilcoxon.xojo_code:Protected Class Wilcoxon
Result Classes/tTest.xojo_code:Protected Class tTest

If you PM me I can share the project.

While I did some Z80 assembler in the Long Ago (printer drivers and the like on TRSDOS/LSDOS 6) and owned the 3-volume set of assembler source code to the OS, that’s about the extent of my machine-level coding experience. But even in line-of-business apps, I am far more aware of what is going on under the hood and tradeoffs between memory and performance than nearly all recently-minted devs. Starting out with 128K of bank-switched RAM and floppy drives will do that to you :wink:

True… I started out on a Sinclair ZX80 with 1KB of ram… (And yes I walked up hill both ways to and from school, barefoot in the snow… :crazy_face:)

My early coding was writing compilers, boot loaders and ROM code, which had to be stored in 8KB ROMS. I still do a bit of that today for industrial machines still using Z80 processors…


1 Like

Lol – in my day we didn’t even have ones and zeroes – we had to use oh’s and i’s.

1 Like

Fixed as of version 1.0.2: Release Version 1.0.2 · gkjpettet/xojotool · GitHub

Works a treat now. The only slight issue is that it identifies DesktopContainer and Containers as Windows.

Nice… Works Now!!


1 Like

Fixed in 1.0.3:

That seems to work. I just spotted another issue. I typed --details by mistake and got an unhandled exception. Raised an issue on you GitHub.