Navigation

Search

Contact

Arbed - Scripting


Similar to Real Studio'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 API

The API currently consists of the following functions:

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 Container () 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 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 GetSource (ByRef value as String) as Boolean
  Function GetValue (ByRef value as String) as Boolean
  Function SetSource (sourceText as String, trimLines as Boolean = false) as Boolean
  Function SetValue (value as String) as Boolean
  Function CanSetName () as Boolean
  Function SetName (value as String) as Boolean
  Function Delete () as Boolean
End Class

Class PrjItemIterator
  Function GetNextPrjItem (ByRef item as PrjItem) as Boolean
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

Examples

Here's a script that 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.GetValue (value) then
        value = ", value "+value
      end
      Print "found: <"+item.Value+"> in "+pi.Label+" ("+pi.Kind+")"+value

      if pi.Kind = "PDef" then
        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:

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 members
  dim iter2 as PrjItemIterator = item.SubItems()
  dim item2 as PrjItem
  while iter2.GetNextPrjItem(item2)
  print "  " + item2.Label + ": " + item2.Kind
  wend
wend

This script finds all methods in the frontmost open project and adds the line System.DebugLog CurrentMethodName to each of them (requires Arbed 1.5.1 or later):

// 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

Page last modified on 2012-05-15, 15:54 EDT
Powered by PmWiki