Local Links External Links Contact Search this site |
Arbed - ScriptingSimilar to Xojo's IDE Scripting, Arbed can be scripted to browse a project and modify it. With Arbed, this can be done in much more detail than it's currently possible with the IDE. Arbed scripts are plain text files with extension ".rbs" or, preferrably, ".arbs". When they're opened in Arbed, there will be a "Run" button that will execute the script on the frontmost project window. Scripting APIFirst off, the scripting is based on XojoScript. Refer to Xojo's documentation of the scripting language and to its function overview for basic functions that are available to you in Arbed's scripting. The Arbed-specific API currently consists of the following functions: Const PropTypeInteger = 1231975456 // 'Int ' Const PropTypeDouble = 1147300896 // 'Dbl ' Const PropTypeString = 1400140398 // 'Strg' Class PrjItem Function HasSubItems () as Boolean // returns true if SubItems() returns a non-empty iterator Function SubItems () as PrjItemIterator // returns an iterator for the item's members Function HasProperties () as Boolean // returns true if Properties() returns a non-empty iterator Function Properties () as PrjItemIterator // returns an iterator for the item's properties Function Parent () as PrjItem // returns the item's parent Function Kind () as String // same as you see in the "Kind" column in the Arbed code editor Function Type () as String // The class name used by Arbed internally for this item Function IsOfType (type as String) as Boolean // Tests if item is a member of the given internal class Function IsDynamicConstant () as Boolean (v1.9.6) Function IsProperty () as Boolean // returns true if item is a Property (vs. member/subItem) Function IsTextualProperty () as Boolean // returns true if the Property contains numeric or textual (not binary) values (v1.9.6) Function ItemID () as Integer // top level items have an ID <> 0 Function ContainerID () as Integer // refernence to another top level item's ItemID Function Name () as String // plain name of an item, may be empty Function Label () as String // "smart" name of an item (methods include their signature) Function Identifier (withSignature as Boolean = false) as String // semantic path to the item Function Location (withSignature as Boolean = false) as String // project path to the item Function Declaration () as String Function DisplayValue () as String // returns values of Properties and Constants in a human readable form (v1.9.6) Function GetSource (ByRef value as String) as Boolean Function GetValue (ByRef value as String) as Boolean // Gets the raw value of Properties and Constants, may be binary! Function SetSource (sourceText as String, trimLines as Boolean = false) as Boolean Function SetValue (value as String) as Boolean Function SetValue (value as Integer) as Boolean // (v1.9.2) Function SetValue (value as Double) as Boolean // (v1.9.2) Function SetValue (value as Boolean) as Boolean // (v1.9.2) Function CanSetName () as Boolean Function SetName (value as String) as Boolean Function Delete () as Boolean Function AttributesProp (addIfMissing as Boolean = false) as PrjItem // Gets (optionally adds) the Attributes item (v1.7) Function Scope () as Integer // return: 1 = public or global, 2 = protected, 3 = private (v1.7) // The following method lets you look up a ShortProp, and optionally add it (then you also have to pass a type) Function ShortPropByName (name as String, addIfMissing as Boolean, propType as UInt32 = PropTypeString) as PrjItem End Class Class PrjItemIterator Function GetNextPrjItem (ByRef item as PrjItem) as Boolean Function Count () as Integer End Class Class FoundItem Function PrjItem () as PrjItem Function Value () as String Function Value (assigns newValue as String) as Boolean End Class Class FoundItemIterator Function GetNextFoundItem (ByRef item as FoundItem) as Boolean End Class Function FindText (txt as String) as FoundItemIterator Function PrjItemRoot () as PrjItem Function PrjItemByID (itemID as Integer) as PrjItem // complements PrjItem.ItemID Function PrjItemByLocation (location as String) as PrjItem // complements PrjItem.Location // If you make many modifications to the project, wrap them to make it faster: Sub StartUpdating () Function EndUpdating () as Boolean Class Dictionary // since Arbed 1.6 Sub Constructor () Function Clone () as Dictionary Function Count () as Integer Function Key (idx as Integer) as String Function Value (key as String) as String Function Lookup (key as String, default as String) as String Sub Value (key as String, assigns value as String) End Class Class BinaryDict // (same as Dictionary, just that the keys are case sensitive) End // Global helper functions, since Arbed 1.6 (some require later versions) Function EndOfLine as String // Returns RB's EndOfLine value Function EndOfLineOfText(text as String) As String // Returns EOL used by text (or LF on OSX and Linux, CR+LR on Windows if text contains no EOL) (v1.6.1) Function ReplaceLineEndings(text as String, replaceEOLwith as String) As String // Same as RB's function (v1.6.1) Function Str(f as Double, format as String) As String // Same as RB's function (v1.6.1) Function Str(i as Int64, format as String) As String // Same as RB's function (v1.6.1) Function StrEqual (a as String, b as String) as Boolean // returns true if both strings are equal in their binary representation (like StrComp(a,b,0)=0) Function ShellExecute (cmd as String, ByRef result as String) as Integer // Invokes RB's Shell.Execute, returning its Result and ErrorCode properties Function TargetOS as String // Returns "OSX" when Arbed runs on Mac OS X, "Win" on Windows and "Linux" otherwise Sub Beep // RB's Beep (v1.6.2) // Global helper functions mimicking the same provided by Xojo's IDE Scripting, since Arbed 1.8 Sub Speak (txt as String, interrupt as Boolean = false) Function ShowDialog (msg as String, expl as String = "", dftBut as String = "OK", cnclBut as String = "", altBut as String = "", icon as Integer = 0) Function ProjectShellPath () as String Function ProjectNativePath () as String // v1.9.2 Function SelectProjectItem (itemPath as String) as Boolean Function Text () as String Function Text (assigns source as String) // Encryption, since Arbed 1.6 Function EncryptBlowfishMBS (s as String, key as String) as String // Uses the BlowfishMBS class Function DecryptBlowfishMBS (s as String, key as String) as String // Reverse of EncryptBlowfishMBS Function EncryptAESMBS (s as String, key as String, optionalIVector as String = "") as String // Uses the AESMBS class Function DecryptAESMBS (s as String, key as String, optionalIVector as String = "") as String // Reverse of EncryptAESMBS // Base64 and Hex encoding, since Arbed 1.6 Function EncodeBase64 (s as String) as String // Invokes RB's EncodeBase64(s,0) function Function DecodeBase64 (s as String) as String // Invokes RB's DecodeBase64(s) function Function EncodeHex (s as String) as String // Invokes RB's EncodeHex(s,0) function Function DecodeHex (s as String) as String // Invokes RB's DecodeHex(s) function // String encoding, since Arbed 1.6 Function DefineAsUTF8 (s as String) as String // Returns s.DefineEncoding(Encodings.UTF8) Function ConvertToUTF8 (s as String) as String // Returns s.ConvertEncoding(Encodings.UTF8) Function HasEncoding (s as String) as Boolean // Returns s.Encoding <> nil // File and Directory operations, since Arbed 1.6.1 Function AppendToFile(path as String, data as String) As Boolean // Appends to existing file or creates file if nonexisting Function ChooseFolderPath(title as String) As String // Shows a modal dialog to select a folder Function ChooseOpenPath(extensions as String, title as String) As String // Shows a modal dialog to open a file Function ChooseSavePath(extensions as String, title as String, suggestedPath as String) As String // Shows a modal dialog to save a file Function CreateDirAtPath(path as String) As Boolean // Creates a directory. Returns true if creation worked or if there was already a directory there Function DeleteItemAtPath(path as String) As Boolean // Deletes a file or empty directory Function LastPathComponent(path as String) As String // Returns the name of a path to a file or folder Function LengthOfFile(path as String) As Int64 // Returns the size of a file, or 0 for directories Function LoadFromFile(path as String, ByRef data as String) As Boolean // Loads a file into a variable Function MoveItemFromPathToNameOrPath(path as String, newNameOrPath as String) As Boolean // Moves or renames an item Function PathComponents(path as String) As String() // Returns an array of all path segments Function PathDoesExist(path as String) As Boolean // Returns true if the item at the path exists Function PathIsAlias(path as String) As Boolean // Returns true if the item at the path is an Alias (or symlink) Function PathIsDirectory(path as String) As Boolean // Returns true if the item at the path is a folder Function PathSeparator() As String // Returns "/" on OSX and Linux, "\" on Windows Function ReadDirectoryItems(path as String, getTrueItems as Boolean, ByRef names() as String) As Boolean // Loops over all items in a directory, // ... returning their names. Uses "FolderItem.TrueItem()" if getTrueItems=true, otherwise uses "FolderItem.Item()". Function ResolveAliasPath(path as String) As String // Follows an Alias (or symlink), returning the destination path Function SaveToFile(path as String, data as String, replaceExisting as Boolean = false) As Boolean // Writes a file // RegEx operations, since Arbed 1.6.1 Class RegEx // The RegEx class (including RegExMatch and RegExOptions) are identical to the ones the RB framework offers. See its documentation. End Class // Selection operations, since Arbed 1.6.2 Function SelectedPrjBrowserItems () as PrjItemIterator // Returns the items that are selected in the left browser pane of the project window. Function SelectPrjBrowserItem (item as PrjItem, selected as Boolean = true) as Boolean // Selected or unselects an item Sub ClearPrjBrowserSelection () // Clears the selection Function RevealPrjItem (item as PrjItem, focusOnSource as Boolean = true, setFocus as Boolean = true) as Boolean // Shows the item in the window. // Sorting, since Arbed 1.7 Sub Sort (int32Array() as Int32) Sub Sort (int64Array() as Int64) Sub Sort (stringArray() as String, mode as Integer = 0) // mode as in StrComp, or mode=2 for case-insensitive compare (ASCII only) Note: The function Parent used to be named Container before version 1.6. It was changed to avoid confusion with the unrelated function ContainerID. Use the "print" command to output a line of text. If you print "<output-to-new-window>" first, the output will appear in a new window, otherwise it'll appear in the editor window. ExamplesNote: More scripts are included with the Arbed download (inside the "Scripts" folder).
This script gets the value of the App's Bundle Identifier and changes it by appending ".modified" to it. (Note: "<Settings>" refers to most of the project-wide settings, including most App properties as well as some other build settings. You can look at all of them by using PrjItemRoot().Properties in place of SubItems in the example further below). dim settings as PrjItem = PrjItemByLocation ("<Settings>") dim addIfMissing as Boolean = true // if it's missing, we'll add it with the following type dim newType as UInt32 = PropTypeString // or PropTypeInteger or PropTypeDouble dim item as PrjItem = settings.ShortPropByName ("BundleIdentifier", addIfMissing, newType) dim s as String if item.GetValue(s) then print "old value: "+s if not item.SetValue("xyz.yourdomain.new-identifier") then print "set failed." end else print "no value." end This script searches all Control properties named "TextFont" and "TextSize", resetting their values to defaults: Sub FindReplacePDef (find as String, newValue as String) dim iter as FoundItemIterator = FindText (find) if iter = nil then Print "not found" else dim item as FoundItem while iter.GetNextFoundItem (item) dim lbl as String dim pi as PrjItem pi = item.PrjItem dim value as String if pi.Kind = "PDef" then if pi.GetValue (value) then value = ", value: "+value end Print "found: <"+item.Value+"> in "+pi.Location(true)+value if not pi.SetValue(newValue) then print "set failed" end end wend end End Sub FindReplacePDef "TextFont", "System" FindReplacePDef "TextSize", "0" This script lists all top level project items and their immediate members: // Lists all top level project items (settings, classes, modules etc.), // and lists all their immediate members and properties as well. dim root as PrjItem = PrjItemRoot() dim iter as PrjItemIterator = root.SubItems() dim item as PrjItem while iter.GetNextPrjItem(item) // iterate over top level items // let's check if the item is inside another (i.e. a module or folder) dim containerInfo as String = "" if item.ContainerID <> 0 then dim containerItem as PrjItem = PrjItemByID (item.ContainerID) if containerItem <> nil then containerInfo = ", container: " + containerItem.Label end end print item.Label + ": " + item.Kind + containerInfo // now iterate over this item's properties dim iter2 as PrjItemIterator = item.Properties() dim item2 as PrjItem while iter2.GetNextPrjItem(item2) showItem item2 wend // now iterate over this item's non-property members iter2 = item.SubItems() while iter2.GetNextPrjItem(item2) showItem item2 wend wend // A subroutine to display the item's kind or value sub showItem (item as PrjItem) dim v as String if item.IsProperty and item.GetValue(v) then print " " + item.Label + " = " + v else print " " + item.Label + ": " + item.Kind end end sub This script finds all methods in the frontmost open project and adds the line System.DebugLog CurrentMethodName to each of them: // Set up global variables that the methods can access and alter dim changeCount as Integer dim textToAddToTopOfSource as String // Here the program starts textToAddToTopOfSource = "System.DebugLog CurrentMethodName" + EndOfLine scan (PrjItemRoot()) Print "Finished. " + Str(changeCount) + " methods were modified." // Here the program ends // // This function finds all methods, events and other items that contain source code: // sub scan (container as PrjItem) dim item as PrjItem // first loop: find all methods and modify them as needed dim iter as PrjItemIterator = container.SubItems() while iter.GetNextPrjItem(item) if item.IsOfType ("MethodCodeBase") then processMethod (item) end wend // second loop: look into this item to find methods inside (-> recursion) iter = container.SubItems() while iter.GetNextPrjItem(item) if item.HasSubItems() then scan (item) end wend end sub // // This function modifies the source code of a found method: // sub processMethod (item as PrjItem) dim src as String if not item.GetSource (src) then Print "Can't get source for "+item.Label else // check if the to-be-added text is already present if Left (src, Len(textToAddToTopOfSource)) = textToAddToTopOfSource then // already present else src = textToAddToTopOfSource + src if not item.SetSource (src) then Print "Can't set source for "+item.Label else // modification was successful changeCount = changeCount + 1 end end end end sub |